Minor changes & renames

This commit is contained in:
John Wellbelove 2021-04-24 09:25:39 +01:00
parent c5850a005b
commit 7f2ea864e0
5 changed files with 145 additions and 67 deletions

View File

@ -153,13 +153,13 @@ namespace etl
};
//***************************************************************************
/// Exception for forbidden state changes.
/// Exception for forbidden state chages.
//***************************************************************************
class fsm_state_enter_state_change_forbidden : public etl::fsm_exception
class fsm_state_composite_state_change_forbidden : public etl::fsm_exception
{
public:
fsm_state_enter_state_change_forbidden(string_type file_name_, numeric_type line_number_)
: etl::fsm_exception(ETL_ERROR_TEXT("fsm:enter state change in composite state forbidden", ETL_FSM_FILE_ID"E"), file_name_, line_number_)
fsm_state_composite_state_change_forbidden(string_type file_name_, numeric_type line_number_)
: etl::fsm_exception(ETL_ERROR_TEXT("fsm:change in composite state forbidden", ETL_FSM_FILE_ID"E"), file_name_, line_number_)
{
}
};
@ -173,16 +173,16 @@ namespace etl
// Pass this whenever no state change is desired. Specifically cast to
// Highest unsigned value of fsm_state_id_t.
static const fsm_state_id_t NO_CHANGE = static_cast<fsm_state_id_t>(-1);
static const fsm_state_id_t No_State_Change = static_cast<fsm_state_id_t>(-1);
/// Allows ifsm_state functions to be private.
friend class etl::fsm;
friend class etl::hfsm;
template <typename, typename, const etl::fsm_state_id_t,
typename, typename, typename, typename,
typename, typename, typename, typename,
typename, typename, typename, typename,
typename, typename, typename, typename >
typename, typename, typename, typename,
typename, typename, typename, typename,
typename, typename, typename, typename,
typename, typename, typename, typename >
friend class etl::fsm_state;
//*******************************************
@ -196,21 +196,56 @@ namespace etl
//*******************************************
/// Adds a child to this state.
//*******************************************
void add_child(etl::ifsm_state& state)
void add_child_state(etl::ifsm_state& state)
{
ETL_ASSERT(state.p_parent == ETL_NULLPTR, ETL_ERROR(etl::fsm_null_state_exception));
state.p_parent = this;
if (p_default_child == ETL_NULLPTR)
{
p_active_child = &state;
p_default_child = &state;
}
}
//*******************************************
/// Adds the initial child to this state.
/// Adds a list of child states.
//*******************************************
void add_initial_child(etl::ifsm_state& state)
template <typename TSize>
void set_child_states(etl::ifsm_state** state_list, TSize size)
{
ETL_ASSERT(p_default_active_child == ETL_NULLPTR, ETL_ERROR(etl::fsm_null_state_exception));
add_child(state);
p_active_child = &state;
p_default_active_child = &state;
p_active_child = ETL_NULLPTR;
p_default_child = ETL_NULLPTR;
for (TSize i = 0; i < size; ++i)
{
ETL_ASSERT(state_list[i] != ETL_NULLPTR, ETL_ERROR(etl::fsm_null_state_exception));
add_child_state(*state_list[i]);
}
}
//*******************************************
/// Get the parent state for this state.
//*******************************************
etl::ifsm_state* get_parent_state() const
{
return p_parent;
}
//*******************************************
/// Get the active child state for this state.
//*******************************************
etl::ifsm_state* get_active_child_state() const
{
return p_active_child;
}
//*******************************************
/// Get the default child state for this state.
//*******************************************
etl::ifsm_state* get_default_child_state() const
{
return p_default_child;
}
protected:
@ -223,7 +258,7 @@ namespace etl
p_context(ETL_NULLPTR),
p_parent(ETL_NULLPTR),
p_active_child(ETL_NULLPTR),
p_default_active_child(ETL_NULLPTR)
p_default_child(ETL_NULLPTR)
{
}
@ -244,7 +279,7 @@ namespace etl
virtual fsm_state_id_t process_event(const etl::imessage& message) = 0;
virtual fsm_state_id_t on_enter_state() { return NO_CHANGE; } // By default, do nothing.
virtual fsm_state_id_t on_enter_state() { return No_State_Change; } // By default, do nothing.
virtual void on_exit_state() {} // By default, do nothing.
//*******************************************
@ -266,7 +301,7 @@ namespace etl
ifsm_state* p_active_child;
// A pointer to the default active child.
ifsm_state* p_default_active_child;
ifsm_state* p_default_child;
// Disabled.
ifsm_state(const ifsm_state&);
@ -304,7 +339,7 @@ namespace etl
number_of_states = etl::fsm_state_id_t(size);
ETL_ASSERT(number_of_states > 0, ETL_ERROR(etl::fsm_state_list_exception));
ETL_ASSERT(number_of_states < ifsm_state::NO_CHANGE, ETL_ERROR(etl::fsm_state_list_exception));
ETL_ASSERT(number_of_states < ifsm_state::No_State_Change, ETL_ERROR(etl::fsm_state_list_exception));
for (etl::fsm_state_id_t i = 0; i < size; ++i)
{
@ -337,7 +372,7 @@ namespace etl
{
p_last_state = p_state;
next_state_id = p_state->on_enter_state();
if (next_state_id != ifsm_state::NO_CHANGE)
if (next_state_id != ifsm_state::No_State_Change)
{
ETL_ASSERT(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception));
p_state = state_list[next_state_id];
@ -354,7 +389,7 @@ namespace etl
{
etl::fsm_state_id_t next_state_id = p_state->process_event(message);
if(next_state_id != ifsm_state::NO_CHANGE)
if(next_state_id != ifsm_state::No_State_Change)
{
ETL_ASSERT(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception));
etl::ifsm_state* p_next_state = state_list[next_state_id];
@ -368,7 +403,7 @@ namespace etl
p_state = p_next_state;
next_state_id = p_state->on_enter_state();
if(next_state_id != ifsm_state::NO_CHANGE)
if(next_state_id != ifsm_state::No_State_Change)
{
ETL_ASSERT(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception));
p_next_state = state_list[next_state_id];
@ -467,9 +502,9 @@ namespace etl
// The definition for all 16 message types.
//***************************************************************************
template <typename TContext, typename TDerived, const etl::fsm_state_id_t STATE_ID_,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8,
typename T9, typename T10, typename T11, typename T12,
typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8,
typename T9, typename T10, typename T11, typename T12,
typename T13, typename T14, typename T15, typename T16>
class fsm_state : public ifsm_state
{

View File

@ -164,11 +164,14 @@ namespace etl
}
};
class fsm_state_enter_state_change_forbidden : public etl::fsm_exception
//***************************************************************************
/// Exception for forbidden state chages.
//***************************************************************************
class fsm_state_composite_state_change_forbidden : public etl::fsm_exception
{
public:
fsm_state_enter_state_change_forbidden(string_type file_name_, numeric_type line_number_)
: etl::fsm_exception(ETL_ERROR_TEXT("fsm:enter state change in composite state forbidden", ETL_FSM_FILE_ID"E"), file_name_, line_number_)
fsm_state_composite_state_change_forbidden(string_type file_name_, numeric_type line_number_)
: etl::fsm_exception(ETL_ERROR_TEXT("fsm:change in composite state forbidden", ETL_FSM_FILE_ID"E"), file_name_, line_number_)
{
}
};
@ -182,16 +185,16 @@ namespace etl
// Pass this whenever no state change is desired. Specifically cast to
// Highest unsigned value of fsm_state_id_t.
static const fsm_state_id_t NO_CHANGE = static_cast<fsm_state_id_t>(-1);
static const fsm_state_id_t No_State_Change = static_cast<fsm_state_id_t>(-1);
/// Allows ifsm_state functions to be private.
friend class etl::fsm;
friend class etl::hfsm;
template <typename, typename, const etl::fsm_state_id_t,
typename, typename, typename, typename,
typename, typename, typename, typename,
typename, typename, typename, typename,
typename, typename, typename, typename >
typename, typename, typename, typename,
typename, typename, typename, typename,
typename, typename, typename, typename,
typename, typename, typename, typename >
friend class etl::fsm_state;
//*******************************************
@ -205,21 +208,56 @@ namespace etl
//*******************************************
/// Adds a child to this state.
//*******************************************
void add_child(etl::ifsm_state& state)
void add_child_state(etl::ifsm_state& state)
{
ETL_ASSERT(state.p_parent == ETL_NULLPTR, ETL_ERROR(etl::fsm_null_state_exception));
state.p_parent = this;
if (p_default_child == ETL_NULLPTR)
{
p_active_child = &state;
p_default_child = &state;
}
}
//*******************************************
/// Adds the initial child to this state.
/// Adds a list of child states.
//*******************************************
void add_initial_child(etl::ifsm_state& state)
template <typename TSize>
void set_child_states(etl::ifsm_state** state_list, TSize size)
{
ETL_ASSERT(p_default_active_child == ETL_NULLPTR, ETL_ERROR(etl::fsm_null_state_exception));
add_child(state);
p_active_child = &state;
p_default_active_child = &state;
p_active_child = ETL_NULLPTR;
p_default_child = ETL_NULLPTR;
for (TSize i = 0; i < size; ++i)
{
ETL_ASSERT(state_list[i] != ETL_NULLPTR, ETL_ERROR(etl::fsm_null_state_exception));
add_child_state(*state_list[i]);
}
}
//*******************************************
/// Get the parent state for this state.
//*******************************************
etl::ifsm_state* get_parent_state() const
{
return p_parent;
}
//*******************************************
/// Get the active child state for this state.
//*******************************************
etl::ifsm_state* get_active_child_state() const
{
return p_active_child;
}
//*******************************************
/// Get the default child state for this state.
//*******************************************
etl::ifsm_state* get_default_child_state() const
{
return p_default_child;
}
protected:
@ -232,7 +270,7 @@ namespace etl
p_context(ETL_NULLPTR),
p_parent(ETL_NULLPTR),
p_active_child(ETL_NULLPTR),
p_default_active_child(ETL_NULLPTR)
p_default_child(ETL_NULLPTR)
{
}
@ -253,7 +291,7 @@ namespace etl
virtual fsm_state_id_t process_event(const etl::imessage& message) = 0;
virtual fsm_state_id_t on_enter_state() { return NO_CHANGE; } // By default, do nothing.
virtual fsm_state_id_t on_enter_state() { return No_State_Change; } // By default, do nothing.
virtual void on_exit_state() {} // By default, do nothing.
//*******************************************
@ -275,7 +313,7 @@ namespace etl
ifsm_state* p_active_child;
// A pointer to the default active child.
ifsm_state* p_default_active_child;
ifsm_state* p_default_child;
// Disabled.
ifsm_state(const ifsm_state&);
@ -313,7 +351,7 @@ namespace etl
number_of_states = etl::fsm_state_id_t(size);
ETL_ASSERT(number_of_states > 0, ETL_ERROR(etl::fsm_state_list_exception));
ETL_ASSERT(number_of_states < ifsm_state::NO_CHANGE, ETL_ERROR(etl::fsm_state_list_exception));
ETL_ASSERT(number_of_states < ifsm_state::No_State_Change, ETL_ERROR(etl::fsm_state_list_exception));
for (etl::fsm_state_id_t i = 0; i < size; ++i)
{
@ -346,7 +384,7 @@ namespace etl
{
p_last_state = p_state;
next_state_id = p_state->on_enter_state();
if (next_state_id != ifsm_state::NO_CHANGE)
if (next_state_id != ifsm_state::No_State_Change)
{
ETL_ASSERT(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception));
p_state = state_list[next_state_id];
@ -363,7 +401,7 @@ namespace etl
{
etl::fsm_state_id_t next_state_id = p_state->process_event(message);
if(next_state_id != ifsm_state::NO_CHANGE)
if(next_state_id != ifsm_state::No_State_Change)
{
ETL_ASSERT(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception));
etl::ifsm_state* p_next_state = state_list[next_state_id];
@ -377,7 +415,7 @@ namespace etl
p_state = p_next_state;
next_state_id = p_state->on_enter_state();
if(next_state_id != ifsm_state::NO_CHANGE)
if(next_state_id != ifsm_state::No_State_Change)
{
ETL_ASSERT(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception));
p_next_state = state_list[next_state_id];

View File

@ -36,6 +36,8 @@ namespace etl
//***************************************************************************
/// The HFSM class.
/// Builds on the FSM class by overriding the receive function and adding
/// state hierarchy walking functions.
//***************************************************************************
class hfsm : public etl::fsm
{
@ -58,7 +60,7 @@ namespace etl
{
etl::fsm_state_id_t next_state_id = p_state->process_event(message);
if (next_state_id != ifsm_state::NO_CHANGE)
if (next_state_id != ifsm_state::No_State_Change)
{
ETL_ASSERT(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception));
etl::ifsm_state* p_next_state = state_list[next_state_id];
@ -73,7 +75,7 @@ namespace etl
next_state_id = do_enters(p_root, p_next_state, true);
if (next_state_id != ifsm_state::NO_CHANGE)
if (next_state_id != ifsm_state::No_State_Change)
{
ETL_ASSERT(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception));
p_state = state_list[next_state_id];
@ -156,17 +158,17 @@ namespace etl
}
etl::fsm_state_id_t next_state = p_target->on_enter_state();
ETL_ASSERT(ifsm_state::NO_CHANGE == next_state, ETL_ERROR(etl::fsm_state_enter_state_change_forbidden));
ETL_ASSERT(ifsm_state::No_State_Change == next_state, ETL_ERROR(etl::fsm_state_composite_state_change_forbidden));
// Activate default child if we need to activate any initial states in an active composite state.
if (activate_default_children)
{
while (p_target->p_default_active_child != ETL_NULLPTR)
while (p_target->p_default_child != ETL_NULLPTR)
{
p_target = p_target->p_default_active_child;
p_target = p_target->p_default_child;
p_target->p_parent->p_active_child = p_target;
next_state = p_target->on_enter_state();
ETL_ASSERT(ifsm_state::NO_CHANGE == next_state, ETL_ERROR(etl::fsm_state_enter_state_change_forbidden));
ETL_ASSERT(ifsm_state::No_State_Change == next_state, ETL_ERROR(etl::fsm_state_composite_state_change_forbidden));
}
next_state = p_target->get_state_id();

View File

@ -224,7 +224,7 @@ namespace
etl::fsm_state_id_t on_event_unknown(const etl::imessage&)
{
++get_fsm_context().unknownCount;
return NO_CHANGE;
return No_State_Change;
}
//***********************************

View File

@ -260,14 +260,14 @@ namespace
etl::fsm_state_id_t on_event_unknown(const etl::imessage&)
{
++get_fsm_context().unknownCount;
return NO_CHANGE;
return No_State_Change;
}
//***********************************
etl::fsm_state_id_t on_enter_state()
{
get_fsm_context().TurnRunningLampOff();
return NO_CHANGE;
return No_State_Change;
}
};
@ -290,7 +290,7 @@ namespace
etl::fsm_state_id_t on_event_unknown(const etl::imessage&)
{
++get_fsm_context().unknownCount;
return NO_CHANGE;
return No_State_Change;
}
//***********************************
@ -298,7 +298,7 @@ namespace
{
get_fsm_context().TurnRunningLampOn();
return NO_CHANGE;
return No_State_Change;
}
};
@ -327,13 +327,13 @@ namespace
etl::fsm_state_id_t on_event_unknown(const etl::imessage&)
{
++get_fsm_context().unknownCount;
return NO_CHANGE;
return No_State_Change;
}
etl::fsm_state_id_t on_enter_state()
{
++get_fsm_context().windUpStartCount;
return NO_CHANGE;
return No_State_Change;
}
};
@ -355,14 +355,14 @@ namespace
{
++get_fsm_context().setSpeedCount;
get_fsm_context().SetSpeedValue(event.speed);
return NO_CHANGE;
return No_State_Change;
}
//***********************************
etl::fsm_state_id_t on_event_unknown(const etl::imessage&)
{
++get_fsm_context().unknownCount;
return NO_CHANGE;
return No_State_Change;
}
};
@ -384,7 +384,7 @@ namespace
etl::fsm_state_id_t on_event_unknown(const etl::imessage&)
{
++get_fsm_context().unknownCount;
return NO_CHANGE;
return No_State_Change;
}
};
@ -400,6 +400,11 @@ namespace
&idle, &running, &windingUp, &windingDown, &atSpeed
};
etl::ifsm_state* childStates[] =
{
&windingUp, &atSpeed, &windingDown
};
MotorControl motorControl;
SUITE(test_hfsm_states)
@ -412,9 +417,7 @@ namespace
CHECK(motorControl.is_producer());
CHECK(motorControl.is_consumer());
running.add_initial_child(windingUp);
running.add_child(atSpeed);
running.add_child(windingDown);
running.set_child_states(childStates, etl::size(childStates));
motorControl.Initialise(stateList, etl::size(stateList));
motorControl.reset();