'Boost MSM call .process_event on outerSM's orthogonal region from submachine
I implemented the depicted state machine as a minimum example in boost::msm. The Code may be reviewed here: https://wandbox.org/permlink/tIhZao8YGhJvPMfF
As shown in the code below I want to call event2 from "someAction", which works fine when someAction is called on event4 from the top level state machine "MainMachine". However when called on event3 from inside the Submachine, only the no transition response of the submachine is triggered (or a runtime assertion fails if no no transition response is provided in the submachine). I would have expected event2 to be refered to the top level state-machine's transition table, however this does not seem to work because someAction only gets a reference to the SubMachine FSM.
What would be the best way to trigger events in an orthogonal region of the top level statemachine inside actions called from a Submachine?
struct someAction
{
template<class EVT, class FSM, class SourceState, class TargetState>
void operator()(EVT const& evt,
FSM& fsm,
SourceState& src,
TargetState& tgt) const
{
fsm.process_event(event2());
std::cout << "Called from: " << typeid(fsm).name() << " / " << &fsm << std::endl;
}
};
#include "fsm.h"
#include <iostream>
int
main()
{
MainMachine p;
std::cout << "--> Start STM" << std::endl;
p.start();
std::cout << "--> Event 1" << std::endl;
p.process_event(event1());
std::cout << "--> Event 3" << std::endl;
p.process_event(event3());
std::cout << "--> Event 4" << std::endl;
p.process_event(event4());
std::cout << "--> Stop STM" << std::endl;
p.stop();
return 0;
}
Output:
Start
--> Start STM
entering: MainMachine
entering: State1
entering: State3
--> Event 1
leaving: State1
entering: SubMachine
entering: SubState1
--> Event 3
leaving: SubState1
Called from: N5boost3msm4back13state_machineIN12MainMachine_11SubMachine1ENS_9parameter5void_ES6_S6_S6_EE / 0x7ffd823f1138
entering: SubState2
no transition from state 1 on event 6event2
--> Event 4
leaving: SubState2
leaving: SubMachine
Called from: N5boost3msm4back13state_machineI12MainMachine_NS_9parameter5void_ES5_S5_S5_EE / 0x7ffd823f10e0
entering: State1
leaving: State3
entering: State4
--> Stop STM
leaving: State1
leaving: State4
leaving: MainMachine
0
Finish
Solution 1:[1]
When someAction()
is called by event3, the fsm
parameter inside it refers to the "SubMachine", not the "MainMachine". Therefore only "SubMachine" receives the event3, but not the "MainMachine".
Unfortunately I don't have a good solution for how to get the "MainMachine" when someAction()
is called inside the "SubMachine". My cumbersome solution is to define a parent class that all the statemachine inherit from, which contains a static pointer to the main state machine.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | auzn |