Variadic FSM

This commit is contained in:
John Wellbelove 2021-08-10 20:25:27 +01:00
parent 774384e316
commit 5904687e6d
5 changed files with 161 additions and 2 deletions

View File

@ -500,7 +500,9 @@ namespace etl
/// Default constructor.
//*************************************************************************
bip_buffer_spsc_atomic()
: base_t(reinterpret_cast<T*>(&buffer[0]), RESERVED_SIZE)
: buffer()
, base_t(reinterpret_cast<T*>(&buffer[0]), RESERVED_SIZE)
{
}

View File

@ -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 <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_, typename... TMessageTypes>
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<TContext&>(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<TMessageTypes>(message, new_state_id) || ...);
if (!was_handled)
{
new_state_id = (p_parent != nullptr) ? p_parent->process_event(message) : static_cast<TDerived*>(this)->on_event_unknown(message);
}
return new_state_id;
}
//********************************************
template <typename TMessage>
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<TDerived*>(this)->on_event(static_cast<const TMessage&>(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<TDerived*>(this)->on_event_unknown(message);
}
};
#endif
}
#include "private/minmax_pop.h"

View File

@ -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 <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_, typename... TMessageTypes>
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<TContext&>(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<TMessageTypes>(message, new_state_id) || ...);
if (!was_handled)
{
new_state_id = (p_parent != nullptr) ? p_parent->process_event(message) : static_cast<TDerived*>(this)->on_event_unknown(message);
}
return new_state_id;
}
//********************************************
template <typename TMessage>
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<TDerived*>(this)->on_event(static_cast<const TMessage&>(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"

View File

@ -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;
}

View File

@ -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)