是否可以使用转换从 HierarchicalMachine 派生模型实例创建 HierarchicalGraphMachine
Is it possible to create HierarchicalGraphMachine from HierarchicalMachine derived model instance using transitions
我有一个模特class喜欢
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
是否可以将我的模型实例重新用于绘图?
谢谢,
价值
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')
如果您想在 HierarchicalGraphMachine
中嵌入任何类型的 Machine
并使用模型,您可以将以下代码添加到上述代码段中。
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')
生成如下图所示的状态图。
有关详细信息,请考虑查看转换 factory.py
的源代码,位于转换存储库的 transition/extension
路径中。并且还可以在同一个存储库的顶级目录中查看非常好的 README.md
。
转换存储库可通过 GitHub 在 https://github.com/tyarkoni/transitions 获得。
As answer already states, the recommended solution is to nest your HierarchicalStateMachine
into a HierarchicalGraphMachine
. Right now transitions
contains a 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')
结果应该是这样的:
同样,这是推荐的方式。但是,如果您 真的 需要在新创建的机器的根级别拥有您的状态,您可以修补两台机器的内部结构,然后通过猴子补丁来获得荣耀。 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')
结果你会得到这个:
我不知道第二种解决方案的防弹性能如何,但我想把它留在这里作为 扩展 文档 transitions
如何操作...当然,我很好奇它是否真的有效;P.
我有一个模特class喜欢
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
是否可以将我的模型实例重新用于绘图?
谢谢,
价值
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')
如果您想在 HierarchicalGraphMachine
中嵌入任何类型的 Machine
并使用模型,您可以将以下代码添加到上述代码段中。
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')
生成如下图所示的状态图。
有关详细信息,请考虑查看转换 factory.py
的源代码,位于转换存储库的 transition/extension
路径中。并且还可以在同一个存储库的顶级目录中查看非常好的 README.md
。
转换存储库可通过 GitHub 在 https://github.com/tyarkoni/transitions 获得。
As HierarchicalStateMachine
into a HierarchicalGraphMachine
. Right now transitions
contains a 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')
结果应该是这样的:
同样,这是推荐的方式。但是,如果您 真的 需要在新创建的机器的根级别拥有您的状态,您可以修补两台机器的内部结构,然后通过猴子补丁来获得荣耀。 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')
结果你会得到这个:
我不知道第二种解决方案的防弹性能如何,但我想把它留在这里作为 扩展 文档 transitions
如何操作...当然,我很好奇它是否真的有效;P.