
Hi Simon Thanks for your review!
I think that custom_reactions that act like guards should be discouraged, as they effectively hide part of the state chart in the implementation.
That is true if you define the react function outside the state subtype. However, it is often possible to define it right inside the state subtype body where it can be seen by anyone browsing the states.
When I read a particular fsm, I want to be able to clearly see all possible transitions and actions without having to search through any decision logic code to fill in the gaps.
Given that you implement the react function inline, I think that custom_reactions are easier to understand than any special guard reaction.
We should be able to specify guards as part of the state definition. Something like this:
struct StState: fsm::simple_state<StState,StOuter, mpl::list < fsm::guard2<EvEvent, fsm::switch<StRes0,StRes0ActCtxt,&StRes0ActCtxt::Action0>, fsm::switch<StRes1,StRes1ActCtxt,&StRes1ActCtxt::Action1>
;
I guess this might make the cpp code look like this:
fsm::guard2::result StState::guard2(const EvEvent& ev) { if(cond) return fsm::guard2::result<0>(); else return fsm::guard2::result<1>(); }
The equivalent with a custom reaction would look as follows: struct StState : fsm::simple_state< StState, StOuter, fsm::custom_reaction< EvEvent > > { fsm::result react( const EvEvent & evt ) { if ( cond ) return transit< StRes0 >( &StRes0ActCtxt::Action0, evt ); else return transit< StRes1 >( &StRes1ActCtxt::Action1, evt ); } }; For a human, IMHO this is easier to read.
I haven't thought about the implementation too much admittedly. Having this would be a big help in automatically generating UML state charts.
Agreed. It is much easier to implement a tool that only needs to look at the state declarations than one that additionally also needs to analyze code inside functions. For this reason I think I will eventually add a construct similar to the one you suggested. But, since such a tool does not yet exist (to my knowledge), this is of fairly low priority at the moment.
* Are there performance bottlenecks? Does the library design fit requirements of real-time systems? How is it useable for embedded systems? Is the documentation clear on performance tradeoffs?
The library produces large binaries.
The produced binaries certainly will never be small. Out of curiosity, do you have any numbers (number of states -> size of executable)?
It does however, appear to scale reasonably well (anecdotally, it seems about linear with the number of states). The in memory footprint is of the same order of magnitude as the binary size.
I guess that is for the hundreds of machine objects you mention below? A single machine object of even a very complex FSM should not use more than 1KB (not counting state-local variables).
My application is fairly soft real time, and runs on an embedded 486-like system, with a few hundred individual state machines and a few hundred events delivered per second. In this case, the performance of boost::fsm is acceptable, and does not threaten any timing constraints of the system.
Thanks again & Best Regards, -- Andreas Huber When replying by private email, please remove the words spam and trap from the address shown in the header.