在 scxml 事件中循环调用
Looped invoke in scxml event
我有一个带有 "invoke" 元素的 scxml 事件。此调用元素会在调用事件时更新数据模型元素。我怎样才能使这种情况定期发生?例如,是否可以每秒定期调用此调用?或者也许每秒都转换到事件?
后者的问题是,如果我在调用的最终确定部分放置一个转换,调用自身,它似乎不会多次调用调用部分。
我首先想提供一些关于 <invoke>
的背景知识。 <invoke>
被放置为 child 到 <state>
。它在进入状态时启动 child 状态机会话,并在退出状态时停止会话。此外,如果 child 会话进入 <final>
状态,则会在 parent 会话上调度 done.invoke.invokeid
事件。您可以在 parent 状态的转换中使用此 done.invoke.invokeid
事件,以在 child 会话终止时强制退出 parent 状态。最后,parent 和 child 状态可以通过 <send>
相互通信。 parent 可以使用 <send>
与 child 通信,target
属性设置为 _invoke_invokeid
,child 可以与 [=74 通信=] 到 <send>
,target
属性设置为 _parent
。
现在,回答您的问题:
This invoke element updates the datamodel elements when the event is called.
我认为您对此概念化的方式可能有问题,因为调用的会话有自己的数据模型(也就是说,有自己的内存)。您可以使用 <param>
绑定 child 会话的初始数据模型值,但您不能真正在 parent 和 child 会话之间共享内存。这意味着您不能直接在 child 会话中更新 parent 会话中的数据模型,例如使用<assign>
或 <script>
标签。
child会话更新parent会话中的数据模型的唯一方法是通过传递事件(例如<send event="update" target="_parent"><param name="dataToUpdate" expr="dataToUpdate"/></send>
)与parent会话通信. parent 然后需要有一个 <transition>
元素,以便它可以处理从 child 会话发送的事件,例如<transition event="update"><assign location="dataToUpdate" expr="_event.dataToUpdate"/></transition>
.
这引出了一个问题,即 <invoke>
是否是定期更新数据模型的最佳、最简单的方法。例如,将数据模型更新逻辑放在 child 或 <parallel>
状态中可能更简单。这样,您可以使用 <assign>
直接更新数据模型。
How can I make this happen periodically? Is it possible to periodically call this invoke for example, every second? Or perhaps to transition to the event every second?
要定期调用会话,您将进入和退出包含 <invoke
> 元素的状态。以下(未经测试的)代码可能会起作用:
<state id=invokeParent">
<!-- this is some data that you want the child session to update in the parent session -->
<datamodel>
<data id="dataToUpdate" />
</datamodel>
<onentry>
<send event="loop" delay="1s"/> <!-- send the 'loop' event every second to loop in invokeParent -->
</onentry>
<transition event="loop" target="invokeParent" /> <!-- this transition will exit and re-enter the state, restarting the invoked session -->
<transition event="done.invoke.myInvoke" target="invokeParent" /> <!-- also loop if the invoked session terminates -->
<invoke id="myInvoke" type="scxml" src="file:test276sub1.scxml"/> <!-- this is the invoke -->
<!-- this targetless transition handles the update event sent from the child session to the parent to update the parent's datamodel -->
<transition event="update">
<assign location="dataToUpdate" expr="_event.dataToUpdate"/>
</transition>
</state>
The problem with the latter is that if I put a transition in the finalize section of the invoke, calling itself, it does not seem to call the invoke section more than once.
我不认为 transition
是 finalize
的合法 child。 finalize
旨在包含可执行内容(例如 script
、assign
),这些内容允许您在 [=74= 处理由 child 会话发送的事件之前对其进行操作] 会话。
我有一个带有 "invoke" 元素的 scxml 事件。此调用元素会在调用事件时更新数据模型元素。我怎样才能使这种情况定期发生?例如,是否可以每秒定期调用此调用?或者也许每秒都转换到事件?
后者的问题是,如果我在调用的最终确定部分放置一个转换,调用自身,它似乎不会多次调用调用部分。
我首先想提供一些关于 <invoke>
的背景知识。 <invoke>
被放置为 child 到 <state>
。它在进入状态时启动 child 状态机会话,并在退出状态时停止会话。此外,如果 child 会话进入 <final>
状态,则会在 parent 会话上调度 done.invoke.invokeid
事件。您可以在 parent 状态的转换中使用此 done.invoke.invokeid
事件,以在 child 会话终止时强制退出 parent 状态。最后,parent 和 child 状态可以通过 <send>
相互通信。 parent 可以使用 <send>
与 child 通信,target
属性设置为 _invoke_invokeid
,child 可以与 [=74 通信=] 到 <send>
,target
属性设置为 _parent
。
现在,回答您的问题:
This invoke element updates the datamodel elements when the event is called.
我认为您对此概念化的方式可能有问题,因为调用的会话有自己的数据模型(也就是说,有自己的内存)。您可以使用 <param>
绑定 child 会话的初始数据模型值,但您不能真正在 parent 和 child 会话之间共享内存。这意味着您不能直接在 child 会话中更新 parent 会话中的数据模型,例如使用<assign>
或 <script>
标签。
child会话更新parent会话中的数据模型的唯一方法是通过传递事件(例如<send event="update" target="_parent"><param name="dataToUpdate" expr="dataToUpdate"/></send>
)与parent会话通信. parent 然后需要有一个 <transition>
元素,以便它可以处理从 child 会话发送的事件,例如<transition event="update"><assign location="dataToUpdate" expr="_event.dataToUpdate"/></transition>
.
这引出了一个问题,即 <invoke>
是否是定期更新数据模型的最佳、最简单的方法。例如,将数据模型更新逻辑放在 child 或 <parallel>
状态中可能更简单。这样,您可以使用 <assign>
直接更新数据模型。
How can I make this happen periodically? Is it possible to periodically call this invoke for example, every second? Or perhaps to transition to the event every second?
要定期调用会话,您将进入和退出包含 <invoke
> 元素的状态。以下(未经测试的)代码可能会起作用:
<state id=invokeParent">
<!-- this is some data that you want the child session to update in the parent session -->
<datamodel>
<data id="dataToUpdate" />
</datamodel>
<onentry>
<send event="loop" delay="1s"/> <!-- send the 'loop' event every second to loop in invokeParent -->
</onentry>
<transition event="loop" target="invokeParent" /> <!-- this transition will exit and re-enter the state, restarting the invoked session -->
<transition event="done.invoke.myInvoke" target="invokeParent" /> <!-- also loop if the invoked session terminates -->
<invoke id="myInvoke" type="scxml" src="file:test276sub1.scxml"/> <!-- this is the invoke -->
<!-- this targetless transition handles the update event sent from the child session to the parent to update the parent's datamodel -->
<transition event="update">
<assign location="dataToUpdate" expr="_event.dataToUpdate"/>
</transition>
</state>
The problem with the latter is that if I put a transition in the finalize section of the invoke, calling itself, it does not seem to call the invoke section more than once.
我不认为 transition
是 finalize
的合法 child。 finalize
旨在包含可执行内容(例如 script
、assign
),这些内容允许您在 [=74= 处理由 child 会话发送的事件之前对其进行操作] 会话。