Merge remote-tracking branch 'origin/feature/light_weight_fsm' into development

This commit is contained in:
John Wellbelove 2018-09-11 23:01:20 +01:00
commit 5522f2aa4e
2 changed files with 70 additions and 35 deletions

View File

@ -223,48 +223,61 @@ namespace etl
{
if (started)
{
// Scan the transition table.
const transition* t = std::find_if(transition_table.begin(),
transition_table.end(),
is_transition(event_id, current_state_id));
const transition* t = transition_table.begin();
// Found an entry?
if (t != transition_table.end())
// Keep looping until we execute a transition or reach the end of the table.
while (t != transition_table.end())
{
// Shall we execute the transition?
if ((t->guard == nullptr) || ((object.*t->guard)()))
// Scan the transition table from the latest position.
t = std::find_if(t,
transition_table.end(),
is_transition(event_id, current_state_id));
// Found an entry?
if (t != transition_table.end())
{
// Shall we execute the action?
if (t->action != nullptr)
// Shall we execute the transition?
if ((t->guard == nullptr) || ((object.*t->guard)()))
{
(object.*t->action)();
}
// Changing state?
if (current_state_id != t->next_state_id)
{
const state* s;
// See if we have a state item for the current state.
s = find_state(current_state_id);
// If the current state has an 'on_exit' then call it.
if ((s != state_table.end()) && (s->on_exit != nullptr))
// Shall we execute the action?
if (t->action != nullptr)
{
(object.*(s->on_exit))();
(object.*t->action)();
}
// See if we have a state item for the next state.
s = find_state(t->next_state_id);
// If the new state has an 'on_entry' then call it.
if ((s != state_table.end()) && (s->on_entry != nullptr))
// Changing state?
if (current_state_id != t->next_state_id)
{
(object.*(s->on_entry))();
}
}
const state* s;
current_state_id = t->next_state_id;
// See if we have a state item for the current state.
s = find_state(current_state_id);
// If the current state has an 'on_exit' then call it.
if ((s != state_table.end()) && (s->on_exit != nullptr))
{
(object.*(s->on_exit))();
}
// See if we have a state item for the next state.
s = find_state(t->next_state_id);
// If the new state has an 'on_entry' then call it.
if ((s != state_table.end()) && (s->on_entry != nullptr))
{
(object.*(s->on_entry))();
}
current_state_id = t->next_state_id;
}
t = transition_table.end();
}
else
{
// Start the search from the next item in the table.
++t;
}
}
}
}

View File

@ -103,6 +103,7 @@ namespace
speed = 0;
windingDown = 0;
entered_idle = false;
null = 0;
}
//***********************************
@ -167,6 +168,12 @@ namespace
return guard;
}
//***********************************
bool NotGuard()
{
return !guard;
}
//***********************************
void TurnRunningLampOn()
{
@ -179,6 +186,12 @@ namespace
isLampOn = false;
}
//***********************************
void Null()
{
++null;
}
int startCount;
int stopCount;
int setSpeedCount;
@ -187,17 +200,19 @@ namespace
int speed;
int windingDown;
bool entered_idle;
int null;
bool guard;
static const etl::array<MotorControl::transition, 5> transitionTable;
static const etl::array<MotorControl::transition, 6> transitionTable;
static const etl::array<MotorControl::state, 3> stateTable;
};
//***************************************************************************
const etl::array<MotorControl::transition, 5> MotorControl::transitionTable =
const etl::array<MotorControl::transition, 6> MotorControl::transitionTable =
{
MotorControl::transition(EventId::START, StateId::IDLE, StateId::RUNNING, &MotorControl::OnStart, &MotorControl::Guard),
MotorControl::transition(EventId::START, StateId::IDLE, StateId::IDLE, &MotorControl::Null, &MotorControl::NotGuard),
MotorControl::transition(EventId::STOP, StateId::RUNNING, StateId::WINDING_DOWN, &MotorControl::OnStop),
MotorControl::transition(EventId::STOPPED, StateId::WINDING_DOWN, StateId::IDLE, &MotorControl::OnStopped),
MotorControl::transition(EventId::EMERGENCY_STOP, StateId::RUNNING, StateId::IDLE, &MotorControl::OnStop),
@ -283,6 +298,7 @@ namespace
CHECK_EQUAL(0, motorControl.stopCount);
CHECK_EQUAL(0, motorControl.stoppedCount);
CHECK_EQUAL(0, motorControl.windingDown);
CHECK_EQUAL(1, motorControl.null);
// Send Start event.
motorControl.guard = true;
@ -299,6 +315,7 @@ namespace
CHECK_EQUAL(0, motorControl.stopCount);
CHECK_EQUAL(0, motorControl.stoppedCount);
CHECK_EQUAL(0, motorControl.windingDown);
CHECK_EQUAL(1, motorControl.null);
// Send unhandled events.
motorControl.process_event(EventId::START);
@ -313,6 +330,7 @@ namespace
CHECK_EQUAL(0, motorControl.stopCount);
CHECK_EQUAL(0, motorControl.stoppedCount);
CHECK_EQUAL(0, motorControl.windingDown);
CHECK_EQUAL(1, motorControl.null);
// Send SetSpeed event.
motorControl.process_event(EventId::SET_SPEED);
@ -328,6 +346,7 @@ namespace
CHECK_EQUAL(0, motorControl.stopCount);
CHECK_EQUAL(0, motorControl.stoppedCount);
CHECK_EQUAL(0, motorControl.windingDown);
CHECK_EQUAL(1, motorControl.null);
// Send Stop event.
motorControl.process_event(EventId::STOP);
@ -343,6 +362,7 @@ namespace
CHECK_EQUAL(1, motorControl.stopCount);
CHECK_EQUAL(0, motorControl.stoppedCount);
CHECK_EQUAL(1, motorControl.windingDown);
CHECK_EQUAL(1, motorControl.null);
// Send unhandled events.
motorControl.process_event(EventId::START);
@ -357,6 +377,7 @@ namespace
CHECK_EQUAL(1, motorControl.stopCount);
CHECK_EQUAL(0, motorControl.stoppedCount);
CHECK_EQUAL(1, motorControl.windingDown);
CHECK_EQUAL(1, motorControl.null);
// Send Stopped event.
motorControl.process_event(EventId::STOPPED);
@ -371,6 +392,7 @@ namespace
CHECK_EQUAL(1, motorControl.stopCount);
CHECK_EQUAL(1, motorControl.stoppedCount);
CHECK_EQUAL(0, motorControl.windingDown);
CHECK_EQUAL(1, motorControl.null);
}
//*************************************************************************