"Felipe Magno de Almeida"
On Tue, Jun 24, 2008 at 4:57 PM, Andreas Huber
wrote: "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.
As we have seen in a different example, after Y is entered a different inner state than Z might be entered next. That's why the approach to pass the inner state arguments to simple_state<> is IMO not to be pursued further.
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. [snip]
I agree that it is a good idea to allow that. So with "fixed" you meant the fact that a user would have to implement two factories if two different constructors should be called in two different transitions. [snip]
quoting the other email:
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?
If we were to define that only the destination state and its outer states can be called with parameters, then no this wouldn't be too hard. See below.
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.
Ok, forget about the map (that might very well be an implementation detail only). I just wanted to emphasize that the transit<> interface should not force the user to mention the different state types in any particular order. Yes, there is a natural order for the destination state and its outer states, but there's none for the inner state(s) of the destination state. That's why I would prefer an interface where the user simply specifies a state type with its associated ctor arguments, then another type with its ctor arguments, etc. Whether he prefers to list the outer or the inner states first is best left to his taste.
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 don't think I understand. The only purpose of the history example was to show that you can't always predict at compile time exactly what inner states will be entered when you transition to a certain outer state. In the CameraWithHistory2 case, as a result of the transition triggered by EvShutterReleased, you will enter either Idle *or* Configuring, so you might want to specify ctor arguments for *both* states.
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.
Agreed.
So I think that my cascate_transit would do fine here too.
Not IMO, because "cascade" + "outer" suggest that there's a natural order that does not exist for inner states. Sure this is "just" naming and is easily resolved but I'm also not very fond of the the chaining interface (no technical reason just personal preference). I would much rather have something like this: transit<MyState>(ctor<SomeOtherState>(1, 42), ctor<YetAnotherState>(24), ...) You wouldn't mention states with default ctors. Also, you can mention the states in any order you see fit. Would this work for you? Disclaimer: I'm not yet sure whether this interface is implementable with reasonable effort. It might turn out *very* tricky with history.
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); } };
Agreed. Regards, -- Andreas Huber When replying by private email, please remove the words spam and trap from the address shown in the header.