Closed thedrow closed 3 years ago
Hello @thedrow,
whether substates are entered in parallel depends in the state.initial
value.
from transitions.extensions import HierarchicalMachine
state = HierarchicalMachine.state_cls(name='A')
child_1 = HierarchicalMachine.state_cls(name='a')
child_2 = HierarchicalMachine.state_cls(name='b')
state.add_substate([child_1, child_2])
machine = HierarchicalMachine(states=[state])
machine.to_A()
print(machine.state) # >>> A
state.initial = ['a', 'b']
machine.to_A()
print(machine.state) # >>> ['A_a', 'A_b']
In theorie, you could also set state.initial
to a subset of child states. But that's not offically supported. It's probably best to either set ONE value for state.initial
or state.initial = [s for s in state.states]
.
The problem is that I'm adding that state dynamically so it is not initially parallel.
In the example above, initial is set after the machine has been initialized and run. The property can be set whenever needed. The state, however, has to be reentered before any effect can be observed.
How do I renter a state I just created? Do I need to call a trigger?
Same as you would do with initially created states. Either you use auto transitions or you add a new transition specifically for that new state:
from transitions.extensions import HierarchicalMachine
class Model:
def __init__(self):
self.machine = HierarchicalMachine(self, states=['A', 'B'], initial='A')
def on_enter_B(self):
child_1 = HierarchicalMachine.state_cls(name='a')
child_2 = HierarchicalMachine.state_cls(name='b')
child_3 = HierarchicalMachine.state_cls(name='c')
state = HierarchicalMachine.state_cls(name='C', initial=['a', 'b', 'c'])
state.add_substate([child_1, child_2, child_3])
self.machine.add_state(state)
# option A: with auto_transitions
# self.to_C()
# option B: without auto_transitions
# self.machine.add_transition(trigger='enter_C', source='*', dest='C')
# self.enter_C()
# option C: without auto_transitions and custom transitions
# every Model is decorated with a 'to' method which create a (temporary) event on-the-fly
self.to('C')
model = Model()
model.to_B()
assert model.state == ['C_a', 'C_b', 'C_c']
I'll close this issue since it's a question about how to use transitions. Feel free to comment anyway. I will reopen the issue should a feature request/bug emerge. For questions about how to use transitions please use Stack Overflow.
You already know this but I quote myself for other readers:
Your question gains higher visibility since most developers look for help there. The targeted community is larger; Some people will even help you to formulate a good question. People get 'rewarded' with 'reputation' to help you. You also gain reputation in case this questions pops up more frequently. It's a win-win situation.
If you tag your question with transitions
and python
as described in the README, Tal and me (and probably others) will get a notification as well.
I have a
started
state and its substates are the state machines of the tasks the actor runs. I'd like to activate both started and one of the states of the task at the same time but it seems like there's no way to declare a parallel state usingadd_nested_substate
. How do I do that?