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!
--
View this message in context: http://boost.2283326.n4.nabble.com/Boost-MSM-Ways-to-send-info-out-from-state-machine-to-outside-world-tp3799703p3799703.html
Sent from the Boost - Users mailing list archive at Nabble.com.
_______________________________________________
Boost-users mailing list
Boost...@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users
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
I had one more question about the lifetime of the FSM. When does the state
machine die? I was expecting that the state machine has to be explicitly
killed (similar to fsm's start() method). But from whatever I have figured
out, I think the state machine dies if it is in a state and no event occurs.
If that is true, what will be an elegant way to "wait" inside a state till
some event occurs (i.e. keeping FSM alive)?
I came up with 2 ways:
1. Have following transition from the waiting state:
Row < state_waiting , none, state_waiting , none, none>
and keep on calling process_event(none())
This however causes the entering the state again and again and gives me
segmentation fault ultimately.
2. Have following transition:
Row < state_waiting, none, state_waiting, none, Gc_always_false>
where guard condition Gc_always_false returns false, prohibiting the
transition but still keeping the state machine alive.
Can you please tell me if the 2nd option is correct and if there is a better
way to sit idle in one state and keep the machine alive.
Thanks!
--
View this message in context: http://boost.2283326.n4.nabble.com/Boost-MSM-Ways-to-send-info-out-from-state-machine-to-outside-world-tp3799703p3800512.html
Sent from the Boost - Users mailing list archive at Nabble.com.
No, what gave you this idea?
I'm afraid you're mixing 2 concepts. The lifecycle of a state machine is the
same as any other class. Created on the stack, it is destroyed by stack
unwinding, created on the heap, by delete.
The second concept is what is called run-to-completion. A state machine
processes an event to the end (meaning, guard, exit, transition action,
entry) then does nothing until another event is processed. True, there are
state machine libraries running constantly in a thread, but this eats your
cycles faster than a wolf a herd of sheeps and causes more race conditions
than the upcoming Oktoberfest will produce drunken tourists sleeping on the
pavement on my way home ;-)
So, no, msm does not do this.
The method start() is simply an optimization allowing you to delay the first
call to on_entry until you really want it.
> If that is true, what will be an elegant way to "wait" inside a state till
> some event occurs (i.e. keeping FSM alive)?
> I came up with 2 ways:
>
> 1. Have following transition from the waiting state:
> Row < state_waiting , none, state_waiting , none, none>
> and keep on calling process_event(none())
> This however causes the entering the state again and again and gives me
> segmentation fault ultimately.
Yes, stack overflow. Not something you want.
> 2. Have following transition:
> Row < state_waiting, none, state_waiting, none, Gc_always_false>
> where guard condition Gc_always_false returns false, prohibiting the
> transition but still keeping the state machine alive.
>
> Can you please tell me if the 2nd option is correct and if there is a
> better
> way to sit idle in one state and keep the machine alive.
If you want to keep your processor busy, sure, but I won't recommend it ;-)
Seriously, a state machine is event-triggered and does nothing until a next
event is fired. It's a purely reactive system.
What are you trying to achieve?
HTH,
Christophe
I was under the impression that if the FSM runs out of events it dies and so
one needs to keep feeding it events (be it none()) to keep the machine
alive. In my case, I can think of at least two scenarios where my machine
will be sitting idle: 1. While setting up connection, till it gets response
from the remote device 2.After sending its share of data, till it receives
new lot from the controller. Since I was under the impression that I have to
keep calling an event to keep the machine alive, I was looking for a
mechanism that will let me call an event but /not/ change the state and
/not/ keep reentering the same state again and again, causing seg fault.
>From what you are saying, I will assume that if the state machine enters
waiting state (or any other state for that matter) and no event occurs, it
will stay in the same state forever. Also, I will assume that the state
machine will die whenever it goes out of scope (if its a stack variable) or
is explicitly deleted (if created on heap).
Christophe Henry-3 wrote:
>
> True, there are state machine libraries running constantly in a thread,
> but this eats your
> cycles faster than a wolf a herd of sheeps and causes more race conditions
> than the upcoming Oktoberfest will produce drunken tourists sleeping on
> the
> pavement on my way home ;-)
>
Btw those analogies were hilarious!
Thanks for the help!
--
View this message in context: http://boost.2283326.n4.nabble.com/Boost-MSM-Ways-to-send-info-out-from-state-machine-to-outside-world-tp3799703p3802740.html
Sent from the Boost - Users mailing list archive at Nabble.com.
Thanks!
--
View this message in context: http://boost.2283326.n4.nabble.com/Boost-MSM-Ways-to-send-info-out-from-state-machine-to-outside-world-tp3799703p3802789.html
The state machine will die only when destroyed (by going out of scope or
being deleted). Until it happens, it does nothing.
The only time it does something is when you process an event.
> Christophe Henry wrote:
>>
>> True, there are state machine libraries running constantly in a thread,
>> but this eats your
>> cycles faster than a wolf a herd of sheeps and causes more race
>> conditions
>> than the upcoming Oktoberfest will produce drunken tourists sleeping on
>> the
>> pavement on my way home ;-)
>>
> Btw those analogies were hilarious!
>
> Thanks for the help!
:)
No. This would be again my metaphors about eating your cycles. It would also
require an extra thread and this would be the race condition stuff.
The guards are evaluated when you process an event.
When you call process_event(event()), the state machine does:
- check the guard. If true:
- call the exit action
- call the transition action
- call the entry action
- else: check if another transition is possible. If yes, repeat, otherwise
stop.
Then it does nothing again.
HTH,
Christophe
--
View this message in context: http://boost.2283326.n4.nabble.com/Boost-MSM-Ways-to-send-info-out-from-state-machine-to-outside-world-tp3799703p3810805.html
Sent from the Boost - Users mailing list archive at Nabble.com.