Boost logo

Boost :

Subject: [boost] [MSM] Additional template arguments for process_event
From: Juan Carlos Franzoy (jfranzoy_at_[hidden])
Date: 2014-01-02 21:52:38


The short question is:

  Would it be possible/convenient that
boost::msm::back::state_machine::process_event
  receive more template parameters?

  template< class Event, typename... ARGS >
  process_event( const Event& event, ARGS&&... args );

  args been forwarded to transition actions?

I've been searching in boost.development mailing list archives and didn't
see this
question before.

The need of additional template parameters is based on the fact that ARGS
may not be
defined at the moment of the state_machine isntantiation.

Note: I would love to notice that I am wrong, and all this is an unnecessary
      complication, please let me know if that is the case.

Thanks for reading.

The long story follows:

I am trying to use MSM for the first time.

I am evaluating the factibility and convenience of a library to try to
make easier the construction of protocol stacks over Boost.Asio. Protocol
stack layers are often Finite State Machines.

The idea is that the user of the library would program reusable 'layers'
and use a library facility called LayerLinker to links the layers.

For example this is a simplified pseudocode:

template< typename STACK, int POSITION >
class LayerLinker {
   typedef ... layer_t;
   typedef LayerLinker<STACK,POSITION+1> upper_linker_t;
   typedef LayerLinker<STACK,POSITION-1> lower_linker_t;
   layer_t layer_;
   upper_linker_t *up_;
   lower_linker_t *low_;
public:
   LayerLinker( boost::asio::io_service& ios ) : layer_{ios} {}
   template<class EVENT>
   void processUpstreamEvent( const EVENT& ev ) {
      layer_.processUpstreamEvent( *this /* let the layer know my type */,
ev );
   }
   // similar for processDownstreamEvent()

   // Called by layer_ to send an event to the upper layer
   template<class EVENT>
   void sendUpstreamEvent( const EVENT& ev ) {
      if ( up_ ) {
         up_->processUpstreamEvent( ev );
      }
   }
   // similar for sendDownstreamEvent()
};

struct MyTopLayer {
   typedef ... my_fsm_t;
   my_fsm_t myFsm_;
public:
   template<class LINKER, class EVENT>
   void processUpstreamEvent( LINKER& linker, const EVENT& ev ) {
      // in transition actions the FSM can send events to upper layers.
      myFsm.process_event( ev, linker /* additional parameter here */ );
   }
   // similar to processDownstreamEvent
};
// similar for MyMiddleLayer and MyBottomLayer

int main() {
   typedef boost::mpl::vector<MyTopLayer,MyMiddleLayer,MyBottomLayer>
stack_t;
   boost::asio::io_service ios;
   LayerLinker<stack_t, 0> topLinker{ios};
   LayerLinker<stack_t, 1> middleLinker{ios};
   LayerLinker<stack_t, 2> bottomLinker{ios};
   topLinker.setLowerLinker( middleLinker );
   middleLinker.setUpperLinker( topLinker );
   middleLinker.setLowerLinker( bottomLinker );
   bottomLinker.setUpperLinker( middleLinker );
   topLinker.processDownstreamEvent( InitEvent{} );
   ios.run();
}

// from asio callbacks
borromLinker.processUpstreamEvent( ReadEvent{...} );

Although I could make it without extra parameters to process_event, it is
basically
a workaround.

THANKS A LOT for reading 95 lines.

Juan Carlos Franzoy


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