mirror of
https://github.com/ETLCPP/etl.git
synced 2026-11-10 07:09:46 +08:00
Merge remote-tracking branch 'origin/feature/callback_service' into development
This commit is contained in:
commit
2173751474
@ -1,58 +1,61 @@
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "function.h"
|
||||
#include "etl/function.h"
|
||||
#include "etl/callback_service.h"
|
||||
|
||||
//********************************
|
||||
// Fake UART Rx register.
|
||||
//********************************
|
||||
char get_char()
|
||||
enum VectorId
|
||||
{
|
||||
static char c = 'A';
|
||||
return c++;
|
||||
}
|
||||
TIM1_CC_IRQ_HANDLER = 42,
|
||||
TIM2_IRQ_HANDLER = 43,
|
||||
TIM3_IRQ_HANDLER = 44,
|
||||
USART1_IRQ_HANDLER = 52,
|
||||
USART2_IRQ_HANDLER = 53,
|
||||
VECTOR_ID_RANGE = USART2_IRQ_HANDLER - TIM1_CC_IRQ_HANDLER + 1,
|
||||
VECTOR_ID_OFFSET = TIM1_CC_IRQ_HANDLER
|
||||
};
|
||||
|
||||
//********************************
|
||||
// Interrupt vectors & callbacks.
|
||||
//********************************
|
||||
// Callback interfaces.
|
||||
// Note that they do not require any knowledge about the callee apart from the parameter type.
|
||||
etl::ifunction<void>* timer1_callback; // A pointer to a callback taking no parameters.
|
||||
etl::ifunction<void>* timer2_callback; // A pointer to a callback taking no parameters.
|
||||
etl::ifunction<void>* timer3_callback; // A pointer to a callback taking no parameters.
|
||||
etl::ifunction<char>* uart1_rx_callback; // A pointer to a callback taking a char parameter.
|
||||
etl::ifunction<char>* uart2_rx_callback; // A pointer to a callback taking a char parameter.
|
||||
typedef etl::callback_service<VECTOR_ID_RANGE, VECTOR_ID_OFFSET> InterruptVectors;
|
||||
|
||||
// Ensure that the callback service is initialised before use.
|
||||
InterruptVectors& GetInterruptVectorsInstance()
|
||||
{
|
||||
static InterruptVectors interruptVectors;
|
||||
|
||||
return interruptVectors;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
InterruptVectors& interruptVectors = GetInterruptVectorsInstance();
|
||||
|
||||
// Function called from the timer1 interrupt vector.
|
||||
void Timer1Interrupt()
|
||||
void TIM1_CC_IRQHandler()
|
||||
{
|
||||
(*timer1_callback)();
|
||||
interruptVectors.callback<TIM1_CC_IRQ_HANDLER>();
|
||||
}
|
||||
|
||||
// Function called from the timer2 interrupt vector.
|
||||
void Timer2Interrupt()
|
||||
void TIM2_IRQHandler()
|
||||
{
|
||||
(*timer2_callback)();
|
||||
interruptVectors.callback<TIM2_IRQ_HANDLER>();
|
||||
}
|
||||
|
||||
// Function called from the timer3 interrupt vector.
|
||||
void Timer3Interrupt()
|
||||
void TIM3_IRQHandler()
|
||||
{
|
||||
(*timer3_callback)();
|
||||
interruptVectors.callback<TIM3_IRQ_HANDLER>();
|
||||
}
|
||||
|
||||
// Function called from the UART1 rx interrupt vector.
|
||||
void Uart1RxInterrupt()
|
||||
// Function called from the usart1 interrupt vector.
|
||||
void USART1_IRQHandler()
|
||||
{
|
||||
(*uart1_rx_callback)(get_char());
|
||||
interruptVectors.callback<USART1_IRQ_HANDLER>();
|
||||
}
|
||||
|
||||
// Function called from the UART2 rx interrupt vector.
|
||||
void Uart2RxInterrupt()
|
||||
// Function called from the usart2 interrupt vector.
|
||||
void USART2_IRQHandler()
|
||||
{
|
||||
(*uart2_rx_callback)(get_char());
|
||||
interruptVectors.callback<USART2_IRQ_HANDLER>();
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,34 +66,29 @@ class Timer
|
||||
{
|
||||
public:
|
||||
|
||||
// Constructor.
|
||||
Timer()
|
||||
Timer(int interruptId)
|
||||
: callback(*this)
|
||||
{
|
||||
GetInterruptVectorsInstance().register_callback(interruptId, callback);
|
||||
}
|
||||
|
||||
// Handler for interrupts from the timer.
|
||||
void MemberTimerInterruptHandler()
|
||||
void InterruptHandler(const size_t id)
|
||||
{
|
||||
std::cout << "Timer interrupt (member)\n";
|
||||
std::cout << "Timer interrupt (member) : ID " << id << "\n";
|
||||
}
|
||||
|
||||
// Static handler for interrupts from the timer.
|
||||
static void StaticTimerInterruptHandler()
|
||||
{
|
||||
std::cout << "Timer interrupt (static)\n";
|
||||
}
|
||||
etl::function_mp<Timer, size_t, &Timer::InterruptHandler> callback;
|
||||
};
|
||||
|
||||
//********************************
|
||||
// Free function timer driver.
|
||||
//********************************
|
||||
void FreeTimerInterruptHandler()
|
||||
void FreeTimerInterruptHandler(const size_t id)
|
||||
{
|
||||
std::cout << "Timer interrupt (free)\n";
|
||||
std::cout << "Timer interrupt (free) : ID " << id << "\n";
|
||||
}
|
||||
|
||||
etl::function_fv<FreeTimerInterruptHandler> free_callback;
|
||||
|
||||
//********************************
|
||||
// UART driver.
|
||||
//********************************
|
||||
@ -99,29 +97,37 @@ class Uart
|
||||
public:
|
||||
|
||||
// Constructor.
|
||||
Uart(int port_id)
|
||||
: port_id(port_id)
|
||||
Uart(int port_id, int interruptId)
|
||||
: port_id(port_id),
|
||||
callback(*this)
|
||||
{
|
||||
GetInterruptVectorsInstance().register_callback(interruptId, callback);
|
||||
}
|
||||
|
||||
// Handler for rx interrupts from the UART.
|
||||
void RxInterruptHandler(char c)
|
||||
// Handler for interrupts from the UART.
|
||||
void InterruptHandler(const size_t id)
|
||||
{
|
||||
std::cout << "UART" << port_id << " Rx char interrupt : Received '" << c << "'\n";
|
||||
std::cout << "UART" << port_id << " : ID " << id << "\n";
|
||||
}
|
||||
|
||||
etl::function_mp<Uart, size_t, &Uart::InterruptHandler> callback;
|
||||
|
||||
int port_id;
|
||||
};
|
||||
|
||||
// Declare the driver instances.
|
||||
Timer timer;
|
||||
Uart uart1(0);
|
||||
Uart uart2(1);
|
||||
void UnhandledInterrupt(const size_t id)
|
||||
{
|
||||
std::cout << "Unhandled Interrupt : ID " << id << "\n";
|
||||
}
|
||||
|
||||
etl::function_imv<Timer, timer, &Timer::MemberTimerInterruptHandler> timer_member_callback;
|
||||
etl::function_fv<&Timer::StaticTimerInterruptHandler> timer_static_callback;
|
||||
etl::function_imp<Uart, char, uart1, &Uart::RxInterruptHandler> uart1_callback;
|
||||
etl::function_imp<Uart, char, uart2, &Uart::RxInterruptHandler> uart2_callback;
|
||||
// Declare the driver instances.
|
||||
Timer timer(TIM1_CC_IRQ_HANDLER);
|
||||
Uart uart1(0, USART1_IRQ_HANDLER);
|
||||
Uart uart2(1, USART2_IRQ_HANDLER);
|
||||
|
||||
// Declare the callbacks for the free functions.
|
||||
etl::function_fp<size_t, FreeTimerInterruptHandler> timer_free_callback;
|
||||
etl::function_fp<size_t, UnhandledInterrupt> unhandled_callback;
|
||||
|
||||
//********************************
|
||||
// Test it out.
|
||||
@ -129,21 +135,17 @@ etl::function_imp<Uart, char, uart2, &Uart::RxInterruptHandler> uart2_callb
|
||||
int main()
|
||||
{
|
||||
// Setup the callbacks.
|
||||
// This may be part of the cross platform interface.
|
||||
timer1_callback = &timer_member_callback;
|
||||
timer2_callback = &timer_static_callback;
|
||||
timer3_callback = &free_callback;
|
||||
uart1_rx_callback = &uart1_callback;
|
||||
uart2_rx_callback = &uart2_callback;
|
||||
InterruptVectors& interruptVectors = GetInterruptVectorsInstance();
|
||||
|
||||
interruptVectors.register_callback<TIM2_IRQ_HANDLER>(timer_free_callback);
|
||||
interruptVectors.register_unhandled_callback(unhandled_callback);
|
||||
|
||||
// Simulate the interrupts.
|
||||
Timer1Interrupt();
|
||||
Timer2Interrupt();
|
||||
Timer3Interrupt();
|
||||
Uart1RxInterrupt();
|
||||
Uart2RxInterrupt();
|
||||
TIM1_CC_IRQHandler();
|
||||
TIM2_IRQHandler();
|
||||
USART1_IRQHandler();
|
||||
USART2_IRQHandler();
|
||||
TIM3_IRQHandler(); // Unhandled!
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@
|
||||
<ProjectGuid>{5157DB15-C255-4E47-9FB1-AF388437F90F}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>FunctionInterruptSimulation</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.15063.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
@ -104,12 +104,12 @@
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<AdditionalIncludeDirectories>../../../src</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>../../../include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
||||
159
include/etl/callback_service.h
Normal file
159
include/etl/callback_service.h
Normal file
@ -0,0 +1,159 @@
|
||||
///\file
|
||||
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2019 jwellbelove
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef ETL_CALLBACK_SERVICE_INCLUDED
|
||||
#define ETL_CALLBACK_SERVICE_INCLUDED
|
||||
|
||||
#include "platform.h"
|
||||
#include "nullptr.h"
|
||||
#include "static_assert.h"
|
||||
#include "function.h"
|
||||
#include "array.h"
|
||||
|
||||
namespace etl
|
||||
{
|
||||
//***************************************************************************
|
||||
/// An indexed callback service.
|
||||
/// \tparam RANGE The number of callbacks to handle.
|
||||
/// \tparam OFFSET The lowest callback id value.
|
||||
/// The callback ids must range between OFFSET and OFFSET + RANGE - 1.
|
||||
//***************************************************************************
|
||||
template <const size_t RANGE, const size_t OFFSET = 0U>
|
||||
class callback_service
|
||||
{
|
||||
public:
|
||||
|
||||
//*************************************************************************
|
||||
/// Reset the callback service.
|
||||
/// Sets all callbacks to the internal default.
|
||||
//*************************************************************************
|
||||
callback_service()
|
||||
: unhandled_callback(*this),
|
||||
p_unhandled(nullptr)
|
||||
{
|
||||
lookup.fill(&unhandled_callback);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Registers a callback for the specified id.
|
||||
/// Compile time assert if the id is out of range.
|
||||
/// \tparam ID The id of the callback.
|
||||
/// \param callback Reference to the callback.
|
||||
//*************************************************************************
|
||||
template <const size_t ID>
|
||||
void register_callback(etl::ifunction<size_t>& callback)
|
||||
{
|
||||
ETL_STATIC_ASSERT(ID < (OFFSET + RANGE), "Callback Id out of range");
|
||||
ETL_STATIC_ASSERT(ID >= OFFSET, "Callback Id out of range");
|
||||
|
||||
lookup[ID - OFFSET] = &callback;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Registers a callback for the specified id.
|
||||
/// No action if the id is out of range.
|
||||
/// \param id Id of the callback.
|
||||
/// \param callback Reference to the callback.
|
||||
//*************************************************************************
|
||||
void register_callback(const size_t id, etl::ifunction<size_t>& callback)
|
||||
{
|
||||
if ((id >= OFFSET) && (id < (OFFSET + RANGE)))
|
||||
{
|
||||
lookup[id - OFFSET] = &callback;
|
||||
}
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Registers an alternative callback for unhandled ids.
|
||||
/// \param callback A reference to the user supplied 'unhandled' callback.
|
||||
//*************************************************************************
|
||||
void register_unhandled_callback(etl::ifunction<size_t>& callback)
|
||||
{
|
||||
p_unhandled = &callback;
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Executes the callback function for the index.
|
||||
/// Compile time assert if the id is out of range.
|
||||
/// \tparam ID The id of the callback.
|
||||
//*************************************************************************
|
||||
template <const size_t ID>
|
||||
void callback()
|
||||
{
|
||||
ETL_STATIC_ASSERT(ID < (OFFSET + RANGE), "Callback Id out of range");
|
||||
ETL_STATIC_ASSERT(ID >= OFFSET, "Callback Id out of range");
|
||||
|
||||
(*lookup[ID - OFFSET])(ID);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
/// Executes the callback function for the index.
|
||||
/// \param id Id of the callback.
|
||||
//*************************************************************************
|
||||
void callback(const size_t id)
|
||||
{
|
||||
if ((id >= OFFSET) && (id < (OFFSET + RANGE)))
|
||||
{
|
||||
(*lookup[id - OFFSET])(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
unhandled(id);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
//*************************************************************************
|
||||
/// The default callback function.
|
||||
/// Calls the user defined 'unhandled' callback if it exists.
|
||||
//*************************************************************************
|
||||
void unhandled(size_t id)
|
||||
{
|
||||
if (p_unhandled != nullptr)
|
||||
{
|
||||
(*p_unhandled)(id);
|
||||
}
|
||||
}
|
||||
|
||||
/// The default callback for unhandled ids.
|
||||
etl::function_mp<callback_service<RANGE, OFFSET>,
|
||||
size_t,
|
||||
&callback_service<RANGE, OFFSET>::unhandled> unhandled_callback;
|
||||
|
||||
/// Pointer to the user defined 'unhandled' callback.
|
||||
etl::ifunction<size_t>* p_unhandled;
|
||||
|
||||
/// Lookup table of callbacks.
|
||||
etl::array<etl::ifunction<size_t>*, RANGE> lookup;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -38,8 +38,8 @@ SOFTWARE.
|
||||
///\ingroup utilities
|
||||
|
||||
#define ETL_VERSION_MAJOR 14
|
||||
#define ETL_VERSION_MINOR 7
|
||||
#define ETL_VERSION_PATCH 2
|
||||
#define ETL_VERSION_MINOR 8
|
||||
#define ETL_VERSION_PATCH 0
|
||||
|
||||
#define ETL_VERSION ETL_STRINGIFY(ETL_VERSION_MAJOR) ETL_STRINGIFY(ETL_VERSION_MINOR) ETL_STRINGIFY(ETL_VERSION_PATCH)
|
||||
#define ETL_VERSION_W ETL_WIDE_STRING(ETL_CONCAT(ETL_CONCAT(ETL_VERSION_MAJOR, ETL_VERSION_MINOR), ETL_VERSION_PATCH))
|
||||
|
||||
@ -1,3 +1,8 @@
|
||||
===============================================================================
|
||||
14.8.0
|
||||
Added etl::callback_service
|
||||
Useful for abstracting the interrupt system from C++ handlers.
|
||||
|
||||
===============================================================================
|
||||
14.7.2
|
||||
Added #include <new> to message_router.h for improved cross platform compatibility.
|
||||
|
||||
@ -161,6 +161,7 @@
|
||||
<Unit filename="../../include/etl/bloom_filter.h" />
|
||||
<Unit filename="../../include/etl/c/ecl_timer.h" />
|
||||
<Unit filename="../../include/etl/callback.h" />
|
||||
<Unit filename="../../include/etl/callback_service.h" />
|
||||
<Unit filename="../../include/etl/callback_timer.h" />
|
||||
<Unit filename="../../include/etl/char_traits.h" />
|
||||
<Unit filename="../../include/etl/checksum.h" />
|
||||
@ -341,6 +342,7 @@
|
||||
<Unit filename="../test_bloom_filter.cpp" />
|
||||
<Unit filename="../test_bsd_checksum.cpp" />
|
||||
<Unit filename="../test_c_timer_framework.cpp" />
|
||||
<Unit filename="../test_callback_service.cpp" />
|
||||
<Unit filename="../test_callback_timer.cpp" />
|
||||
<Unit filename="../test_checksum.cpp" />
|
||||
<Unit filename="../test_compare.cpp" />
|
||||
|
||||
333
test/test_callback_service.cpp
Normal file
333
test/test_callback_service.cpp
Normal file
@ -0,0 +1,333 @@
|
||||
/******************************************************************************
|
||||
The MIT License(MIT)
|
||||
|
||||
Embedded Template Library.
|
||||
https://github.com/ETLCPP/etl
|
||||
https://www.etlcpp.com
|
||||
|
||||
Copyright(c) 2019 jwellbelove
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files(the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions :
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
#include "UnitTest++.h"
|
||||
|
||||
#include "etl/function.h"
|
||||
#include "etl/callback_service.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
const size_t SIZE = 3U;
|
||||
const size_t OFFSET = 5U;
|
||||
|
||||
typedef etl::callback_service<SIZE, OFFSET> Service;
|
||||
|
||||
//*****************************************************************************
|
||||
bool global_called = false;
|
||||
bool member1_called = false;
|
||||
bool member2_called = false;
|
||||
bool unhandled_called = false;
|
||||
size_t called_id = UINT_MAX;
|
||||
|
||||
//*****************************************************************************
|
||||
// The global function taking no parameters.
|
||||
//*****************************************************************************
|
||||
void global(size_t id)
|
||||
{
|
||||
global_called = true;
|
||||
called_id = id;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// The external unhandled callback.
|
||||
//*****************************************************************************
|
||||
void unhandled(size_t id)
|
||||
{
|
||||
unhandled_called = true;
|
||||
called_id = id;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// The test class with member functions.
|
||||
//*****************************************************************************
|
||||
class Test
|
||||
{
|
||||
public:
|
||||
|
||||
Test()
|
||||
: callback(*this)
|
||||
{
|
||||
}
|
||||
|
||||
void member1(size_t id)
|
||||
{
|
||||
member1_called = true;
|
||||
called_id = id;
|
||||
}
|
||||
|
||||
void member2(size_t id)
|
||||
{
|
||||
member2_called = true;
|
||||
called_id = id;
|
||||
}
|
||||
|
||||
// Callback for 'member1'.
|
||||
etl::function_mp<Test, size_t, &Test::member1> callback;
|
||||
};
|
||||
|
||||
Test test;
|
||||
|
||||
// Callback for 'member2'.
|
||||
etl::function_imp<Test, size_t, test, &Test::member2> member_callback;
|
||||
|
||||
// Callback for 'global'.
|
||||
etl::function_fp<size_t, global> global_callback;
|
||||
|
||||
// Callback for 'unhandled'.
|
||||
etl::function_fp<size_t, unhandled> unhandled_callback;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
// Initialises the test results.
|
||||
//*****************************************************************************
|
||||
struct SetupFixture
|
||||
{
|
||||
SetupFixture()
|
||||
{
|
||||
called_id = UINT_MAX;
|
||||
global_called = false;
|
||||
member1_called = false;
|
||||
member2_called = false;
|
||||
unhandled_called = false;
|
||||
}
|
||||
};
|
||||
|
||||
namespace
|
||||
{
|
||||
enum
|
||||
{
|
||||
GLOBAL = OFFSET,
|
||||
MEMBER1,
|
||||
MEMBER2,
|
||||
OUT_OF_RANGE
|
||||
};
|
||||
|
||||
SUITE(test_callback_service)
|
||||
{
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_callback_global_compile_time)
|
||||
{
|
||||
Service service;
|
||||
|
||||
service.register_callback<GLOBAL>(global_callback);
|
||||
service.register_callback<MEMBER1>(test.callback);
|
||||
service.register_callback<MEMBER2>(member_callback);
|
||||
|
||||
service.callback<GLOBAL>();
|
||||
|
||||
CHECK_EQUAL(GLOBAL, called_id);
|
||||
CHECK(global_called);
|
||||
CHECK(!member1_called);
|
||||
CHECK(!member2_called);
|
||||
CHECK(!unhandled_called);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_callback_global_run_time)
|
||||
{
|
||||
Service service;
|
||||
|
||||
service.register_callback(GLOBAL, global_callback);
|
||||
service.register_callback(MEMBER1, test.callback);
|
||||
service.register_callback(MEMBER2, member_callback);
|
||||
|
||||
service.callback(GLOBAL);
|
||||
|
||||
CHECK_EQUAL(GLOBAL, called_id);
|
||||
CHECK(global_called);
|
||||
CHECK(!member1_called);
|
||||
CHECK(!member2_called);
|
||||
CHECK(!unhandled_called);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_callback_member1_compile_time)
|
||||
{
|
||||
Service service;
|
||||
|
||||
service.register_callback<GLOBAL>(global_callback);
|
||||
service.register_callback<MEMBER1>(test.callback);
|
||||
service.register_callback<MEMBER2>(member_callback);
|
||||
|
||||
service.callback<MEMBER1>();
|
||||
|
||||
CHECK_EQUAL(MEMBER1, called_id);
|
||||
CHECK(!global_called);
|
||||
CHECK(member1_called);
|
||||
CHECK(!member2_called);
|
||||
CHECK(!unhandled_called);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_callback_member1_run_time)
|
||||
{
|
||||
Service service;
|
||||
|
||||
service.register_callback(GLOBAL, global_callback);
|
||||
service.register_callback(MEMBER1, test.callback);
|
||||
service.register_callback(MEMBER2, member_callback);
|
||||
|
||||
service.callback(MEMBER1);
|
||||
|
||||
CHECK_EQUAL(MEMBER1, called_id);
|
||||
CHECK(!global_called);
|
||||
CHECK(member1_called);
|
||||
CHECK(!member2_called);
|
||||
CHECK(!unhandled_called);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_callback_member2_compile_time)
|
||||
{
|
||||
Service service;
|
||||
|
||||
service.register_callback<GLOBAL>(global_callback);
|
||||
service.register_callback<MEMBER1>(test.callback);
|
||||
service.register_callback<MEMBER2>(member_callback);
|
||||
|
||||
service.callback<MEMBER2>();
|
||||
|
||||
CHECK_EQUAL(MEMBER2, called_id);
|
||||
CHECK(!global_called);
|
||||
CHECK(!member1_called);
|
||||
CHECK(member2_called);
|
||||
CHECK(!unhandled_called);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_callback_unhandled_out_of_range_run_time_default)
|
||||
{
|
||||
Service service;
|
||||
|
||||
service.register_callback<GLOBAL>(global_callback);
|
||||
service.register_callback<MEMBER1>(test.callback);
|
||||
service.register_callback<MEMBER2>(member_callback);
|
||||
|
||||
service.callback(OUT_OF_RANGE);
|
||||
|
||||
CHECK_EQUAL(UINT_MAX, called_id);
|
||||
CHECK(!global_called);
|
||||
CHECK(!member1_called);
|
||||
CHECK(!member2_called);
|
||||
CHECK(!unhandled_called);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_callback_unhandled_out_of_range_run_time_user_supplied)
|
||||
{
|
||||
Service service;
|
||||
|
||||
service.register_callback<GLOBAL>(global_callback);
|
||||
service.register_callback<MEMBER1>(test.callback);
|
||||
service.register_callback<MEMBER2>(member_callback);
|
||||
|
||||
service.register_unhandled_callback(unhandled_callback);
|
||||
|
||||
service.callback(OUT_OF_RANGE);
|
||||
|
||||
CHECK_EQUAL(OUT_OF_RANGE, called_id);
|
||||
CHECK(!global_called);
|
||||
CHECK(!member1_called);
|
||||
CHECK(!member2_called);
|
||||
CHECK(unhandled_called);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_callback_unhandled_not_registered_compile_time_default)
|
||||
{
|
||||
Service service;
|
||||
|
||||
service.register_callback<GLOBAL>(global_callback);
|
||||
service.register_callback<MEMBER2>(member_callback);
|
||||
|
||||
service.callback<MEMBER1>();
|
||||
|
||||
CHECK_EQUAL(UINT_MAX, called_id);
|
||||
CHECK(!global_called);
|
||||
CHECK(!member1_called);
|
||||
CHECK(!member2_called);
|
||||
CHECK(!unhandled_called);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_callback_unhandled_not_registered_run_time_default)
|
||||
{
|
||||
Service service;
|
||||
|
||||
service.register_callback(GLOBAL, global_callback);
|
||||
service.register_callback(MEMBER2, member_callback);
|
||||
|
||||
service.callback(MEMBER1);
|
||||
|
||||
CHECK_EQUAL(UINT_MAX, called_id);
|
||||
CHECK(!global_called);
|
||||
CHECK(!member1_called);
|
||||
CHECK(!member2_called);
|
||||
CHECK(!unhandled_called);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_callback_not_registered_compile_time_user_supplied)
|
||||
{
|
||||
Service service;
|
||||
|
||||
service.register_callback<GLOBAL>(global_callback);
|
||||
service.register_callback<MEMBER2>(member_callback);
|
||||
|
||||
service.register_unhandled_callback(unhandled_callback);
|
||||
|
||||
service.callback<MEMBER1>();
|
||||
|
||||
CHECK_EQUAL(MEMBER1, called_id);
|
||||
CHECK(!global_called);
|
||||
CHECK(!member1_called);
|
||||
CHECK(!member2_called);
|
||||
CHECK(unhandled_called);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
TEST_FIXTURE(SetupFixture, test_callback_unhandled_run_time_user_supplied)
|
||||
{
|
||||
Service service;
|
||||
|
||||
service.register_callback(GLOBAL, global_callback);
|
||||
service.register_callback(MEMBER2, member_callback);
|
||||
|
||||
service.register_unhandled_callback(unhandled_callback);
|
||||
|
||||
service.callback(MEMBER1);
|
||||
|
||||
CHECK_EQUAL(MEMBER1, called_id);
|
||||
CHECK(!global_called);
|
||||
CHECK(!member1_called);
|
||||
CHECK(!member2_called);
|
||||
CHECK(unhandled_called);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -373,6 +373,7 @@
|
||||
<ClInclude Include="..\..\include\etl\c\ecl_timer.h" />
|
||||
<ClInclude Include="..\..\include\etl\fsm.h" />
|
||||
<ClInclude Include="..\..\include\etl\fsm_generator.h" />
|
||||
<ClInclude Include="..\..\include\etl\callback_service.h" />
|
||||
<ClInclude Include="..\..\include\etl\largest_generator.h" />
|
||||
<ClInclude Include="..\..\include\etl\absolute.h" />
|
||||
<ClInclude Include="..\..\include\etl\scaled_rounding.h" />
|
||||
@ -565,6 +566,7 @@
|
||||
<ClCompile Include="..\murmurhash3.cpp" />
|
||||
<ClCompile Include="..\test_algorithm.cpp" />
|
||||
<ClCompile Include="..\test_alignment.cpp" />
|
||||
<ClCompile Include="..\test_callback_service.cpp" />
|
||||
<ClCompile Include="..\test_cumulative_moving_average.cpp" />
|
||||
<ClCompile Include="..\test_forward_list_shared_pool.cpp" />
|
||||
<ClCompile Include="..\test_bit_stream.cpp" />
|
||||
|
||||
@ -723,6 +723,9 @@
|
||||
<ClInclude Include="..\data.h">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\include\etl\callback_service.h">
|
||||
<Filter>ETL\Frameworks</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\main.cpp">
|
||||
@ -1145,6 +1148,9 @@
|
||||
<ClCompile Include="..\test_cumulative_moving_average.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\test_callback_service.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\library.properties">
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user