Updated fsm generator

This commit is contained in:
John Wellbelove 2025-08-13 10:46:14 +01:00
parent e449a09b3e
commit 534fcc6ebe

View File

@ -72,7 +72,9 @@ cog.outl("//********************************************************************
#include "message_router.h"
#include "integral_limits.h"
#include "largest.h"
#include "tuple.h"
#if ETL_USING_CPP11
#include "tuple.h"
#endif
#include <stdint.h>
@ -242,6 +244,7 @@ namespace etl
class ifsm_state;
#if ETL_USING_CPP11
//***************************************************************************
/// A class to store FSM states.
//***************************************************************************
@ -298,6 +301,7 @@ namespace etl
/// Pointers to the states.
etl::ifsm_state* states[sizeof...(TStates)]{ &etl::get<TStates>(storage)... };
};
#endif
//***************************************************************************
/// Interface class for FSM states.
@ -536,30 +540,7 @@ namespace etl
{
etl::fsm_state_id_t next_state_id = p_state->process_event(message);
if (have_changed_state(next_state_id))
{
ETL_ASSERT_OR_RETURN_VALUE(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception), p_state->get_state_id());
etl::ifsm_state* p_next_state = state_list[next_state_id];
do
{
p_state->on_exit_state();
p_state = p_next_state;
next_state_id = p_state->on_enter_state();
if (have_changed_state(next_state_id))
{
ETL_ASSERT_OR_RETURN_VALUE(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception), p_state->get_state_id());
p_next_state = state_list[next_state_id];
}
} while (p_next_state != p_state); // Have we changed state again?
}
else if (is_self_transition(next_state_id))
{
p_state->on_exit_state();
p_state->on_enter_state();
}
process_state_change(next_state_id);
}
else
{
@ -567,6 +548,21 @@ namespace etl
}
}
//*******************************************
/// Invoke a state transition.
//*******************************************
etl::fsm_state_id_t transition_to(etl::fsm_state_id_t new_state_id)
{
if (is_started())
{
return process_state_change(new_state_id);
}
else
{
return ifsm_state::No_State_Change;
}
}
using imessage_router::accepts;
//*******************************************
@ -661,6 +657,39 @@ namespace etl
return (next_state_id == ifsm_state::Self_Transition);
}
//*******************************************
/// Core function to process a state change.
//*******************************************
virtual etl::fsm_state_id_t process_state_change(etl::fsm_state_id_t next_state_id)
{
if (have_changed_state(next_state_id))
{
ETL_ASSERT_OR_RETURN_VALUE(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception), p_state->get_state_id());
etl::ifsm_state* p_next_state = state_list[next_state_id];
do
{
p_state->on_exit_state();
p_state = p_next_state;
next_state_id = p_state->on_enter_state();
if (have_changed_state(next_state_id))
{
ETL_ASSERT_OR_RETURN_VALUE(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception), p_state->get_state_id());
p_next_state = state_list[next_state_id];
}
} while (p_next_state != p_state); // Have we changed state again?
}
else if (is_self_transition(next_state_id))
{
p_state->on_exit_state();
p_state->on_enter_state();
}
return p_state->get_state_id();
}
etl::ifsm_state* p_state; ///< A pointer to the current state.
etl::ifsm_state** state_list; ///< The list of added states.
etl::fsm_state_id_t number_of_states; ///< The number of states.