|
Boost Users : |
Subject: Re: [Boost-users] [statechart] Several questions
From: Andreas Huber (ahd6974-spamboostorgtrap_at_[hidden])
Date: 2009-05-05 08:25:29
Hi Michael
> 1. Is there a clean way to seperate the definition of a state from the
> definition of its initial inner state? Say we have
> // StatePlayGame.h
> #include "MyStateMachine.h"
> class MyStateMachine;
> class StatePlayGame : public boost::statechart::state<StatePlayGame,
> MyStateMachine, StateGameStartup>
> {
> //...
> };
> // StateGameStartup.h
> #include "StatePlayGame.h"
> class StateGameStartup : public boost::statechart::state<StateGameStartup,
> StatePlayGame>
> {
> //...
> };
> It appears that any translation unit that includes StatePlayGame.h also
> requires StateGameStartup.h in order to compile - obviously a less than
> ideal situation.
The implementation of a state and its inner initial state must always reside
in the same TU. There's no generally working way around that. However, you
can make the inner initial state just a dummy state that ...
1. posts a dummy event in its constructor, and
2. has a custom reaction that reacts to said event, and
3. defers all other events
// StatePlayGame.h:
// Includes omitted
struct EvDummy : sc::event< EvDummy > {};
struct Dummy;
struct StatePlayGame :
sc::simple_state< StatePlayGame, MyStateMachine, Dummy > {};
struct Dummy : sc::state<Dummy, StatePlayGame >
{
public:
typedef mpl::list<
sc::custom_reaction< EvDummy >,
sc::deferral< sc::event_base > // Save possibly already pending events
> reactions;
Dummy( my_context ctx ) : my_base( ctx )
{
post_event(new EvDummy());
}
sc::result react( const EvDummy & ); // Only declared here
};
// Dummy.cpp
// Includes & forward declarations omitted
sc::result Dummy::react( const EvDummy & )
{
return transit<StateGameStartup>();
}
> 2. Is it possible to pass parameters to a state's constructor?
No, but that is a pretty popular request. I did consider to allow for state
constructors that could accept the triggering event as parameter. One
problem is that the same state can be entered as a result of several
different events, so you could only accept a base type and type-safety is
therefore wrecked. One might want to pass the arguments to transit<> but
that would preclude the entering of the state as a side effect of
state_machine::initiate.
> Going
> with
> the little example above let's say that StateGameStartup asks the player
> how
> many enemies he wants to fight, and then transitions to StateGameRunning,
> which needs that number. Can it be passed by StateGameRunning's ctor or
> is
> it just required that states can only share information via their context?
In this case I would store said number in StatePlayGame, assuming that
StateGameRunning is a substate of StatePlayGame. If the number of enemies is
passed in as an event carrying parameters then you could simply define a
transition from StateGameStartup to StateGameRunning, with a transition
action that stores the number in StatePlayGame.
HTH,
-- Andreas Huber When replying by private email, please remove the words spam and trap from the address shown in the header.
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