|
Boost Users : |
From: Johan Nilsson (r.johan.nilsson_at_[hidden])
Date: 2006-05-09 03:13:29
Tim Milward wrote:
> Johan Nilsson wrote:
>> 1. For a state, is it possible to specify a method that will be
>> called when an event with no defined handlers is received?
>
> Interesting question. Can all events inherit from a common base class,
> to which a state could define a (default) reaction, and override this
> with reactions to specific event sub-classes?
Should be possible from my point of view. Not sure how the framework would
handle that even though it sounds reasonable. It's a bit limiting though,
and should be possible have support for in the library.
I'd figure it's a pretty common requirement to be able to take actions (log
a warning or similar) when an unexpected event is received.
>
>> 2. Is is somehow possible to reuse state definitions as substates of
>> different "higher-level" states?
>
> In boost/libs/statechart/doc/tutorial.html#TransitionActions it says,
> "With Boost.Statechart, a transition action can be a member of any
> common outer context" and goes on to give some examples. If I've
> understood your question correctly then the answer is "Yes".
Actually, I'm inclined to say "No" considering the following (partially
duplicated from your part later in the posting):
Top
Remote
Idle
Executing
Local
Idle
Executing
This I cannot do, right? Idle and Executing would ideally be the same, but
as they are statically associated with their outer states (and vice versa)
it doesn't look like it's possible.
>
>> - I've got an application that can be either in remote or locally
>> controlled mode (this is the highest-level states).
>> - Certain events are allowed both in remote and local, while some
>> are not. As an example, the "CommandEvent" event should be handled
>> both in remote and local - resulting in the "ExecutingCommandState"
>> being entered. - I'd like to be able to reuse the definition of
>> ExecutingCommandState regardless of the enclosing state being Remote
>> or Local - Possible?
>
> Could you implement this with orthogonal regions?
>
> Top
> Remote
> Local
> ------
> Idle
> Executing
>
> Here the top state contains two orthogonal regions separated by a
> dashed line.
Sorry for my ignorance, but what then happens if there would be an
additional substate, that should only be possible when in e.g. the Remote
state.
> The only problem here is that actions (in transitions
> from say Idle) that need to be different depending on whether it's in
> Remote or Local gain conditional logic. (If that's all Remote and
> Local are used for they could just be replaced by a bool member of
> Top.) If you had
>
> Top
> Remote
> RIdle
> RExecuting
> Local
> LIdle
> LExecuting
>
> you'd avoid this, at the expense of possibly repeating code in the
> (only slightly different) actions of a transition originating from
> either RIdle or LIdle. This common code could perhaps be extracted
> into a method belonging to the shared super-state, Top.
This is more similar to what I've got. There isn't really any other code
duplication that having to define the e.g. RIdle, LIdle, RExecuting,
LExecuting, as the state machine itself holds a reference to the domain
object responsible for executing the actions. Within the different states I
simply get this object using context<StateMachine> and delegate - so the
state machine is in this case only used for discriminating the disallowed
events according to the current state.
If I had lots of different actions that could be performed this would result
in a very bloated interface for the domain object, but in this case it's not
a problem - I can keep the interface down to 3-4 methods.
>
> This sounds like a similar problem to the one I face. Where are you
> planning to execute the command? In my application the commands take a
> long time, so are not suitable for implementing as an action.
I'm planning to execute the command(s) in context of the react(...) method
calls. Some of them do take a pretty long time to execute, but as the
intention is to only accept one active command at a time it doesn't really
matter (this isn't ideal though, see below).
> UML
> provides "Do Activities" that can be used for this purpose. The
> statechart docs suggest simulating this "with a separate thread that
> is started in the entry action and canceled (!) in the exit action of
> a particular state". I quite like that approach.
I considered executing the commands in a worker thread similar to that
approach; when receiving a command the FSM would enter the ExecutingCommand
state, kick off a new thread (or using a previously existing worker thread)
to execute the command. The problem I ran into that I wanted the
command-executing thread _itself_ being able to signal the completion of the
command (and thus trigger exiting the ExecutingCommand state to the previous
state). It should never be possible to exit the state unless the command has
run to an end, e.g. by unconditionally joining the worker thread in the
state's destructor.
I couldn't really find a clean, thread-safe way to implement this. Did you
actually try to implement anything like this?
Thanks // Johan
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