mirror of
https://github.com/ETLCPP/etl.git
synced 2026-06-29 22:08:45 +08:00
Merge remote-tracking branch 'origin/feature/light_weight_fsm' into development
This commit is contained in:
commit
5522f2aa4e
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
//*************************************************************************
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user