
Hi Juraj, First of all, thank you for being the first one to write a review. I imagine it's not an easy thing. Thank you also for bringing a few very interesting points to the discussion. I'm happy to build on them and hope to finally start some discussion.
MSM does lack some of the SC functionality. There is no state-local storage in SC sense, as all states are constructed when main state machine is constructed. This can be easily worked around though.
As this point is being brought for the second time, I'd like to spend some time on it. You already have state local storage with msm, just not like with SC. Like SC, msm defines states as classes, meaning they can have data. There is however one important difference with SC. Msm builds all the states upon state machine creation. States are not destroyed until state machine destruction. This has advantages and disadvantages: - states must be default-constructible - you might need to heap allocate the state data if you cannot initialize it at state construction. + speed: states don't need to be constructed again and again. Constructing a state (and its attributes) each time it becomes active can be costly, even if memory allocation can be optimized. + your state data is always available. In my experience, state data is not only needed in the entry or when the next event is processed, but during a transition or even at some time after a transition. This means, that you have, during a transition, access to data from the source or the target state. + combined with the visitor, you can at any time access data from the currently active state and build a generic way to do something with state data. + you can build examples like the iPodSearch where states keep iterators to some container, thus keeping information from an iteration to the next one. + you avoid having data released inside a destructor. Knowing that destructors should not throw, it makes your life easier. + on_entry is templatized, giving you more leeway to add event-specific handling. + your event data is not lost upon state entry Msm's handling is hard to emulate with SC, on the other hand, SC's handling is easy to emulate with Msm. It has its drawbacks but all considered, I think it is a superior solution.
It is impossible to stop event from propagation (SCs discard_event()) without actually changing state.
It is true. At the moment you cannot. Actually, I don't think UML foresees this possibility. OTOH, I think it is an interesting one and will be happy to borrow it from SC. I think that using the transition table is one of Msm's biggest strengths so I offer to add a row or a functor allowing event propagation to be stopped. You could even give it a guard, thus allowing fine-grained transition conflict resolution.
You cannot conditionally defer an event.
Again you're right. I think UML doesn't foresee this either, but I also like it and will also borrow it from SC. You offered the idea of a d_row (deferred row) or dg_row (the same with a guard). I think it is the best possibility with the simplest front-end and makes deferred events a first-class citizen, being in the transition table and coming into play during conflict resolution. For the functor and eUML front-ends I think it could be done as an execution row. Something like: State1() + Event1() / defer_() Seems an interesting starting point.
There seem to be some differences on how event deferral is handled when composite states are used. This part is a still bit mysterious to me.
I will add a part about the dispatch algorithm to the documentation.
Aesthetically - I'm not a great fan of one big fat html documentation and would prefer to have it broken down and cross-referenced as most boost libraries docs are organized, but this is just a minor issue.
If Msm is accepted into Boost, I'd probably move to BoostBook anyway, so this will be done at this time.
The author seems masochistic enough to try to tackle this. :)
Sure :) and I don't mind the term at all :) Thanks for the review and the very good points you brought during the last weeks! Regards, Christophe

Christophe Henry wrote:
You already have state local storage with msm, just not like with SC. Like SC, msm defines states as classes, meaning they can have data. There is however one important difference with SC. Msm builds all the states upon state machine creation. States are not destroyed until state machine destruction. This has advantages and disadvantages: - states must be default-constructible
I know nothing about MSM and very little about state machines in general, but if all states are constructed at SM instantiation time, would it be possible to pass the SM constructor a tuple of constructed states that are copied/moved into the internal states? Would it be worth the effort? Sebastian

Hi Cristophe [Advantages/disadvantages of state local storage...]
+ speed: states don't need to be constructed again and again. Constructing a state (and its attributes) each time it becomes active can be costly, even if memory allocation can be optimized.
I agree that the feature can be costly. I don't have a lot of experience with fsms with very tight time constraints though - SC seems to meet our time requirements (ie the state machine itself is much faster than the other operations we perform).
+ your state data is always available. In my experience, state data is not only needed in the entry or when the next event is processed, but during a transition or even at some time after a transition. This means, that you have, during a transition, access to data from the source or the target state.
This is simple to emulate in SC. The state data can be owned by the outer state, or by the state_machine itself. The advantage of true state local storage is that it encourages the use of meaningful destructors. As a (real life) example, a common strategy in our use of (asynchronous) SC is to instantiate a timer in the constructor of the state (which may be an inner state of another state which has its own timer). Since exiting the state destructs the timer, we don't have to explicitly cancel it (in the exit action for example). It's just one less thing we risk forgetting to do.
+ combined with the visitor, you can at any time access data from the currently active state and build a generic way to do something with state data.
Granted. Personally though, I prefer to keep my fsm opaque, and force the use of events and actions to update and monitor the fsm respectively. Any other method (in our application) is a violation of the desired encapsulation. Of course, this probably just means that I haven't come across such a requirement in my use of fsms, so I won't hold the visitor against you :)
+ you can build examples like the iPodSearch where states keep iterators to some container, thus keeping information from an iteration to the next one.
Again, the iterator can be held by an outer state, or by the state_machine itself in SC.
+ you avoid having data released inside a destructor. Knowing that destructors should not throw, it makes your life easier.
If releasing data in destructors (or in exit actions) is considered harmful, one can simply not use state local storage (make all state data owned by the state_machine).
+ on_entry is templatized, giving you more leeway to add event-specific handling. + your event data is not lost upon state entry
True, I believe that these features could be useful. IMO the lack of state local storage is actually a relatively minor issue. The big ticket issue for me is its ability (or rather, the compiler's ability) to create large state machines. With SC, I might create a 50 transition state machine. Over time, normal maintenance might add another 10 or 20 transitions. This isn't a big deal. However, I'd be less likely to start developing such a state machine with msm for fear that any additional transitions might push the compiler 'over the edge'. So for medium to large state machines, I would choose SC. For very small state machines, I might be tempted to choose a C style hand written state machine to avoid the learning overhead for such a trivial application (though Euml is cool enough that I might overcome that). Cheers Simon --------------------------------------------------------------------- CONFIDENTIALITY NOTE: Please consider our environment before printing this email.This email and any attachments are confidential and may be subject to copyright, legal or some other professional privilege. They are intended solely for the attention and use of the named addressee(s). They may only be copied, distributed or disclosed with the consent of the copyright owner. If you have received this email by mistake or by breach of the confidentiality clause, please notify the sender immediately by return email and delete or destroy all copies of the email. Any confidentiality, privilege or copyright is not waived or lost because this email has been sent to you by mistake. ---------------------------------------------------------------------
participants (3)
-
Christophe Henry
-
Sebastian Redl
-
Simon Gittins