Skip to content

Instantly share code, notes, and snippets.

@pmuellr
Last active April 13, 2018 01:23
Show Gist options
  • Save pmuellr/810ee407a92d1a31de21 to your computer and use it in GitHub Desktop.
Save pmuellr/810ee407a92d1a31de21 to your computer and use it in GitHub Desktop.
scxml as a JavaScript builder
//------------------------------------------------------------------------------
// examples from:
// State Chart XML (SCXML): State Machine Notation for Control Abstraction
// http://www.w3.org/TR/scxml/
// http://www.w3.org/TR/2014/WD-scxml-20140529/ (latest version)
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// <state id=s">
// <transition event="e" cond="x==1" target="s1"/>
// <transition event="e" target="s2"/>
// <transition event="*" target="s3"/>
// </state>
//------------------------------------------------------------------------------
sc = state( {id:"s"} , function() {
transition( {event:"e", target:"s1", cond:"x==1"} )
transition( {event:"e", target:"s2"} )
transition( {event:"*", target:"s3"} )
})
console.log(JSON.stringify(sc,null,4))
// prints:
// {
// "el": "state",
// "id": "s",
// "children": [
// {
// "el": "transition",
// "event": "e",
// "target": "s1",
// "cond": "x==1"
// },
// {
// "el": "transition",
// "event": "e",
// "target": "s2"
// },
// {
// "el": "transition",
// "event": "*",
// "target": "s3"
// }
// ]
// }
//------------------------------------------------------------------------------
// <parallel id="p">
//
// <transition event="done.state.p" target="someOtherState"/>
//
// <state id="S1" initial="S11">
// <state id="S11">
// <transition event="e4" target="S12"/>
// </state>
// <state id="S12">
// <transition event="e1" target="S1Final"/>
// </state>
// <final id="S1Final"/>
// </state>
//
// <state id="S2" initial="S21">
// <state id=S21">
// <transition event="e1" target="S22"/>
// </state>
// <state id="S22">
// <transition event="e2" target="S2Final/>
// </state>
// <final id="S2Final"/>
// </state>
//
// </parallel>
//------------------------------------------------------------------------------
sc = parallel( {id:"p"}, function() {
transition( {event:"done.state.p", target:"someOtherState"} )
state( {id:"S1", initial:"S11"}, function() {
state( {id:"S11"}, function() {
transition( {event:"e4", target:"S12"} )
})
state( {id:"S12"}, function() {
transition( {event:"e1", target:"S1Final"} )
})
final( {id:"S1Final"} )
})
state( {id:"S2", initial:"S21"}, function() {
state( {id:"S21"}, function() {
transition( {event:"e1", target:"S22"} )
})
state( {id:"S22"}, function() {
transition( {event:"e2", target:"S2Final"} )
})
final( {id:"S2Final"} )
})
})
console.log(JSON.stringify(sc,null,4))
//------------------------------------------------------------------------------
// impl
//------------------------------------------------------------------------------
function parallel( attrs, children ) { return genNode("parallel", attrs, children) }
function state( attrs, children ) { return genNode("state", attrs, children) }
function transition( attrs, children ) { return genNode("transition", attrs, children) }
function final( attrs, children ) { return genNode("final", attrs, children) }
//------------------------------------------------------------------------------
var NodeParent
function genNode(name, attrs, children) {
// create new node with el as first property
var node = { el: name }
// copy in rest of attrs
for (var key in attrs) {
node[key] = attrs[key]
}
// set parentage
node.children = []
if (NodeParent) NodeParent.children.push(node)
// assign children
var prevNodeParent = NodeParent
NodeParent = node
if (children) children()
NodeParent = prevNodeParent
return node
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment