diff --git a/include/etl/callback_timer.h b/include/etl/callback_timer.h index c725922d..cbd1924d 100644 --- a/include/etl/callback_timer.h +++ b/include/etl/callback_timer.h @@ -385,6 +385,8 @@ namespace etl typedef etl::delegate callback_type; + typedef etl::delegate event_callback_type; + //******************************************* /// Register a timer. //******************************************* @@ -500,6 +502,7 @@ namespace etl { ETL_DISABLE_TIMER_UPDATES; active_list.remove(timer.id, false); + remove_callback.call_if(timer.id); ETL_ENABLE_TIMER_UPDATES; } @@ -571,12 +574,14 @@ namespace etl count -= timer.delta; active_list.remove(timer.id, true); + remove_callback.call_if(timer.id); if (timer.repeating) { // Reinsert the timer. timer.delta = timer.period; active_list.insert(timer.id); + insert_callback.call_if(timer.id); } if (timer.p_callback != ETL_NULLPTR) @@ -637,10 +642,12 @@ namespace etl if (timer.is_active()) { active_list.remove(timer.id, false); + remove_callback.call_if(timer.id); } timer.delta = immediate_ ? 0 : timer.period; active_list.insert(timer.id); + insert_callback.call_if(timer.id); ETL_ENABLE_TIMER_UPDATES; result = true; @@ -670,6 +677,7 @@ namespace etl { ETL_DISABLE_TIMER_UPDATES; active_list.remove(timer.id, false); + remove_callback.call_if(timer.id); ETL_ENABLE_TIMER_UPDATES; } @@ -756,6 +764,34 @@ namespace etl return false; } + //******************************************* + /// Set a callback when a timer is inserted on list + //******************************************* + void set_insert_callback(event_callback_type insert_) + { + insert_callback = insert_; + } + + //******************************************* + /// Set a callback when a timer is removed from list + //******************************************* + void set_remove_callback(event_callback_type remove_) + { + remove_callback = remove_; + } + + //******************************************* + void clear_insert_callback() + { + insert_callback.clear(); + } + + //******************************************* + void clear_remove_callback() + { + remove_callback.clear(); + } + protected: //******************************************* @@ -806,6 +842,9 @@ namespace etl #endif uint_least8_t registered_timers; + event_callback_type insert_callback; + event_callback_type remove_callback; + public: const uint_least8_t MAX_TIMERS; diff --git a/include/etl/callback_timer_atomic.h b/include/etl/callback_timer_atomic.h index d2c63a47..b18703aa 100644 --- a/include/etl/callback_timer_atomic.h +++ b/include/etl/callback_timer_atomic.h @@ -53,6 +53,8 @@ namespace etl typedef etl::delegate callback_type; + typedef etl::delegate event_callback_type; + //******************************************* /// Register a timer. //******************************************* @@ -102,6 +104,7 @@ namespace etl { ++process_semaphore; active_list.remove(timer.id, false); + remove_callback.call_if(timer.id); --process_semaphore; } @@ -173,6 +176,7 @@ namespace etl count -= timer.delta; active_list.remove(timer.id, true); + remove_callback.call_if(timer.id); if (timer.callback.is_valid()) { @@ -185,6 +189,7 @@ namespace etl // Reinsert the timer. timer.delta = timer.period; active_list.insert(timer.id); + insert_callback.call_if(timer.id); } has_active = !active_list.empty(); @@ -226,10 +231,12 @@ namespace etl if (timer.is_active()) { active_list.remove(timer.id, false); + remove_callback.call_if(timer.id); } timer.delta = immediate_ ? 0U : timer.period; active_list.insert(timer.id); + insert_callback.call_if(timer.id); --process_semaphore; result = true; @@ -259,6 +266,7 @@ namespace etl { ++process_semaphore; active_list.remove(timer.id, false); + remove_callback.call_if(timer.id); --process_semaphore; } @@ -355,6 +363,34 @@ namespace etl return result; } + //******************************************* + /// Set a callback when a timer is inserted on list + //******************************************* + void set_insert_callback(event_callback_type insert_) + { + insert_callback = insert_; + } + + //******************************************* + /// Set a callback when a timer is removed from list + //******************************************* + void set_remove_callback(event_callback_type remove_) + { + remove_callback = remove_; + } + + //******************************************* + void clear_insert_callback() + { + insert_callback.clear(); + } + + //******************************************* + void clear_remove_callback() + { + remove_callback.clear(); + } + protected: //************************************************************************* @@ -638,6 +674,9 @@ namespace etl mutable TSemaphore process_semaphore; uint_least8_t number_of_registered_timers; + event_callback_type insert_callback; + event_callback_type remove_callback; + public: const uint_least8_t Max_Timers; diff --git a/include/etl/callback_timer_deferred_locked.h b/include/etl/callback_timer_deferred_locked.h index 2cd97d10..b8546ef7 100644 --- a/include/etl/callback_timer_deferred_locked.h +++ b/include/etl/callback_timer_deferred_locked.h @@ -111,6 +111,7 @@ namespace etl count -= timer.delta; active_list.remove(timer.id, true); + remove_callback.call_if(timer.id); if (timer.callback.is_valid()) { @@ -125,6 +126,7 @@ namespace etl // Reinsert the timer. timer.delta = timer.period; active_list.insert(timer.id); + insert_callback.call_if(timer.id); } has_active = !active_list.empty(); diff --git a/include/etl/callback_timer_interrupt.h b/include/etl/callback_timer_interrupt.h index 22058cdc..247b69de 100644 --- a/include/etl/callback_timer_interrupt.h +++ b/include/etl/callback_timer_interrupt.h @@ -52,6 +52,8 @@ namespace etl typedef etl::delegate callback_type; + typedef etl::delegate event_callback_type; + //******************************************* /// Register a timer. //******************************************* @@ -106,6 +108,7 @@ namespace etl (void)guard; // Silence 'unused variable warnings. active_list.remove(timer.id, false); + remove_callback.call_if(timer.id); } // Reset in-place. @@ -176,6 +179,7 @@ namespace etl count -= timer.delta; active_list.remove(timer.id, true); + remove_callback.call_if(timer.id); if (timer.callback.is_valid()) { @@ -187,6 +191,7 @@ namespace etl // Reinsert the timer. timer.delta = timer.period; active_list.insert(timer.id); + insert_callback.call_if(timer.id); } has_active = !active_list.empty(); @@ -229,10 +234,12 @@ namespace etl if (timer.is_active()) { active_list.remove(timer.id, false); + remove_callback.call_if(timer.id); } timer.delta = immediate_ ? 0U : timer.period; active_list.insert(timer.id); + insert_callback.call_if(timer.id); result = true; } @@ -263,6 +270,7 @@ namespace etl (void)guard; // Silence 'unused variable warnings. active_list.remove(timer.id, false); + remove_callback.call_if(timer.id); } result = true; @@ -356,6 +364,34 @@ namespace etl return false; } + //******************************************* + /// Set a callback when a timer is inserted on list + //******************************************* + void set_insert_callback(event_callback_type insert_) + { + insert_callback = insert_; + } + + //******************************************* + /// Set a callback when a timer is removed from list + //******************************************* + void set_remove_callback(event_callback_type remove_) + { + remove_callback = remove_; + } + + //******************************************* + void clear_insert_callback() + { + insert_callback.clear(); + } + + //******************************************* + void clear_remove_callback() + { + remove_callback.clear(); + } + protected: //************************************************************************* @@ -637,6 +673,9 @@ namespace etl bool enabled; uint_least8_t number_of_registered_timers; + event_callback_type insert_callback; + event_callback_type remove_callback; + public: const uint_least8_t Max_Timers; diff --git a/include/etl/callback_timer_locked.h b/include/etl/callback_timer_locked.h index 861f2101..ff2837c5 100644 --- a/include/etl/callback_timer_locked.h +++ b/include/etl/callback_timer_locked.h @@ -54,6 +54,8 @@ namespace etl typedef etl::delegate lock_type; typedef etl::delegate unlock_type; + typedef etl::delegate event_callback_type; + //******************************************* /// Register a timer. //******************************************* @@ -103,6 +105,7 @@ namespace etl { lock(); active_list.remove(timer.id, false); + remove_callback.call_if(timer.id); unlock(); } @@ -180,10 +183,12 @@ namespace etl if (timer.is_active()) { active_list.remove(timer.id, false); + remove_callback.call_if(timer.id); } timer.delta = immediate_ ? 0U : timer.period; active_list.insert(timer.id); + insert_callback.call_if(timer.id); unlock(); result = true; @@ -213,6 +218,7 @@ namespace etl { lock(); active_list.remove(timer.id, false); + remove_callback.call_if(timer.id); unlock(); } @@ -319,6 +325,34 @@ namespace etl return result; } + //******************************************* + /// Set a callback when a timer is inserted on list + //******************************************* + void set_insert_callback(event_callback_type insert_) + { + insert_callback = insert_; + } + + //******************************************* + /// Set a callback when a timer is removed from list + //******************************************* + void set_remove_callback(event_callback_type remove_) + { + remove_callback = remove_; + } + + //******************************************* + void clear_insert_callback() + { + insert_callback.clear(); + } + + //******************************************* + void clear_remove_callback() + { + remove_callback.clear(); + } + protected: //************************************************************************* @@ -604,6 +638,9 @@ namespace etl lock_type lock; ///< The callback that locks. unlock_type unlock; ///< The callback that unlocks. + event_callback_type insert_callback; + event_callback_type remove_callback; + public: template friend class callback_timer_locked; @@ -666,6 +703,7 @@ namespace etl count -= timer.delta; active_list.remove(timer.id, true); + remove_callback.call_if(timer.id); if (timer.callback.is_valid()) { @@ -677,6 +715,7 @@ namespace etl // Reinsert the timer. timer.delta = timer.period; active_list.insert(timer.id); + insert_callback.call_if(timer.id); } has_active = !active_list.empty(); diff --git a/include/etl/message_timer.h b/include/etl/message_timer.h index 7ddc55fc..094d8b03 100644 --- a/include/etl/message_timer.h +++ b/include/etl/message_timer.h @@ -39,6 +39,7 @@ SOFTWARE. #include "timer.h" #include "atomic.h" #include "algorithm.h" +#include "delegate.h" #include @@ -341,6 +342,8 @@ namespace etl { public: + typedef etl::delegate event_callback_type; + //******************************************* /// Register a timer. //******************************************* @@ -396,6 +399,7 @@ namespace etl { ETL_DISABLE_TIMER_UPDATES; active_list.remove(timer.id, true); + remove_callback.call_if(timer.id); ETL_ENABLE_TIMER_UPDATES; } @@ -467,11 +471,13 @@ namespace etl count -= timer.delta; active_list.remove(timer.id, true); + remove_callback.call_if(timer.id); if (timer.repeating) { timer.delta = timer.period; active_list.insert(timer.id); + insert_callback.call_if(timer.id); } if (timer.p_router != ETL_NULLPTR) @@ -518,10 +524,12 @@ namespace etl if (timer.is_active()) { active_list.remove(timer.id, false); + remove_callback.call_if(timer.id); } timer.delta = immediate_ ? 0 : timer.period; active_list.insert(timer.id); + insert_callback.call_if(timer.id); ETL_ENABLE_TIMER_UPDATES; result = true; @@ -551,6 +559,7 @@ namespace etl { ETL_DISABLE_TIMER_UPDATES; active_list.remove(timer.id, false); + remove_callback.call_if(timer.id); ETL_ENABLE_TIMER_UPDATES; } @@ -619,6 +628,34 @@ namespace etl return delta; } + //******************************************* + /// Set a callback when a timer is inserted on list + //******************************************* + void set_insert_callback(event_callback_type insert_) + { + insert_callback = insert_; + } + + //******************************************* + /// Set a callback when a timer is removed from list + //******************************************* + void set_remove_callback(event_callback_type remove_) + { + remove_callback = remove_; + } + + //******************************************* + void clear_insert_callback() + { + insert_callback.clear(); + } + + //******************************************* + void clear_remove_callback() + { + remove_callback.clear(); + } + protected: //******************************************* @@ -669,6 +706,9 @@ namespace etl #endif uint_least8_t registered_timers; + event_callback_type insert_callback; + event_callback_type remove_callback; + public: const uint_least8_t Max_Timers; diff --git a/include/etl/message_timer_atomic.h b/include/etl/message_timer_atomic.h index a8826da2..cf349c57 100644 --- a/include/etl/message_timer_atomic.h +++ b/include/etl/message_timer_atomic.h @@ -39,6 +39,7 @@ SOFTWARE. #include "timer.h" #include "atomic.h" #include "algorithm.h" +#include "delegate.h" #include @@ -54,6 +55,8 @@ namespace etl { public: + typedef etl::delegate event_callback_type; + //******************************************* /// Register a timer. //******************************************* @@ -109,6 +112,7 @@ namespace etl { ++process_semaphore; active_list.remove(timer.id, true); + remove_callback.call_if(timer.id); --process_semaphore; } @@ -180,6 +184,7 @@ namespace etl count -= timer.delta; active_list.remove(timer.id, true); + remove_callback.call_if(timer.id); if (timer.p_router != ETL_NULLPTR) { @@ -190,6 +195,7 @@ namespace etl { timer.delta = timer.period; active_list.insert(timer.id); + insert_callback.call_if(timer.id); } has_active = !active_list.empty(); @@ -231,10 +237,12 @@ namespace etl if (timer.is_active()) { active_list.remove(timer.id, false); + remove_callback.call_if(timer.id); } timer.delta = immediate_ ? 0U : timer.period; active_list.insert(timer.id); + insert_callback.call_if(timer.id); --process_semaphore; result = true; @@ -264,6 +272,7 @@ namespace etl { ++process_semaphore; active_list.remove(timer.id, false); + remove_callback.call_if(timer.id); --process_semaphore; } @@ -332,6 +341,34 @@ namespace etl return delta; } + //******************************************* + /// Set a callback when a timer is inserted on list + //******************************************* + void set_insert_callback(event_callback_type insert_) + { + insert_callback = insert_; + } + + //******************************************* + /// Set a callback when a timer is removed from list + //******************************************* + void set_remove_callback(event_callback_type remove_) + { + remove_callback = remove_; + } + + //******************************************* + void clear_insert_callback() + { + insert_callback.clear(); + } + + //******************************************* + void clear_remove_callback() + { + remove_callback.clear(); + } + protected: //************************************************************************* @@ -620,6 +657,9 @@ namespace etl mutable TSemaphore process_semaphore; uint_least8_t registered_timers; + event_callback_type insert_callback; + event_callback_type remove_callback; + public: const uint_least8_t MAX_TIMERS; diff --git a/include/etl/message_timer_interrupt.h b/include/etl/message_timer_interrupt.h index 5fc0281d..6945d968 100644 --- a/include/etl/message_timer_interrupt.h +++ b/include/etl/message_timer_interrupt.h @@ -54,6 +54,8 @@ namespace etl typedef etl::delegate callback_type; + typedef etl::delegate event_callback_type; + public: //******************************************* @@ -116,6 +118,7 @@ namespace etl (void)guard; // Silence 'unused variable warnings. active_list.remove(timer.id, true); + remove_callback.call_if(timer.id); } // Reset in-place. @@ -187,6 +190,7 @@ namespace etl count -= timer.delta; active_list.remove(timer.id, true); + remove_callback.call_if(timer.id); if (timer.p_router != ETL_NULLPTR) { @@ -198,6 +202,7 @@ namespace etl // Reinsert the timer. timer.delta = timer.period; active_list.insert(timer.id); + insert_callback.call_if(timer.id); } has_active = !active_list.empty(); @@ -240,10 +245,12 @@ namespace etl if (timer.is_active()) { active_list.remove(timer.id, false); + remove_callback.call_if(timer.id); } timer.delta = immediate_ ? 0 : timer.period; active_list.insert(timer.id); + insert_callback.call_if(timer.id); result = true; } @@ -274,6 +281,7 @@ namespace etl (void)guard; // Silence 'unused variable warnings. active_list.remove(timer.id, false); + remove_callback.call_if(timer.id); } result = true; @@ -340,6 +348,34 @@ namespace etl return delta; } + //******************************************* + /// Set a callback when a timer is inserted on list + //******************************************* + void set_insert_callback(event_callback_type insert_) + { + insert_callback = insert_; + } + + //******************************************* + /// Set a callback when a timer is removed from list + //******************************************* + void set_remove_callback(event_callback_type remove_) + { + remove_callback = remove_; + } + + //******************************************* + void clear_insert_callback() + { + insert_callback.clear(); + } + + //******************************************* + void clear_remove_callback() + { + remove_callback.clear(); + } + protected: //************************************************************************* @@ -626,6 +662,9 @@ namespace etl bool enabled; uint_least8_t number_of_registered_timers; + event_callback_type insert_callback; + event_callback_type remove_callback; + public: const uint_least8_t Max_Timers; diff --git a/include/etl/message_timer_locked.h b/include/etl/message_timer_locked.h index 9f0e2a2c..1d4e4b61 100644 --- a/include/etl/message_timer_locked.h +++ b/include/etl/message_timer_locked.h @@ -56,6 +56,8 @@ namespace etl typedef etl::delegate lock_type; typedef etl::delegate unlock_type; + typedef etl::delegate event_callback_type; + public: //******************************************* @@ -113,6 +115,7 @@ namespace etl { lock(); active_list.remove(timer.id, true); + remove_callback.call_if(timer.id); unlock(); } @@ -184,6 +187,7 @@ namespace etl count -= timer.delta; active_list.remove(timer.id, true); + remove_callback.call_if(timer.id); if (timer.p_router != ETL_NULLPTR) { @@ -194,6 +198,7 @@ namespace etl { timer.delta = timer.period; active_list.insert(timer.id); + insert_callback.call_if(timer.id); } has_active = !active_list.empty(); @@ -237,10 +242,12 @@ namespace etl if (timer.is_active()) { active_list.remove(timer.id, false); + remove_callback.call_if(timer.id); } timer.delta = immediate_ ? 0 : timer.period; active_list.insert(timer.id); + insert_callback.call_if(timer.id); unlock(); result = true; @@ -270,6 +277,7 @@ namespace etl { lock(); active_list.remove(timer.id, false); + remove_callback.call_if(timer.id); unlock(); } @@ -348,6 +356,34 @@ namespace etl return delta; } + //******************************************* + /// Set a callback when a timer is inserted on list + //******************************************* + void set_insert_callback(event_callback_type insert_) + { + insert_callback = insert_; + } + + //******************************************* + /// Set a callback when a timer is removed from list + //******************************************* + void set_remove_callback(event_callback_type remove_) + { + remove_callback = remove_; + } + + //******************************************* + void clear_insert_callback() + { + insert_callback.clear(); + } + + //******************************************* + void clear_remove_callback() + { + remove_callback.clear(); + } + protected: //************************************************************************* @@ -638,6 +674,8 @@ namespace etl lock_type lock; ///< The callback that locks. unlock_type unlock; ///< The callback that unlocks. + event_callback_type insert_callback; + event_callback_type remove_callback; public: const uint_least8_t Max_Timers; diff --git a/test/test_callback_timer.cpp b/test/test_callback_timer.cpp index e800990d..62b2a059 100644 --- a/test/test_callback_timer.cpp +++ b/test/test_callback_timer.cpp @@ -81,10 +81,42 @@ namespace etl::callback_timer<3>* p_controller; }; + using event_callback_type = etl::icallback_timer::event_callback_type; + Object object; etl::function_imv member_callback; etl::function_imv member_callback2; + class TimerInsertRemoveTest + { + public: + uint32_t inserted; + uint32_t removed; + TimerInsertRemoveTest() : inserted(0), removed(0) + { + } + + void insert_handler(etl::timer::id::type id_) + { + (void)id_; + inserted++; + } + + void remove_handler(etl::timer::id::type id_) + { + (void)id_; + removed++; + } + + void clear(void) + { + inserted = 0; + removed = 0; + } + }; + + TimerInsertRemoveTest timerInsertRemoveTest; + //*************************************************************************** // Free function callback via etl::function //*************************************************************************** @@ -762,36 +794,55 @@ namespace //************************************************************************* TEST(callback_timer_is_active) { + timerInsertRemoveTest.clear(); etl::callback_timer<4> timer_controller; etl::timer::id::type id1 = timer_controller.register_timer(member_callback, 37, etl::timer::mode::Single_Shot); etl::timer::id::type id2 = timer_controller.register_timer(free_function_callback, 23, etl::timer::mode::Single_Shot); etl::timer::id::type id3 = timer_controller.register_timer(free_callback2, 11, etl::timer::mode::Single_Shot); + timer_controller.set_insert_callback(event_callback_type::create()); + timer_controller.set_remove_callback(event_callback_type::create()); + timer_controller.start(id1); timer_controller.start(id3); timer_controller.start(id2); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(0, timerInsertRemoveTest.removed); + timer_controller.enable(true); CHECK_TRUE(timer_controller.is_active(id1)); CHECK_TRUE(timer_controller.is_active(id2)); CHECK_TRUE(timer_controller.is_active(id3)); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(0, timerInsertRemoveTest.removed); + timer_controller.tick(11); CHECK_TRUE(timer_controller.is_active(id1)); CHECK_TRUE(timer_controller.is_active(id2)); CHECK_FALSE(timer_controller.is_active(id3)); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(1, timerInsertRemoveTest.removed); + timer_controller.tick(23 - 11); CHECK_TRUE(timer_controller.is_active(id1)); CHECK_FALSE(timer_controller.is_active(id2)); CHECK_FALSE(timer_controller.is_active(id3)); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(2, timerInsertRemoveTest.removed); + timer_controller.tick(37 - 23); CHECK_FALSE(timer_controller.is_active(id1)); CHECK_FALSE(timer_controller.is_active(id2)); CHECK_FALSE(timer_controller.is_active(id3)); + + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(3, timerInsertRemoveTest.removed); } //************************************************************************* diff --git a/test/test_callback_timer_atomic.cpp b/test/test_callback_timer_atomic.cpp index 97d1b366..01b09e89 100644 --- a/test/test_callback_timer_atomic.cpp +++ b/test/test_callback_timer_atomic.cpp @@ -86,10 +86,42 @@ namespace using callback_type = etl::icallback_timer_atomic::callback_type; + using event_callback_type = etl::icallback_timer_atomic::event_callback_type; + Object object; callback_type member_callback1 = callback_type::create(); callback_type member_callback2 = callback_type::create(); + class TimerInsertRemoveTest + { + public: + uint32_t inserted; + uint32_t removed; + TimerInsertRemoveTest() : inserted(0), removed(0) + { + } + + void insert_handler(etl::timer::id::type id_) + { + (void)id_; + inserted++; + } + + void remove_handler(etl::timer::id::type id_) + { + (void)id_; + removed++; + } + + void clear(void) + { + inserted = 0; + removed = 0; + } + }; + + TimerInsertRemoveTest timerInsertRemoveTest; + //*************************************************************************** // Free function callback via etl::function //*************************************************************************** @@ -767,36 +799,55 @@ namespace //************************************************************************* TEST(callback_timer_is_active) { + timerInsertRemoveTest.clear(); etl::callback_timer_atomic<3, std::atomic_uint32_t> timer_controller; etl::timer::id::type id1 = timer_controller.register_timer(member_callback1, 37, etl::timer::mode::Single_Shot); etl::timer::id::type id2 = timer_controller.register_timer(free_function_callback1, 23, etl::timer::mode::Single_Shot); etl::timer::id::type id3 = timer_controller.register_timer(free_function_callback2, 11, etl::timer::mode::Single_Shot); + timer_controller.set_insert_callback(event_callback_type::create()); + timer_controller.set_remove_callback(event_callback_type::create()); + timer_controller.start(id1); timer_controller.start(id3); timer_controller.start(id2); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(0, timerInsertRemoveTest.removed); + timer_controller.enable(true); CHECK_TRUE(timer_controller.is_active(id1)); CHECK_TRUE(timer_controller.is_active(id2)); CHECK_TRUE(timer_controller.is_active(id3)); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(0, timerInsertRemoveTest.removed); + timer_controller.tick(11); CHECK_TRUE(timer_controller.is_active(id1)); CHECK_TRUE(timer_controller.is_active(id2)); CHECK_FALSE(timer_controller.is_active(id3)); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(1, timerInsertRemoveTest.removed); + timer_controller.tick(23 - 11); CHECK_TRUE(timer_controller.is_active(id1)); CHECK_FALSE(timer_controller.is_active(id2)); CHECK_FALSE(timer_controller.is_active(id3)); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(2, timerInsertRemoveTest.removed); + timer_controller.tick(37 - 23); CHECK_FALSE(timer_controller.is_active(id1)); CHECK_FALSE(timer_controller.is_active(id2)); CHECK_FALSE(timer_controller.is_active(id3)); + + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(3, timerInsertRemoveTest.removed); } //************************************************************************* diff --git a/test/test_callback_timer_deferred_locked.cpp b/test/test_callback_timer_deferred_locked.cpp index 591cf732..33610c02 100644 --- a/test/test_callback_timer_deferred_locked.cpp +++ b/test/test_callback_timer_deferred_locked.cpp @@ -147,6 +147,8 @@ namespace using lock_type = etl::icallback_timer_locked::lock_type; using unlock_type = etl::icallback_timer_locked::unlock_type; + using event_callback_type = etl::icallback_timer_locked::event_callback_type; + Object object; callback_type member_callback = callback_type::create(); callback_type member_callback2 = callback_type::create(); @@ -154,6 +156,36 @@ namespace callback_type member_callback_inc2 = callback_type::create(); callback_type member_callback_inc3 = callback_type::create(); + class TimerInsertRemoveTest + { + public: + uint32_t inserted; + uint32_t removed; + TimerInsertRemoveTest() : inserted(0), removed(0) + { + } + + void insert_handler(etl::timer::id::type id_) + { + (void)id_; + inserted++; + } + + void remove_handler(etl::timer::id::type id_) + { + (void)id_; + removed++; + } + + void clear(void) + { + inserted = 0; + removed = 0; + } + }; + + TimerInsertRemoveTest timerInsertRemoveTest; + //*************************************************************************** // Free function callback via etl::function //*************************************************************************** @@ -1024,6 +1056,7 @@ namespace TEST(message_timer_time_to_next_with_has_active_timer) { locks.clear(); + timerInsertRemoveTest.clear(); try_lock_type try_lock = try_lock_type::create(); lock_type lock = lock_type::create(); unlock_type unlock = unlock_type::create(); @@ -1034,31 +1067,49 @@ namespace etl::timer::id::type id2 = timer_controller.register_timer(free_function_callback, 23, etl::timer::mode::Single_Shot); etl::timer::id::type id3 = timer_controller.register_timer(free_function_callback2, 11, etl::timer::mode::Single_Shot); + timer_controller.set_insert_callback(event_callback_type::create()); + timer_controller.set_remove_callback(event_callback_type::create()); + timer_controller.start(id1); timer_controller.start(id3); timer_controller.start(id2); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(0, timerInsertRemoveTest.removed); + timer_controller.enable(true); timer_controller.tick(11); timer_controller.handle_deferred(); - CHECK_EQUAL(12, timer_controller.time_to_next()); + CHECK_EQUAL(23 - 11, timer_controller.time_to_next()); CHECK_TRUE(timer_controller.has_active_timer()); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(1, timerInsertRemoveTest.removed); + timer_controller.tick(23); timer_controller.handle_deferred(); CHECK_EQUAL(3, timer_controller.time_to_next()); CHECK_TRUE(timer_controller.has_active_timer()); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(2, timerInsertRemoveTest.removed); + timer_controller.tick(2); timer_controller.handle_deferred(); CHECK_EQUAL(1, timer_controller.time_to_next()); CHECK_TRUE(timer_controller.has_active_timer()); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(2, timerInsertRemoveTest.removed); + timer_controller.tick(1); timer_controller.handle_deferred(); CHECK_EQUAL(static_cast(etl::timer::interval::No_Active_Interval), timer_controller.time_to_next()); CHECK_FALSE(timer_controller.has_active_timer()); + + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(3, timerInsertRemoveTest.removed); } //************************************************************************* diff --git a/test/test_callback_timer_interrupt.cpp b/test/test_callback_timer_interrupt.cpp index e13683d1..ae373c6e 100644 --- a/test/test_callback_timer_interrupt.cpp +++ b/test/test_callback_timer_interrupt.cpp @@ -99,10 +99,42 @@ namespace using callback_type = etl::icallback_timer_interrupt::callback_type; + using event_callback_type = etl::icallback_timer_interrupt::event_callback_type; + Object object; callback_type member_callback = callback_type::create(); callback_type member_callback2 = callback_type::create(); + class TimerInsertRemoveTest + { + public: + uint32_t inserted; + uint32_t removed; + TimerInsertRemoveTest() : inserted(0), removed(0) + { + } + + void insert_handler(etl::timer::id::type id_) + { + (void)id_; + inserted++; + } + + void remove_handler(etl::timer::id::type id_) + { + (void)id_; + removed++; + } + + void clear(void) + { + inserted = 0; + removed = 0; + } + }; + + TimerInsertRemoveTest timerInsertRemoveTest; + //*************************************************************************** // Free function callback via etl::function //*************************************************************************** @@ -775,36 +807,55 @@ namespace //************************************************************************* TEST(callback_timer_is_active) { + timerInsertRemoveTest.clear(); etl::callback_timer_interrupt<3, ScopedGuard> timer_controller; etl::timer::id::type id1 = timer_controller.register_timer(member_callback, 37, etl::timer::mode::Single_Shot); etl::timer::id::type id2 = timer_controller.register_timer(free_function_callback, 23, etl::timer::mode::Single_Shot); etl::timer::id::type id3 = timer_controller.register_timer(free_function_callback2, 11, etl::timer::mode::Single_Shot); + timer_controller.set_insert_callback(event_callback_type::create()); + timer_controller.set_remove_callback(event_callback_type::create()); + timer_controller.start(id1); timer_controller.start(id3); timer_controller.start(id2); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(0, timerInsertRemoveTest.removed); + timer_controller.enable(true); CHECK_TRUE(timer_controller.is_active(id1)); CHECK_TRUE(timer_controller.is_active(id2)); CHECK_TRUE(timer_controller.is_active(id3)); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(0, timerInsertRemoveTest.removed); + timer_controller.tick(11); CHECK_TRUE(timer_controller.is_active(id1)); CHECK_TRUE(timer_controller.is_active(id2)); CHECK_FALSE(timer_controller.is_active(id3)); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(1, timerInsertRemoveTest.removed); + timer_controller.tick(23 - 11); CHECK_TRUE(timer_controller.is_active(id1)); CHECK_FALSE(timer_controller.is_active(id2)); CHECK_FALSE(timer_controller.is_active(id3)); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(2, timerInsertRemoveTest.removed); + timer_controller.tick(37 - 23); CHECK_FALSE(timer_controller.is_active(id1)); CHECK_FALSE(timer_controller.is_active(id2)); CHECK_FALSE(timer_controller.is_active(id3)); + + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(3, timerInsertRemoveTest.removed); } //************************************************************************* diff --git a/test/test_callback_timer_locked.cpp b/test/test_callback_timer_locked.cpp index c0e21bd1..ddeda3a4 100644 --- a/test/test_callback_timer_locked.cpp +++ b/test/test_callback_timer_locked.cpp @@ -121,10 +121,42 @@ namespace using lock_type = etl::icallback_timer_locked::lock_type; using unlock_type = etl::icallback_timer_locked::unlock_type; + using event_callback_type = etl::icallback_timer_locked::event_callback_type; + Object object; callback_type member_callback = callback_type::create(); callback_type member_callback2 = callback_type::create(); + class TimerInsertRemoveTest + { + public: + uint32_t inserted; + uint32_t removed; + TimerInsertRemoveTest() : inserted(0), removed(0) + { + } + + void insert_handler(etl::timer::id::type id_) + { + (void)id_; + inserted++; + } + + void remove_handler(etl::timer::id::type id_) + { + (void)id_; + removed++; + } + + void clear(void) + { + inserted = 0; + removed = 0; + } + }; + + TimerInsertRemoveTest timerInsertRemoveTest; + //*************************************************************************** // Free function callback via etl::function //*************************************************************************** @@ -874,6 +906,7 @@ namespace //************************************************************************* TEST(callback_timer_is_active) { + timerInsertRemoveTest.clear(); locks.clear(); try_lock_type try_lock = try_lock_type::create(); lock_type lock = lock_type::create(); @@ -885,30 +918,48 @@ namespace etl::timer::id::type id2 = timer_controller.register_timer(free_function_callback, 23, etl::timer::mode::Single_Shot); etl::timer::id::type id3 = timer_controller.register_timer(free_function_callback2, 11, etl::timer::mode::Single_Shot); + timer_controller.set_insert_callback(event_callback_type::create()); + timer_controller.set_remove_callback(event_callback_type::create()); + timer_controller.start(id1); timer_controller.start(id3); timer_controller.start(id2); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(0, timerInsertRemoveTest.removed); + timer_controller.enable(true); CHECK_TRUE(timer_controller.is_active(id1)); CHECK_TRUE(timer_controller.is_active(id2)); CHECK_TRUE(timer_controller.is_active(id3)); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(0, timerInsertRemoveTest.removed); + timer_controller.tick(11); CHECK_TRUE(timer_controller.is_active(id1)); CHECK_TRUE(timer_controller.is_active(id2)); CHECK_FALSE(timer_controller.is_active(id3)); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(1, timerInsertRemoveTest.removed); + timer_controller.tick(23 - 11); CHECK_TRUE(timer_controller.is_active(id1)); CHECK_FALSE(timer_controller.is_active(id2)); CHECK_FALSE(timer_controller.is_active(id3)); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(2, timerInsertRemoveTest.removed); + timer_controller.tick(37 - 23); CHECK_FALSE(timer_controller.is_active(id1)); CHECK_FALSE(timer_controller.is_active(id2)); CHECK_FALSE(timer_controller.is_active(id3)); + + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(3, timerInsertRemoveTest.removed); } //************************************************************************* diff --git a/test/test_message_timer.cpp b/test/test_message_timer.cpp index 0d5231f6..1e4eca2e 100644 --- a/test/test_message_timer.cpp +++ b/test/test_message_timer.cpp @@ -134,6 +134,38 @@ namespace Router1 router1; Bus1 bus1; + using event_callback_type = etl::imessage_timer::event_callback_type; + + class TimerInsertRemoveTest + { + public: + uint32_t inserted; + uint32_t removed; + TimerInsertRemoveTest() : inserted(0), removed(0) + { + } + + void insert_handler(etl::timer::id::type id_) + { + (void)id_; + inserted++; + } + + void remove_handler(etl::timer::id::type id_) + { + (void)id_; + removed++; + } + + void clear(void) + { + inserted = 0; + removed = 0; + } + }; + + TimerInsertRemoveTest timerInsertRemoveTest; + SUITE(test_message_timer) { //************************************************************************* @@ -646,35 +678,57 @@ namespace //************************************************************************* TEST(message_timer_time_to_next_with_has_active_timer) { + timerInsertRemoveTest.clear(); etl::message_timer<3> timer_controller; etl::timer::id::type id1 = timer_controller.register_timer(message1, router1, 37, etl::timer::mode::Single_Shot); etl::timer::id::type id2 = timer_controller.register_timer(message2, router1, 23, etl::timer::mode::Single_Shot); etl::timer::id::type id3 = timer_controller.register_timer(message3, router1, 11, etl::timer::mode::Single_Shot); + timer_controller.set_insert_callback(event_callback_type::create()); + timer_controller.set_remove_callback(event_callback_type::create()); + router1.clear(); timer_controller.start(id1); timer_controller.start(id3); timer_controller.start(id2); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(0, timerInsertRemoveTest.removed); + timer_controller.enable(true); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(0, timerInsertRemoveTest.removed); + timer_controller.tick(11); CHECK_EQUAL(12, timer_controller.time_to_next()); CHECK_TRUE(timer_controller.has_active_timer()); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(1, timerInsertRemoveTest.removed); + timer_controller.tick(23); CHECK_EQUAL(3, timer_controller.time_to_next()); CHECK_TRUE(timer_controller.has_active_timer()); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(2, timerInsertRemoveTest.removed); + timer_controller.tick(2); CHECK_EQUAL(1, timer_controller.time_to_next()); CHECK_TRUE(timer_controller.has_active_timer()); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(2, timerInsertRemoveTest.removed); + timer_controller.tick(1); CHECK_EQUAL(static_cast(etl::timer::interval::No_Active_Interval), timer_controller.time_to_next()); CHECK_FALSE(timer_controller.has_active_timer()); + + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(3, timerInsertRemoveTest.removed); } //************************************************************************* diff --git a/test/test_message_timer_atomic.cpp b/test/test_message_timer_atomic.cpp index 98a899ee..b612cd46 100644 --- a/test/test_message_timer_atomic.cpp +++ b/test/test_message_timer_atomic.cpp @@ -134,6 +134,38 @@ namespace Router1 router1; Bus1 bus1; + using event_callback_type = etl::imessage_timer_atomic::event_callback_type; + + class TimerInsertRemoveTest + { + public: + uint32_t inserted; + uint32_t removed; + TimerInsertRemoveTest() : inserted(0), removed(0) + { + } + + void insert_handler(etl::timer::id::type id_) + { + (void)id_; + inserted++; + } + + void remove_handler(etl::timer::id::type id_) + { + (void)id_; + removed++; + } + + void clear(void) + { + inserted = 0; + removed = 0; + } + }; + + TimerInsertRemoveTest timerInsertRemoveTest; + SUITE(test_message_timer) { //************************************************************************* @@ -646,35 +678,57 @@ namespace //************************************************************************* TEST(message_timer_time_to_next_with_has_active_timer) { + timerInsertRemoveTest.clear(); etl::message_timer_atomic<3, std::atomic_uint32_t> timer_controller; etl::timer::id::type id1 = timer_controller.register_timer(message1, router1, 37, etl::timer::mode::Single_Shot); etl::timer::id::type id2 = timer_controller.register_timer(message2, router1, 23, etl::timer::mode::Single_Shot); etl::timer::id::type id3 = timer_controller.register_timer(message3, router1, 11, etl::timer::mode::Single_Shot); + timer_controller.set_insert_callback(event_callback_type::create()); + timer_controller.set_remove_callback(event_callback_type::create()); + router1.clear(); timer_controller.start(id1); timer_controller.start(id3); timer_controller.start(id2); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(0, timerInsertRemoveTest.removed); + timer_controller.enable(true); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(0, timerInsertRemoveTest.removed); + timer_controller.tick(11); CHECK_EQUAL(12, timer_controller.time_to_next()); CHECK_TRUE(timer_controller.has_active_timer()); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(1, timerInsertRemoveTest.removed); + timer_controller.tick(23); CHECK_EQUAL(3, timer_controller.time_to_next()); CHECK_TRUE(timer_controller.has_active_timer()); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(2, timerInsertRemoveTest.removed); + timer_controller.tick(2); CHECK_EQUAL(1, timer_controller.time_to_next()); CHECK_TRUE(timer_controller.has_active_timer()); + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(2, timerInsertRemoveTest.removed); + timer_controller.tick(1); CHECK_EQUAL(static_cast(etl::timer::interval::No_Active_Interval), timer_controller.time_to_next()); CHECK_FALSE(timer_controller.has_active_timer()); + + CHECK_EQUAL(3, timerInsertRemoveTest.inserted); + CHECK_EQUAL(3, timerInsertRemoveTest.removed); } //*************************************************************************