
Hi Christophe!
...yes, you told me that the submachines have no direct access to its parent state machine. Sorry for the confusion...
No problem. I just want to make sure others will not misunderstand.
The reason why we are using a "global" event queue (each submachine has access to it) is because we don't think that it is not a good design to call process_event from within a submachine: doing so, we will lose the advantages of a hierachical statemachine design.
I admit I am not completely decided on this. Ususally I prefer to give the submachine from outside a boost::function or something equivalent or I exit the submachine with a pseudo exit, even if I have to re-enter it. This preserves my encapsulation and avoids a global queue, but I admit it is more work. In any case, I need to provide a better solution. I had no luck so far but I don't despair ;-)
Further, how you will stop a submachine in case it calls permantely its process_event method: doing so would cut the possibility to stop the complete statemachine from the outside world!
I'm not sure I understand this. Permanently would mean stack overflow, in any case, outside or not it is dead ;-)
Our approach is to start an event collector, which is gathering events from different sources and puts it afterwards into the "global" event queue. In the next step an event dispatcher pops the events from our "global" queue of type std::queue <boost::variant <eventtype1, eventtype2, ..., eventtype44>> and forwards it to to the process_event method of the hierarchical Master or Slave state machines, which perform the appropriate transistions and actions. Note: within one state an event can be put to the "global" event queue, but it is in our opinion a bad design to call the process_event method of the current sub machine. We used the book" Practical UML Statecharts in C/C++: Event-Driven Programming for Embedded Systems - Miro Samek" as basis for such kind of design( not calling process_event event from within submachines).
I would very appreciate your opinion regarding my comment above.
I don't see why it would be bad design to call process_event on either the outer or the submachine. But I didn't read this book. As long as the library makes sure that an event is completed before the next one starts (which msm does), I see no problem. Furthermore, if calling process_event on the submachine is enough for some events, you have 1) a more localized code (good) and 2) a better performance (you avoid processing the event from the outer to the submachine, so one process_event less). But really, if you like the global queue, I don't want to talk you out of it ;-) There is no such thing as the Unique Perfect Solution and I surely don't have it.
Regarding the " out of memory problem": Today I've splitted my library into two parts: one slave and one master shared library. So the slave state machine does only now 20 events and the master knows 24 events. We have now a better compilation performance, but the memory allocation is still big for master state machine: at the highest almost 900Mb memory is being allocated while the compilation on windows. In comparison to the approach with a slave and master state machine in one shared library we saved almost 400Mb memory allocation while compile time. This all is already compiled without debug information and it is still a massive memory consumption.
Sorry, I know too little about compilers to provide an answer, sounds strange that it makes a difference. OTOH 900Mb is not unreasonable for heavily templatized code.
Tomorrow I will have a look if I can reduce the number of events or maybe even the number of submachines...
Question: does the use of guards and actions in a transition table also produce compilation time (template invocations) in boost.msm like with events? Please say no,
No :) Seriously, no, I never found a measurable impact.
cause I still have to define actions and some guards into the state machines. If yes, so we have ultimatively to decide if it would be better to switch to another state machine library (state chart, etc.). Actually, I don't want this:)
Me neither ;-) But clearly, statechart would compile faster, yes. Or you can give a try to favor_compile_time. With so many submachines, it could help much.
Br,
Rafael
HTH, Christophe