I have an scxml event with an "invoke" element. This invoke element updates the datamodel elements when the event is called. 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?
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.
I first wanted to provide some background on
<invoke>
.<invoke>
is placed as a child to<state>
. It starts a child state machine session on entering the state, and stops the session on exiting the state. Furthermore, if the child session enters a<final>
state, then adone.invoke.invokeid
event is dispatched on the parent session. You can use thisdone.invoke.invokeid
event in a transition on the parent state, to force the parent state to exit when the child session terminates. Finally, the parent and child states can communicate with each other through<send>
. The parent can communicate with the child using<send>
withtarget
attribute set to_invoke_invokeid
, and the child can communicate with the parent through<send>
withtarget
attribute set to_parent
.Now, onto your questions:
I think there may be a problem with the way you have conceptualized this, because the invoked session has its own datamodel (which is to say, its own memory). You can bind the initial datamodel values of the child session using
<param>
, but you can't really share memory between the parent and child sessions. This means that you can't update the datamodel in the parent session directly in the child session using e.g.<assign>
or<script>
tags.The only way for the child session to update the datamodel in the parent session is to communicate with the parent session through passing events (e.g.
<send event="update" target="_parent"><param name="dataToUpdate" expr="dataToUpdate"/></send>
). The parent then needs to have a<transition>
element so that it can process the event sent from the child session, e.g.<transition event="update"><assign location="dataToUpdate" expr="_event.dataToUpdate"/></transition>
.This leads to the question of whether
<invoke>
is the best, simplest approach to updating the datamodel periodically. It might be simpler to, for example, just put the datamodel update logic inside of a child of<parallel>
state. This way, you could use<assign>
to update the datamodel directly.To invoke a session periodically, you would enter and exit the state containing the
<invoke
> element. The following (untested) code would probably work:I don't believe
transition
is a legal child offinalize
.finalize
is meant to contain executable content (e.g.script
,assign
) that allow you to manipulate events sent by the child session before they are processed by the parent session.See https://www.w3.org/TR/scxml/#finalize