diff options
-rw-r--r-- | src/uscxml/Interpreter.cpp | 25 | ||||
-rw-r--r-- | test/src/issues/test-issue67.scxml | 36 |
2 files changed, 60 insertions, 1 deletions
diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index 12f1c32..596bf20 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -2695,7 +2695,30 @@ void InterpreterImpl::finalizeAndAutoForwardCurrentEvent() { Arabica::XPath::NodeSet<std::string> finalizes = DOMUtils::filterChildElements(_nsInfo.xmlNSPrefix + "finalize", invokeIter->second.getElement()); for (size_t k = 0; k < finalizes.size(); k++) { Element<std::string> finalizeElem = Element<std::string>(finalizes[k]); - executeContent(finalizeElem); + + bool hasChildElems = false; + Node<std::string> child = finalizeElem.getFirstChild(); + while(child) { + if (child.getNodeType() == Node_base::ELEMENT_NODE) { + hasChildElems = true; + break; + } + child = child.getNextSibling(); + } + + if (hasChildElems) { + executeContent(finalizeElem); + } else { + // Specification 6.5.2: http://www.w3.org/TR/scxml/#N110EF + if (HAS_ATTR(invokeIter->second.getElement(), "namelist")) { + std::list<std::string> names = tokenize(ATTR(invokeIter->second.getElement(), "namelist")); + for (std::list<std::string>::iterator nameIter = names.begin(); nameIter != names.end(); nameIter++) { + if (_currEvent.data.compound.find(*nameIter) != _currEvent.data.compound.end()) { + _dataModel.assign(*nameIter, _currEvent.data.compound[*nameIter]); + } + } + } + } } } if (HAS_ATTR(invokeIter->second.getElement(), "autoforward") && stringIsTrue(ATTR(invokeIter->second.getElement(), "autoforward"))) { diff --git a/test/src/issues/test-issue67.scxml b/test/src/issues/test-issue67.scxml new file mode 100644 index 0000000..e1fc5fa --- /dev/null +++ b/test/src/issues/test-issue67.scxml @@ -0,0 +1,36 @@ +<scxml datamodel="lua" initial="main" name="root" version="1.0" xmlns="http://www.w3.org/2005/07/scxml"> + <datamodel> + <data expr="1" id="i_GLOBAL_VAR"/> + </datamodel> + <state id="main" initial="start"> + <transition event="error.*" target="Fail"/> + <transition cond="i_GLOBAL_VAR==2" event="completed" target="Pass"/> + <transition event="completed" target="Fail"/> + <state id="start"> + <invoke id="test_invoke" namelist="i_GLOBAL_VAR" type="scxml"> + <content> + <scxml datamodel="lua" initial="InvokeStart" name="scxml_invoke" version="1.0" xmlns="http://www.w3.org/2005/07/scxml"> + <datamodel> + <data expr="0" id="i_GLOBAL_VAR"/> + </datamodel> + <final id="InvokeEnd"> + <onentry> + <send event="completed" namelist="i_GLOBAL_VAR" target="#_parent"/> + </onentry> + </final> + <state id="InvokeStart"> + <onentry> + <assign expr="i_GLOBAL_VAR*2" location="i_GLOBAL_VAR"/> + <log expr="i_GLOBAL_VAR" label="INVOKE-i_GLOBAL_VAR"/> + </onentry> + <transition target="InvokeEnd"/> + </state> + </scxml> + </content> + <finalize/> + </invoke> + </state> + </state> + <final id="Fail"/> + <final id="Pass"/> +</scxml> |