Skip to content

Commit

Permalink
Correct more entry/exit special cases
Browse files Browse the repository at this point in the history
  • Loading branch information
dziegel committed Sep 9, 2024
1 parent 7fa93c2 commit 62114f8
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 18 deletions.
52 changes: 34 additions & 18 deletions include/cpp_event_framework/Statemachine.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,7 @@ public:
{
assert(impl_ != nullptr); // Most probably you forgot to call Init()
current_state_ = &kInTransition;
initial_.clear();
EnterStatesFromDownTo(nullptr, initial);
}

Expand Down Expand Up @@ -713,33 +714,45 @@ private:
return state->initial_;
}

void ExitState(StatePtr state)
{
if (on_state_exit_ != nullptr)
{
on_state_exit_(*this, *state);
}

if (state->on_exit_ != nullptr)
{
(impl_->*state->on_exit_)();
}
}

void ExitStatesFromUpTo(StatePtr from, StatePtr top)
{
const auto* state = from;

while (state != top)
if (state == top)
{
ExitState(state);
}
else
{
// Save history state
if (state->parent_ != nullptr)
while (state != top)
{
if ((state->parent_->flags_ & EFlags::kHistory) != EFlags::kNone)
// Save history state
if (state->parent_ != nullptr)
{
SetInitialState(state->parent_, state);
if ((state->parent_->flags_ & EFlags::kHistory) != EFlags::kNone)
{
SetInitialState(state->parent_, state);
}
}
}

if (on_state_exit_ != nullptr)
{
on_state_exit_(*this, *state);
}

if (state->on_exit_ != nullptr)
{
(impl_->*state->on_exit_)();
}
ExitState(state);

state = state->parent_;
};
state = state->parent_;
};
}
}

void EnterState(StateRef state) const
Expand Down Expand Up @@ -769,7 +782,10 @@ private:

void EnterStatesFromDownTo(StatePtr top, StatePtr target)
{
EnterStatesFromDownToRecursive(top, target->parent_);
if (top != target)
{
EnterStatesFromDownToRecursive(top, target->parent_);
}

if (GetInitialState(target) != nullptr)
{
Expand Down
35 changes: 35 additions & 0 deletions test/Statemachine_unittest.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ class EvtTurnOff : public cpp_event_framework::NextSignal<EvtTurnOff, EvtTurnOn>
{
};

class EvtSelfTransition : public cpp_event_framework::NextSignal<EvtSelfTransition, EvtTurnOff>
{
};

class StatemachineImpl;
class Fsm : public cpp_event_framework::Statemachine<StatemachineImpl, const cpp_event_framework::Signal::SPtr&>
{
Expand Down Expand Up @@ -177,6 +181,16 @@ class StatemachineImpl
off_entry_called_ = false;
CheckAllFalse();

fsm_.React(EvtSelfTransition::MakeShared());
assert(fsm_.CurrentState() == &Fsm::kOff);
assert(off_entry_called_ == true);
off_entry_called_ = false;
assert(off_exit_called_ == true);
off_exit_called_ = false;
assert(on_recall_event_called_ == true);
on_recall_event_called_ = false;
CheckAllFalse();

fsm_.React(EvtTurnOn::MakeShared());
assert(off_exit_called_ == true);
assert(on_entry_called_ == true);
Expand Down Expand Up @@ -207,10 +221,18 @@ class StatemachineImpl
assert(fsm_.CurrentState() == &Fsm::kRedYellow);
CheckAllFalse();

fsm_.React(EvtSelfTransition::MakeShared());
assert(fsm_.CurrentState() == &Fsm::kRedYellow);
CheckAllFalse();

fsm_.React(EvtGoGreen::MakeShared());
assert(fsm_.CurrentState() == &Fsm::kGreen);
CheckAllFalse();

fsm_.React(EvtGoRed::MakeShared());
assert(fsm_.CurrentState() == &Fsm::kRed);
CheckAllFalse();

fsm_.React(EvtTurnOff::MakeShared());
assert(on_exit_called_ == true);
assert(off_entry_called_ == true);
Expand Down Expand Up @@ -267,6 +289,9 @@ Fsm::Transition Fsm::FsmOffHandler(ImplPtr /*impl*/, Event event)
case EvtGoYellow::kId: // fall through
case EvtGoRed::kId:
return DeferEvent();
case EvtSelfTransition::kId:
// Self transition, entry + exit must be called
return TransitionTo(kOff);
default:
return UnhandledEvent();
}
Expand All @@ -280,6 +305,8 @@ Fsm::Transition Fsm::FsmOnHandler(ImplPtr /*impl*/, Event event)
return TransitionTo(kOff);
case EvtTurnOn::kId:
return NoTransition();
case EvtGoRed::kId:
return TransitionTo(kRed);
default:
return UnhandledEvent();
}
Expand All @@ -293,6 +320,8 @@ Fsm::Transition Fsm::FsmGreenHandler(ImplPtr /*impl*/, Event event)
return TransitionTo(kYellow);
case EvtGoGreen::kId:
return NoTransition();
case EvtSelfTransition::kId:
return TransitionTo(kGreen);
default:
return UnhandledEvent();
}
Expand All @@ -308,6 +337,8 @@ Fsm::Transition Fsm::FsmYellowHandler(ImplPtr /*impl*/, Event event)
return TransitionTo(kRed, kYellowRedTransitionActions);
case EvtGoYellow::kId:
return NoTransition();
case EvtSelfTransition::kId:
return TransitionTo(kYellow);
default:
return UnhandledEvent();
}
Expand All @@ -321,6 +352,8 @@ Fsm::Transition Fsm::FsmRedHandler(ImplPtr /*impl*/, Event event)
return TransitionTo(kRedYellow);
case EvtGoRed::kId:
return NoTransition();
case EvtSelfTransition::kId:
return TransitionTo(kRed);
default:
return UnhandledEvent();
}
Expand All @@ -334,6 +367,8 @@ Fsm::Transition Fsm::FsmRedYellowHandler(ImplPtr /*impl*/, Event event)
return TransitionTo(kGreen, &Fsm::Impl::Walk);
case EvtGoYellow::kId:
return NoTransition();
case EvtSelfTransition::kId:
return TransitionTo(kRedYellow);
default:
return UnhandledEvent();
}
Expand Down

0 comments on commit 62114f8

Please sign in to comment.