On Tue, Jun 24, 2008 at 4:57 PM, Andreas Huber
"Felipe Magno de Almeida"
wrote in message
[snip]
struct Z : sc::simple_state
{ Z(int, int); }; struct Y : sc::simple_state
{ Y() : sc::simple_state(inner_state_arguments(0,1)) {} }; IIUC, then Y as defined above would require that all its inner states have a constructor with two integer parameters. I think this is too limiting.
The naming is confusing, but I meant only the inner initial state Z. [snip]
I'm not sure I understand. How are the constructors "fixed" with the factory approach I suggested? How are they not fixed with other approaches?
My idea is that different transit calls could call different constructors with
different arguments.
struct A : sc::simple_state
{
A(int);
A(int, int);
};
struct B : sc::simple_state
{
typedef sc::custom_reaction<event1> reactiotns;
sc::result react(event1 const&) { return transit<A>(5); }
};
struct C : sc::simple_state
Actually, I have myself an use case for passing arguments to outer states.
I'm just throwing here a suggestion: How about having another way of transiting in this case?
cascate_transit<state1>(inner_arg1, inner_arg2) .outer<state2>(middle_arg1, middle_arg2) .outer<state3>(outer_arg1, middle_arg2);
Something in this direction could work. With .outer you mean to imply that state2 is a direct outer state of state1, right? What if state2 doesn't require any ctor parameters but state3 does? Also, here's a somewhat esoteric but IMO still not unreasonable case:
I wanted that empty constructors could be implicit, so if it wanted to call state2 with an empty constructor, then it wouldn't be needed to call .outer<state2>. And an empty call to outer<statex>() should be defined as calling the default constructor. Should this be too hard?
http://www.boost.org/doc/libs/1_35_0/libs/statechart/doc/CameraWithHistory2....
In the transition triggered by EvShutterReleased, it is clear that we're entering NotShooting but it's not clear whether we will enter Idle or Configuring (this depends on which of the two was active when we last left NotShooting). IMO, you should be able to supply ctor parameters for none, one or even both of the inner states of NotShooting.
At this point I think it is kind of obvious that there's no point in enforcing an order of supplying ctor arguments. We need a map that associates a type with a construction function, with no particular order of map entries. Exactly how said map should look like and how it is constructed is not yet clear to me. I hope I'll find the time to toy around a little bit.
I'm not sure if a map is helpful. What we really need, IMHO, is a way that reactions can construct dictate how state transition is going to be. Not only from a static typing POV, but as dynamic data as well. That's why I have focused on transit<> until now. I see that your example is related to history. Isn't it more related to how the state was, rather than how the state will be? I understand that *if needed* (as much as in my case for construction of outer states) people should be able to pass arguments for all states in the chain. But where someone doesn't matter, the states should be restored. So I think that my cascate_transit would do fine here too. IMHO, a transition is always specific, and anything that wouldn't allow different transitions to pass different arguments to different constructors of the same state in whichever reaction is not enough. Even the same reaction function should be able to transit to different state values for the same state type. I want this for example: struct A : sc::simple_state { int i; A(int i) : i(i) {} }; struct B : sc::simple_state { typedef sc::custom_reaction<event1> reactions; sc::result reac(event1 const& e) { return transit<A>(e.value); } };
And completely off-topic: Also, a state that is instantiated through tss (when multithreaded), or through a global variable (when single-threaded) could be good.
I don't think I understand. Could you elaborate a little bit on this one?
It might not be worth because states are completely templated, and
that could generate too much global points, though that can be
alleviated with downcasting and upcasting the context.
but let me show:
struct A : sc::auto_state
{
A()
{
context<machine>().process_event(event1());
}
};
the code that does the initialization for auto_state would be
something like this:
boost::thread_specific_ptr<context> global_auto_state_context;
template
Regards,
-- Andreas Huber
Regards, -- Felipe Magno de Almeida