From 5904687e6d7fe2a48c20db4a87583cadb8ced595 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Tue, 10 Aug 2021 20:25:27 +0100 Subject: [PATCH] Variadic FSM --- include/etl/bip_buffer_spsc_atomic.h | 4 +- include/etl/fsm.h | 78 ++++++++++++++++++++++++++ include/etl/generators/fsm_generator.h | 78 ++++++++++++++++++++++++++ include/etl/message.h | 2 +- test/etl_profile.h | 1 + 5 files changed, 161 insertions(+), 2 deletions(-) diff --git a/include/etl/bip_buffer_spsc_atomic.h b/include/etl/bip_buffer_spsc_atomic.h index 4b2427aa..6cc54013 100644 --- a/include/etl/bip_buffer_spsc_atomic.h +++ b/include/etl/bip_buffer_spsc_atomic.h @@ -500,7 +500,9 @@ namespace etl /// Default constructor. //************************************************************************* bip_buffer_spsc_atomic() - : base_t(reinterpret_cast(&buffer[0]), RESERVED_SIZE) + : buffer() + , base_t(reinterpret_cast(&buffer[0]), RESERVED_SIZE) + { } diff --git a/include/etl/fsm.h b/include/etl/fsm.h index cf1216eb..d2429ea3 100644 --- a/include/etl/fsm.h +++ b/include/etl/fsm.h @@ -480,6 +480,82 @@ namespace etl etl::fsm_state_id_t number_of_states; ///< The number of states. }; +#if ETL_CPP17_SUPPORTED && !defined(ETL_FSM_FORCE_CPP03) // For C++17 and above + + //*************************************************************************** +// The definition for all types. +//*************************************************************************** + template + class fsm_state : public ifsm_state + { + public: + + public: + + enum + { + STATE_ID = STATE_ID_ + }; + + fsm_state() + : ifsm_state(STATE_ID) + { + } + + protected: + + ~fsm_state() + { + } + + inline TContext& get_fsm_context() const + { + return static_cast(ifsm_state::get_fsm_context()); + } + + private: + + //******************************************** + struct result_t + { + bool was_handled; + etl::fsm_state_id_t state_id; + }; + + //******************************************** + etl::fsm_state_id_t process_event(const etl::imessage& message) + { + etl::fsm_state_id_t new_state_id; + etl::message_id_t event_id = message.get_message_id(); + + const bool was_handled = (process_event_type(message, new_state_id) || ...); + + if (!was_handled) + { + new_state_id = (p_parent != nullptr) ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message); + } + + return new_state_id; + } + + //******************************************** + template + bool process_event_type(const etl::imessage& msg, etl::fsm_state_id_t& state_id) + { + if (TMessage::ID == msg.get_message_id()) + { + state_id = static_cast(this)->on_event(static_cast(msg)); + return true; + } + else + { + return false; + } + } + }; + +#else // For C++03, C++11 & C++14 + //*************************************************************************** // The definition for all 16 message types. //*************************************************************************** @@ -1411,6 +1487,8 @@ namespace etl return p_parent ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message); } }; + +#endif } #include "private/minmax_pop.h" diff --git a/include/etl/generators/fsm_generator.h b/include/etl/generators/fsm_generator.h index 8bd67bb8..35638249 100644 --- a/include/etl/generators/fsm_generator.h +++ b/include/etl/generators/fsm_generator.h @@ -506,6 +506,82 @@ namespace etl etl::fsm_state_id_t number_of_states; ///< The number of states. }; +#if ETL_CPP17_SUPPORTED && !defined(ETL_FSM_FORCE_CPP03) // For C++17 and above + + //*************************************************************************** +// The definition for all types. +//*************************************************************************** + template + class fsm_state : public ifsm_state + { + public: + + public: + + enum + { + STATE_ID = STATE_ID_ + }; + + fsm_state() + : ifsm_state(STATE_ID) + { + } + + protected: + + ~fsm_state() + { + } + + inline TContext& get_fsm_context() const + { + return static_cast(ifsm_state::get_fsm_context()); + } + + private: + + //******************************************** + struct result_t + { + bool was_handled; + etl::fsm_state_id_t state_id; + }; + + //******************************************** + etl::fsm_state_id_t process_event(const etl::imessage& message) + { + etl::fsm_state_id_t new_state_id; + etl::message_id_t event_id = message.get_message_id(); + + const bool was_handled = (process_event_type(message, new_state_id) || ...); + + if (!was_handled) + { + new_state_id = (p_parent != nullptr) ? p_parent->process_event(message) : static_cast(this)->on_event_unknown(message); + } + + return new_state_id; + } + + //******************************************** + template + bool process_event_type(const etl::imessage& msg, etl::fsm_state_id_t& state_id) + { + if (TMessage::ID == msg.get_message_id()) + { + state_id = static_cast(this)->on_event(static_cast(msg)); + return true; + } + else + { + return false; + } + } + }; + +#else // For C++03, C++11 & C++14 + /*[[[cog import cog ################################################ @@ -692,6 +768,8 @@ namespace etl cog.outl("};") ]]]*/ /*[[[end]]]*/ + +#endif } #include "private/minmax_pop.h" diff --git a/include/etl/message.h b/include/etl/message.h index 27b634a1..cae10650 100644 --- a/include/etl/message.h +++ b/include/etl/message.h @@ -91,7 +91,7 @@ namespace etl ID = ID_ }; - ETL_CONSTEXPR ETL_NODISCARD etl::message_id_t get_message_id() const ETL_NOEXCEPT ETL_OVERRIDE + ETL_NODISCARD etl::message_id_t get_message_id() const ETL_NOEXCEPT ETL_OVERRIDE { return ID; } diff --git a/test/etl_profile.h b/test/etl_profile.h index 469975bb..c28904c8 100644 --- a/test/etl_profile.h +++ b/test/etl_profile.h @@ -97,6 +97,7 @@ SOFTWARE. #define ETL_MESSAGE_PACKET_FORCE_CPP03 #define ETL_OBSERVER_FORCE_CPP03 #define ETL_MESSAGE_ROUTER_FORCE_CPP03 + #define ETL_FSM_FORCE_CPP03 #endif #if defined(ETL_FORCE_TEST_CPP11)