jbeard4 / SCION

SCXML/Statecharts in JavaScript, moved to gitlab: https://gitlab.com/scion-scxml/scion
https://scion.scxml.io
Apache License 2.0
149 stars 29 forks source link

Starting state machine within running state machine #397

Closed jasonpfi closed 6 years ago

jasonpfi commented 6 years ago

Is there a way to call another XML file from the state machine that is currently executing?

I want to start another State Machine based on a state of the current machine. So far I have used "" with both the absolute directory path and the URL of the XML file hosted on an apache server. Neither has worked.

I had an idea to add a listener to the current state machine and spawn another interpreter if a certain state was achieved, but this seems to have barriers to the approach.

Any help would be appreciated!

jasonpfi commented 6 years ago

Note: I am using SCXML.

jasonpfi commented 6 years ago

Example: I always get a timeout

\ \ \ \ \ \ \ \ \ \ \ \ \

jbeard4 commented 6 years ago

You are doing this correctly, but SCION does not currently support <invoke>. The next version of SCION will support <invoke>, so please stand by. Thanks.

jasonpfi commented 6 years ago

Great! Any idea on when this is going to be released?

jbeard4 commented 6 years ago

Maybe next week

jasonpfi commented 6 years ago

Hi, Any idea when the invoke tag will be implemented in the code base?

jbeard4 commented 6 years ago

Pretty soon. I am getting it ready for release.

jbeard4 commented 6 years ago

@jasonpfi Hi. The the latest version of scion released today (4.3.1) supports <invoke>. I would appreciate if you could please give it a try, and report any bugs. Thanks.

jasonpfi commented 6 years ago

Great, will definitely give it a try on Monday.

Getafix-hub commented 6 years ago

Thanks Jacob! I will test invoke later this week

jbeard4 commented 6 years ago

Great, I look forward to your feedback. Thanks

Getafix-hub commented 6 years ago

The invoke is basically working, but is there a way to make the parent context accessible? for example, in the parent script, I can send a websocket message: ws.send(s) but that does not work in the child script

Parent scxml extract

    <state id="state2">
        <onentry>
            <script>
                <log label="In state2"/>
            </script>
        </onentry>

        <invoke src="echoChild.xml" type="scxml">
            <finalize/>
        </invoke>

        <transition event="done.invoke.state2.*" target="fstate">
            <log label="Received event done.invoke.state2.*"/>
        </transition>

        <transition event="error.invoke.state2.*" target="fstate">
            <log label="Received event error.invoke.state2.*"/>
        </transition>
    </state>

echoChild.xml: (update: moved transition outside onentry block)

<?xml version="1.0" encoding="UTF-8"?>
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="idle">

    <datamodel>
        <data id="msg" expr="[7,8,9]"/>
    </datamodel>

    <state id="idle">
        <onentry>
            <log label="Echo Child - idle state"/>
            <script>
                const json = {
                    "type": "MSG_ECHO", 
                    "value": { "msg": msg  }};
                const s = JSON.stringify(json);
                console.log('In idle ' + s);
                ws.send(s);
            </script>
        </onentry>

         <transition event="MSG_ECHO" target="fstate">
                <log label="Received MSG_ECHO"/>
         </transition>
    </state>

    <final id="fstate">
        <onentry>
            <log label="Echo Child - final state"/>
        </onentry>
    </final>

</scxml>
jbeard4 commented 6 years ago

SCXML supports data sharing between parent and child invoked instances through the use of the param element. This lets you initialize data in the child session to data from the parent session. You can find an example of this in test226 of the scxml IRP test suite.

https://github.com/jbeard4/scxml-test-framework/blob/master/test/w3c-ecma/test226.txml.scxml

https://github.com/jbeard4/scxml-test-framework/blob/master/test/w3c-ecma/test226sub1.scxml

Getafix-hub commented 6 years ago

Thanks!

I was able to share the ws websocket from the parent

`

        <finalize/>
    </invoke>

to the child state machine

`

would you have any pointer showing how the child state machine can receive the events:

jbeard4 commented 6 years ago

In general, I recommend reviewing the spec for <invoke> and <send>: https://www.w3.org/TR/scxml/#invoke https://www.w3.org/TR/scxml/#send

Can the parent state machine forward events to a child state machine?

There are two ways to achieve this:

Can a child state machine register for event notifications to receive all the parent's events?

Just use regular transitions in the child state machine to handle the events sent by the parent.

If this support is helpful, please consider backing the project on OpenCollective. It really helps to sustain the project. Thank you!

Getafix-hub commented 6 years ago

Thank you! As far as I can tell, Invoke feature works as expected

jbeard4 commented 6 years ago

Thank you for trying it out and providing feedback.