Looped invoke в событии scxml

У меня есть событие scxml с элементом "invoke". Этот элемент invoke обновляет элементы модели данных при вызове события. Как я могу сделать это периодически? Можно ли периодически вызывать этот вызов, например, каждую секунду? Или, возможно, переходить на событие каждую секунду?

Проблема с последним состоит в том, что, если я помещаю переход в раздел finalize вызова, вызывающего себя, он, кажется, не вызывает раздел invoke более одного раза.

1 ответ

Решение

Сначала я хотел предоставить некоторые сведения о <invoke>, <invoke> как ребенок <state>, Он запускает сеанс дочернего конечного автомата при входе в состояние и останавливает сеанс при выходе из состояния. Кроме того, если дочерний сеанс вводит <final> состояние, то done.invoke.invokeid событие отправляется на родительский сеанс. Вы можете использовать это done.invoke.invokeid событие при переходе в родительское состояние, чтобы принудительно завершить родительское состояние после завершения дочернего сеанса. Наконец, родительское и дочернее состояния могут общаться друг с другом через <send>, Родитель может общаться с ребенком, используя <send> с target атрибут установлен в _invoke_invokeidи ребенок может общаться с родителем через <send> с target атрибут установлен в _parent,

Теперь на ваши вопросы:

Этот элемент invoke обновляет элементы модели данных при вызове события.

Я думаю, что может быть проблема с тем, как вы это поняли, потому что вызываемый сеанс имеет свою собственную модель данных (то есть, свою собственную память). Вы можете привязать начальные значения модели данных дочернего сеанса, используя <param>, но вы не можете разделить память между родительским и дочерним сеансами. Это означает, что вы не можете обновить модель данных в родительском сеансе непосредственно в дочернем сеансе, используя, например, <assign> или же <script> теги.

Единственный способ для дочернего сеанса обновить модель данных в родительском сеансе - это связаться с родительским сеансом посредством передачи событий (например, <send event="update" target="_parent"><param name="dataToUpdate" expr="dataToUpdate"/></send>). Затем родитель должен иметь <transition> элемент, чтобы он мог обработать событие, отправленное из дочернего сеанса, например <transition event="update"><assign location="dataToUpdate" expr="_event.dataToUpdate"/></transition>,

Это приводит к вопросу о том, <invoke> это лучший и самый простой подход к периодическому обновлению модели данных. Например, может быть проще поместить логику обновления модели данных в дочерний элемент <parallel> государство. Таким образом, вы могли бы использовать <assign> обновить модель данных напрямую.

Как я могу сделать это периодически? Можно ли периодически вызывать этот вызов, например, каждую секунду? Или, возможно, переходить на событие каждую секунду?

Чтобы периодически вызывать сеанс, вы должны входить и выходить из состояния, содержащего <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>

Проблема с последним состоит в том, что, если я помещаю переход в раздел finalize вызова, вызывающего себя, он, кажется, не вызывает раздел invoke более одного раза.

Я не верю transition является законным ребенком finalize, finalize должен содержать исполняемый контент (например, script, assign), которые позволяют вам манипулировать событиями, отправленными дочерним сеансом, прежде чем они будут обработаны родительским сеансом.

См. https://www.w3.org/TR/scxml/.

Другие вопросы по тегам