2016-11-29 6 views
0

У меня есть класс модели какМожно ли создать HierarchicalGraphMachine из HierarchicalMachine экземпляра модели получены с использованием переходов

class MyModel(HierarchicalMachine): 
    Machine.__init__(self, states=self.states, transitions=self.transitions, 
                initial='EstablishingWsConnection') 
... 

, который прекрасно работает.

Теперь я хотел бы создать HierarchicalGraphMachine из моей модели, как

model = MyModel() 
GraphMachine = mfact.get_predefined(graph=True, nested=True) 
grMachine =self.GraphMachine(      
        send_event=False, 
        auto_transitions=False, 
        title="BootNotificationStates", 
        show_conditions=True) 
hgm = HierarchicalGraphMachine(model, grMachine) 

hgm.model.show_graph('mystate.png') 

результатов в mystate.png

Можно ли повторно использовать мой экземпляр модели для рисунков?

Thx,

вал

ответ

1

Как уже было сказано this, рекомендуется использовать гнездо вашего HierarchicalStateMachine в HierarchicalGraphMachine. Прямо сейчас transitions содержит bug, который влияет на разбор вложенных состояний. Вот почему это выглядит немного странно. Скоро это будет исправлено! В конце концов, это:

Решение 1: Вложение

from transitions.extensions import MachineFactory as factory 

HSM = factory.get_predefined(nested=True) 
GraphHSM = factory.get_predefined(nested=True, graph=True) 

class MyModel(HSM): 
    def __init__(self): 
     self.states = ['A', 'B', 'C'] 
     self.transitions = [['go', 'A', 'B'], 
          ['go', 'B', 'C'], 
          ['go', 'C', 'A']] 
     super(MyModel, self).__init__(self, states=self.states,  
             transitions=self.transitions, 
             auto_transitions=False, initial='A') 

mymodel = MyModel() 

# define the nesting for the new machine 
states = [{'name': 'mymodel', 'children': mymodel}] 
# set the initial state to A of mymodel. Replace the underscore 
# with the seperatore you are using 
graph_machine = GraphHSM(states=states, auto_transitions=False, 
         title="Reused Machine", initial="mymodel_A") 
graph_machine.graph.draw('reuse.png', prog='dot') 

Если в результате этого: enter image description here

Опять же, это рекомендуемый способ.Однако, если у вас действительно должны иметь свои состояния на уровне корня только что созданной машины, вы можете возиться с внутренними частями обеих машин, а обезьяна заплатит вам путь к славе. transitions управляет своими центральными частями в двух коллекциях: список с states и словарь с events (которые содержат переходы состояний). Второе, что нужно знать, это переход к обновлению графика, когда он будет действительным. Объекты типа NestedTransition не знают, как это сделать. Так это то, что вы могли бы сделать:

Решение 2: Заделка

# Create a new graph_machine which is initialized in mymodel's state 
graph_machine = GraphHSM(mymodel, title="Patched Machine", 
         states=[mymodel.state], 
         initial=mymodel.state) 
# shallow copy the core parts to the new machine 
graph_machine.events = mymodel.events 
graph_machine.states = mymodel.states 
# reinitialize the graph with the new configuration 
mymodel.get_graph(force_new=True) 

# 'upcast' the transitions to be of the type NestedGraphTransition 
from transitions.extensions.factory import NestedGraphTransition 
for event in mymodel.events.values(): 
    event.machine = graph_machine 
    for lists in event.transitions.values(): 
     for transition in lists: 
      transition.__class__ = NestedGraphTransition 
# use the machine and test if the graph has been updated 
mymodel.go() 
mymodel.graph.draw('patching.png', prog='dot') 

В результате вы получите это: enter image description here

Я не знаю, как пуленепробиваемые второе решение но я хотел оставить его здесь как немного документация о том, как работает transitions ... и, конечно, мне было любопытно, если он действительно работает;

1

GraphMachine не то, что mfact.get_predefined(graph=True, nested=True) даст вам. Это будет mfact.get_predefined(graph=True). То, что вы называете GraphMachine здесь, уже HierarchicalGraphMachine.

Для этого вы можете создать HierarchicalGraphMachine, как в следующем фрагменте.

from transitions import Machine 
from transitions.extensions import MachineFactory 

myStates = ['walking', 'running'] 
myTransitions = [ { 'trigger': 'accelerate', 'source': 'walking', 'dest': 'running' } ] 

graphNestedMachineClass = MachineFactory.get_predefined(
    graph=True, nested=True) 
hierarchicalGraphMachine = graphNestedMachineClass(
    states=myStates, transitions=myTransitions, initial='walking') 

Если вы хотите встроить любой тип Machine внутри HierarchicalGraphMachine и использовать модель, вы можете добавить следующий код в приведенном выше фрагменте кода.

class MyModel(object): 
    pass 

myModel = MyModel() 

moreStates = [ 
    'waiting', 
    {'name': 'moving', 'children': hierarchicalGraphMachine } 
] 
moreTransitions = [ 
    { 'trigger': 'wait', 'source': '*', 'dest': 'waiting'}, 
    {'trigger': 'move', 'source': 'waiting', 'dest': 'moving_walking'} 
] 

parentHierarchicalGraphMachine = graphNestedMachineClass(
    model=myModel, states=moreStates, transitions=moreTransitions, initial='waiting') 

Теперь вы можете перемещаться между состояниями, как так:

print myModel.state # prints 'waiting' 
myModel.move() 
print myModel.state # prints 'move_walking' 
myModel.accelerate() 
print myModel.state # prints 'move_running' 
myModel.wait() 
print myModel.state # prints 'waiting' 

И вы могли бы использовать, например, myModel.graph.draw('mystate.png', prog='dot'), чтобы создать диаграмму состояний, такую ​​как следующая.

mystate.png

Для получения более подробной информации, пожалуйста, рассмотреть возможность заглянуть в исходный код переходов factory.py, расположенных в transition/extension пути репозитория переходов. А также взгляните на очень хороший README.md в верхнем каталоге того же репозитория.

Репозиторий переходов доступен через GitHub по адресу https://github.com/tyarkoni/transitions.