Boost logo

Boost :

From: jdspalding_at_[hidden]
Date: 2005-03-04 22:58:26


   FSM Review - John Spalding - 2005/MAR/04
   
   Contents
   - Overall impression.
   - my use case.
   - review manager's questions.
   
   *******************************
   Overall Impression
   *******************************
   
   I have been completly impressed by the FSM library, and
   recommend that it be immediately accepted into the Boost Libraries.
   
   I had been looking for a system that implemented hierarchical
   state machines, and never before found anything satisfactory.
   The ideas behind the Harel state chart had always seemed to me
   to have a place in standard software development.
   Prior to using FSM, I had read through another
   effort on C++ state machine development
   "Practical State Charts in C++", by Miro Samek,
   CMP Books, 2002, and found its methods unsatisfactory.
   I was impressed by Samek's advocacy of the utility of
   hierarchical state machines in software design.
   
   I am now using FSM for a modest practical project at my work,
   involving about 10 events and 10 states. FSM will replace a
   home brew non-hierarchical state machine. I like the ability
   to model hierarchical states and I also like the way FSM allows
   state networks to be constructed and modified quickly.
   
   => improvements - new user documentation <=
   
   I would add to the documentation a small section on trouble
   shooting the compile. When I started out, the fact that state
   machine connectivity was specified in templates caused me a
   bit of head scratching. My typical new-user mistakes resulted in
   lots of error messages.
   I would explicitly address this area, describing how connectivity
   errors cause compile time errors, for common state machine
   hook up errors. For example, if I change the "context" for
   just one state from the correct value to an incorrect value,
   I get over 90 lines of output.
   
   I think if you explicitly described a simple strategy
   for tracking down these connectivity problems, it would help
   the new user.
   
   **********************************************
   Usability Evaluation - my modest use case.
   **********************************************
   
   A distinguishing characteristic of this FSM library
   is its use of C++ templates to specify event/state
   connectivity.
   - we specify which events are handled or ignored
   when we are in a specified state.
   - we specify the sub-state network for the state machine.
   
   These are two separate connection operations.
   Both are specified by the class declaration for the state.
   A typical class template I used follows, in the example code.
   - the event handing connectivity is specified by the 3-rd
   argument to the fsm::simple_state<> template, an mpl::list
   of events. Simpler forms exist for the case that an event
   does not require special processing, however this general
   case is not complex.
   
   - the sub-state network is handled by the first two arguments
   to the fsm::simple_state<> template. The second argument simply
   names the "outer state", or containing state of this state.
   
   The outermost states of the finite state machine also have to
   instead name the controlling class, derived from fsm::state_machine.
   
   - In addition, I have provided an IFsmState<> template that
   implements a "GetState()" function that can be called by the
   state machine.
   
   I have used FSM to implement a modest sized state machine with
   about 10 events and 10 states. This particular state machine
   implements the high level application state of a data taking
   machine control application.
   
   In this application there are about 4 varieties of data taking.
   Using a common outer state Acquisition, containing the data
   taking states, allows me to write once
   the common code that causes data taking to stop.
   
   This application also monitors a significant number of conditions
   that require the system to take action when an abnormal condition
   (or hazard) occurs. This led me to have two outermost states,
   Hazard and NoHazard. When an abnormal condition is signalled,
   the hierarchy allows me to write once the code that stops data
   taking, and causes the system to enter the Hazard state.
   
   Bottom line, I found hierarchical state modeling to be very
   useful. I also found that FSM had answers for all the problems
   I encountered reducing the hiersrchical state machine to working
   code, in this relatively small example. The only "advanced"
   functions of FSM I utilized were state_cast<> and context<>.
   
   
   struct StIdle
   : IFsmState<StIdle>,
     fsm::simple_state< StIdle,
                        StNoHazard,
                        mpl::list<
                                  fsm::custom_reaction< EvSortEnter>,
                                  fsm::custom_reaction< EvCalEnter>,
                                  fsm::custom_reaction< EvTestEnter>,
                                  fsm::custom_reaction< EvTemplGenEnter> > >
   {
      StIdle();
      ~StIdle();
   
      fsm::result react(const EvSortEnter &);
      fsm::result react(const EvCalEnter &);
      fsm::result react(const EvTestEnter &);
      fsm::result react(const EvTemplGenEnter &);
   };
   
   // Used for all states...
   struct IFsmStateQuerry
   {
      virtual const type_info & GetState() const = 0;
   };
   // Used for all states...
   template<typename T>
   struct IFsmState : public IFsmStateQuerry
   {
      const type_info & GetState() const
      {
              return typeid(T);
      }
   };
   
   class SystemFsm : public IFsmStateQuerry,
                      public fsm::state_machine< SystemFsm, StNoHazard >
   {
   public:
      SystemFsm() { }
      // ...
      
      // Get state information.
      const type_info & GetState() const
      {
      // state_cast produces object in active state.
      // GetState returns type_info for that state.
      return state_cast< const IFsmStateQuerry & >().GetState();
      }
   };
   *****************************
   Review manager's questions
   *****************************
   
   What is your evaluation of the documentation?
   
   - I proposed adding a new user section, to help
   with compile time problems caused by state machine
   connect errors.
   - I also think the central role of the "context" parameter
   in simple_state<>, when specifying how to connect up all
   the states, could be stressed more, esp. for new users.
   
   What is your evaluation of the design?
   - I did not review the design implementation.
   - The FSM API is novel, due to template use,
   but I grew to like it.
   
   Are there parts of the implementation that duplicate parts of BOOST?
   - no, the entire FSM is novel.
   
   I did not evaluate performance bottlenecks, nor real-time aspects
   of usage.
   
   I did try to use the library for a practical library,
   and had lots of fun. (see my use case section)
   
   How much work did you put into the evaluation.
   - I have spent several days reviewing FSM, and have tracked
   it since I read about it on the boost list in 2004.
   - I have spent 2-3 days on the modest practical project.
   
   Domain Knowledge...
   - I am an "interested" user, but not an expert.
   
   I strongly believe FSM should be accepted into Boost.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk