Looped invoke в событии scxml - PullRequest
       16

Looped invoke в событии scxml

0 голосов
/ 08 октября 2018

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

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

1 Ответ

0 голосов
/ 08 октября 2018

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

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

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

Я думаю, что может быть проблема с тем, как вы это поняли, потому что вызванный сеанс имеет свою собственную модель данных (то есть, свою собственную память).Вы можете связать начальные значения модели данных дочернего сеанса, используя <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/#finalize

...