|
Boost Users : |
Subject: Re: [Boost-users] Boost MSM - Ways to send info out from state machine to outside world
From: Christophe Henry (christophe.j.henry_at_[hidden])
Date: 2011-09-08 15:48:24
> Hi,
>
> I wanted to know what are different ways to send info from state machine
> to
> outside world. I am planning to use MSM in my project to represent
> connection between local computer and remote computer. This connection
> will
> be used as a channel to send data over to remote device. There can be >1
> channels existing between local computer and the remote device. There will
> be a controller sitting at local computer monitoring all these channels.
> The
> data will be sent over connection that is idle/free at that point of time.
> Whenever the connection, i.e. FSM, is done sending the data, it will let
> the
> controller (which resides outside of the FSM) know that it is done sending
> the data and the controller will then send next lot of data over that
> connection. There can be 2 ways of achieving this: 1. Controller polling
> all
> the connections and knowing what "state" the FSM is in.(In this case, the
> outer world will need to know the current state of the state machine) 2.
> The
> FSM will proactively let the controller know that it is done with sending
> data. (In this case the FSM will have to send data to outside world). I
> would like to know about ways to implement both the cases (i.e knowing
> status/current state of the FSM and sending info from FSM). I would also
> like to know what are different ways to interact with (both to and from)
> FSM
> in general, apart from sending events.
>
> Thanks!
Hi,
I personally use mostly 2. but 1. is useful if you need to do something at
some regular interval.
To 1:
- current_state / get_state_by_id will get you a base class of all states if
you define one.
- better is to use flags
(http://svn.boost.org/svn/boost/trunk/libs/msm/doc/HTML/ch03s02.html#d0e1032)
to know if your fsm fulfills some property (is in one or more states which
define these flags). It's a bit like knowing in which state you are but more
general. This one is my favorite.
- you can use a visitor
(http://svn.boost.org/svn/boost/trunk/libs/msm/doc/HTML/ch03s05.html#d0e2333)
to let the current state "do" something.
To 2:
This shouts for a transition action
(http://svn.boost.org/svn/boost/trunk/libs/msm/doc/HTML/ch03s03.html#d0e1260).
An action is a functor or a function which is called when a transition
fires.
There is no rule written in marble, but I suggest you stick to 2. until you
cannot do otherwise, it will make your fsm much more useful and readable.
Plus, it mixes very well with boost.asio (I do it quite a bit myself). Every
callback from asio generates some event, to which the fsm reacts by changing
state and calling another action, which triggers another asio task, etc.
For example, a HTTP client
(http://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/example/http/client/async_client.cpp):
- fsm starts
- when asked, fsm calls async_resolve
- handle_resolve generates an event which triggers a transition
- the transition action calls async_connect
- handle_connect generates an event which triggers a transition
- the transition action sends data by calling async_write
etc. etc. Add some events and actions for error handling and you get a
pretty complete communication handling in a fsm.
To your last question, interact with a fsm, well, it's a class so you can
add whatever methods or attributes you might need.
HTH,
Christophe
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net