Hi Andreas,
Andreas Huber
For various reasons I do not want to use the asynchroneous_state_machine - mostly because my application is built around a global event/message handler and I do not want to use multiple threads with their necessary synchronization.
As Igor has already pointed out, you don't have to use multiple threads. In fact, it's perfectly sensible to use multiple asynchronous_state_machine<> subclass objects hosted in one fifo_scheduler in a program that only has exactly one thread. Moreover, even under circumstances where you have very limited control over a global message queue and its handlers, you should still be able to use fifo_scheduler, as you can instruct it to simply return from its operator() as soon as its internal queue runs empty. So, in your scenario, if you can ensure that fifo_scheduler::operator() is called periodically, you *can* use async machines.
That's good to know - I did not realize that. From the tutorial and the reference I had the impression that a separate thread would be needed for every other state machine, and I also wanted to go the easy way first ;-) I'll give it a try; according to the reference all functionality I need seem to be available.
It basically works because in my hierarchy state_machine<>::process_event() is called only in one direction, while in the "opposite" direction (or if unsure) state_machine<>::post_event() is being used. E.g. A calls B->process_event(), B calls C->process_event(), but C calls B->post_event() and B calls A->post_event().
state_machine<>::post_event() is not intended to be called from code "outside" of the machine, but only transition actions, which is why post_event is documented as being protected. Unfortunately, it is public in the code because it has to be called from other class templates and template friend support was very spotty at the time this was implemented. Anyway, I certainly could have done more to prevent calls from outside (e.g. with an assert and/or better documentation). May I ask you to enter a ticket for this? Sure, the ticket is opened. Now that I read this I see that this function is indeed declared protected in the reference, but not in the source.
Regarding my other questions about the synchroneous state machine: is it really intended that a new event is processed before other events already queued? Of course this might be related to the post_event() issue above - if events cannot be queued up from outside without being processed immediately, the queue cannot contain any pending events. Right? Regards, Arne