From d5e1f6397c52513018cd59972cf5ca8740de18eb Mon Sep 17 00:00:00 2001 From: Stefan Radomski Date: Mon, 7 Jul 2014 02:38:46 +0200 Subject: Appr. 15% performance boost by avoiding dynamic_cast in DOM --- README.md | 8 +- src/uscxml/Interpreter.cpp | 157 +++++++++++++++------------ src/uscxml/Interpreter.h | 44 ++++---- src/uscxml/debug/SCXMLDotWriter.cpp | 4 +- src/uscxml/interpreter/InterpreterDraft6.cpp | 66 +++++------ src/uscxml/interpreter/InterpreterDraft6.h | 10 +- src/uscxml/interpreter/InterpreterRC.cpp | 68 ++++++------ src/uscxml/interpreter/InterpreterRC.h | 6 +- src/uscxml/transform/ChartToFSM.cpp | 21 +--- src/uscxml/transform/ChartToFSM.h | 6 +- src/uscxml/transform/FSMToPromela.cpp | 2 +- 11 files changed, 198 insertions(+), 194 deletions(-) diff --git a/README.md b/README.md index 039720c..527509a 100644 --- a/README.md +++ b/README.md @@ -67,10 +67,10 @@ uSCXML still fails the following ecmascript tests: - + diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index 7ae34f2..e6fc8fa 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -813,7 +813,7 @@ void InterpreterImpl::init() { NodeSet globalScriptElems = filterChildElements(_nsInfo.xmlNSPrefix + "script", _scxml); for (unsigned int i = 0; i < globalScriptElems.size(); i++) { if (_dataModel) { - executeContent(globalScriptElems[i]); + executeContent(Element(globalScriptElems[i])); } } @@ -881,15 +881,14 @@ void InterpreterImpl::receive(const Event& event, bool toFront) { _condVar.notify_all(); } -void InterpreterImpl::internalDoneSend(const Arabica::DOM::Node& state) { +void InterpreterImpl::internalDoneSend(const Arabica::DOM::Element& state) { if (!isState(state)) return; - Arabica::DOM::Element stateElem = (Arabica::DOM::Element)state; - Arabica::DOM::Element parent = (Arabica::DOM::Element)stateElem.getParentNode(); + Arabica::DOM::Element parent = (Arabica::DOM::Element)state.getParentNode(); Event event; - Arabica::XPath::NodeSet doneDatas = filterChildElements(_nsInfo.xmlNSPrefix + "donedata", stateElem); + Arabica::XPath::NodeSet doneDatas = filterChildElements(_nsInfo.xmlNSPrefix + "donedata", state); if (doneDatas.size() > 0) { // only process first donedata element Arabica::DOM::Node doneData = doneDatas[0]; @@ -912,7 +911,7 @@ void InterpreterImpl::internalDoneSend(const Arabica::DOM::Node& st } } - event.name = "done.state." + ATTR(stateElem.getParentNode(), "id"); // parent?! + event.name = "done.state." + ATTR(state.getParentNode(), "id"); // parent?! receiveInternal(event); } @@ -1502,8 +1501,7 @@ bool InterpreterImpl::nameMatch(const std::string& transitionEvent, const std::s } -bool InterpreterImpl::hasConditionMatch(const Arabica::DOM::Node& conditional) { - +bool InterpreterImpl::hasConditionMatch(const Arabica::DOM::Element& conditional) { if (HAS_ATTR(conditional, "cond") && ATTR(conditional, "cond").length() > 0) { try { return _dataModel.evalAsBool(ATTR_NODE(conditional, "cond"), ATTR(conditional, "cond")); @@ -1524,7 +1522,7 @@ void InterpreterImpl::executeContent(const NodeList& content, bool if (node.getNodeType() != Node_base::ELEMENT_NODE) continue; try { - executeContent(node, true); + executeContent(Element(node), true); } CATCH_AND_DISTRIBUTE2("Error when executing content", content.item(i)); } @@ -1536,13 +1534,13 @@ void InterpreterImpl::executeContent(const NodeSet& content, bool r if (node.getNodeType() != Node_base::ELEMENT_NODE) continue; try { - executeContent(node, true); + executeContent(Element(node), true); } CATCH_AND_DISTRIBUTE2("Error when executing content", content[i]); } } -void InterpreterImpl::executeContent(const Arabica::DOM::Node& content, bool rethrow) { +void InterpreterImpl::executeContent(const Arabica::DOM::Element& content, bool rethrow) { if (content.getNodeType() != Node_base::ELEMENT_NODE) return; @@ -1553,7 +1551,9 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node& cont // --- CONVENIENCE LOOP -------------------------- NodeList executable = content.getChildNodes(); for (int i = 0; i < executable.getLength(); i++) { - executeContent(executable.item(i), rethrow); + if (executable.item(i).getNodeType() != Node_base::ELEMENT_NODE) + continue; + executeContent(Element(executable.item(i)), rethrow); } return; } @@ -1626,6 +1626,7 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node& cont for (unsigned int i = 0; i < childs.getLength(); i++) { if (childs.item(i).getNodeType() != Node_base::ELEMENT_NODE) continue; + Element childElem(childs.item(i)); if (iequals(TAGNAME(childs.item(i)), _nsInfo.xmlNSPrefix + "elseif") || iequals(TAGNAME(childs.item(i)), _nsInfo.xmlNSPrefix + "else")) { if (blockIsTrue) { @@ -1633,11 +1634,11 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node& cont break; } else { // is this block the one to execute? - blockIsTrue = hasConditionMatch(childs.item(i)); + blockIsTrue = hasConditionMatch(childElem); } } else { if (blockIsTrue) { - executeContent(childs.item(i), rethrow); + executeContent(childElem, rethrow); } } } @@ -1805,7 +1806,9 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Node& cont if (execContent.processChildren()) { NodeList executable = content.getChildNodes(); for (int i = 0; i < executable.getLength(); i++) { - executeContent(executable.item(i), rethrow); + if (executable.item(i).getNodeType() != Node_base::ELEMENT_NODE) + continue; + executeContent(Element(executable.item(i)), rethrow); } } execContent.exitElement(content); @@ -1848,25 +1851,24 @@ void InterpreterImpl::returnDoneEvent(const Arabica::DOM::Node& sta } } -bool InterpreterImpl::parentIsScxmlState(const Arabica::DOM::Node& state) { - Arabica::DOM::Element stateElem = (Arabica::DOM::Element)state; +bool InterpreterImpl::parentIsScxmlState(const Arabica::DOM::Element& state) { Arabica::DOM::Element parentElem = (Arabica::DOM::Element)state.getParentNode(); if (iequals(TAGNAME(parentElem), _nsInfo.xmlNSPrefix + "scxml")) return true; return false; } -bool InterpreterImpl::isInFinalState(const Arabica::DOM::Node& state) { +bool InterpreterImpl::isInFinalState(const Arabica::DOM::Element& state) { if (isCompound(state)) { Arabica::XPath::NodeSet childs = getChildStates(state); for (int i = 0; i < childs.size(); i++) { - if (isFinal(childs[i]) && isMember(childs[i], _configuration)) + if (isFinal(Element(childs[i])) && isMember(childs[i], _configuration)) return true; } } else if (isParallel(state)) { Arabica::XPath::NodeSet childs = getChildStates(state); for (int i = 0; i < childs.size(); i++) { - if (!isInFinalState(childs[i])) + if (!isInFinalState(Element(childs[i]))) return false; } return true; @@ -1887,7 +1889,9 @@ Arabica::XPath::NodeSet InterpreterImpl::getChildStates(const Arabi Arabica::DOM::NodeList childElems = state.getChildNodes(); for (int i = 0; i < childElems.getLength(); i++) { - if (isState(childElems.item(i))) { + if (childElems.item(i).getNodeType() != Node_base::ELEMENT_NODE) + continue; + if (isState(Element(childElems.item(i)))) { childs.push_back(childElems.item(i)); } } @@ -1902,12 +1906,12 @@ Arabica::XPath::NodeSet InterpreterImpl::getChildStates(const Arabi return childs; } -Arabica::DOM::Node InterpreterImpl::getParentState(const Arabica::DOM::Node& element) { +Arabica::DOM::Element InterpreterImpl::getParentState(const Arabica::DOM::Node& element) { Arabica::DOM::Node parent = element.getParentNode(); - while(parent && !isState(parent)) { + while(parent && !isState(Element(parent))) { parent = parent.getParentNode(); } - return parent; + return Element(parent); } Arabica::DOM::Node InterpreterImpl::getAncestorElement(const Arabica::DOM::Node& node, const std::string tagName) { @@ -1943,7 +1947,7 @@ Arabica::DOM::Node InterpreterImpl::findLCCA(const Arabica::XPath:: // ancestors.push_back(states[0]); // state[0] may already be the ancestor - bug in W3C spec? Arabica::DOM::Node ancestor; for (int i = 0; i < ancestors.size(); i++) { - if (!isCompound(ancestors[i])) + if (!isCompound(Element(ancestors[i]))) continue; for (int j = 0; j < states.size(); j++) { #if 0 @@ -1978,7 +1982,7 @@ Arabica::XPath::NodeSet InterpreterImpl::getStates(const std::list< return states; } -Arabica::DOM::Node InterpreterImpl::getState(const std::string& stateId) { +Arabica::DOM::Element InterpreterImpl::getState(const std::string& stateId) { if (_cachedStates.find(stateId) != _cachedStates.end()) { return _cachedStates[stateId]; @@ -2010,14 +2014,15 @@ Arabica::DOM::Node InterpreterImpl::getState(const std::string& sta FOUND: if (target.size() > 0) { for (int i = 0; i < target.size(); i++) { - if (!isInEmbeddedDocument(target[i])) { - _cachedStates[stateId] = target[i]; - return target[i]; + Element targetElem(target[i]); + if (!isInEmbeddedDocument(targetElem)) { + _cachedStates[stateId] = targetElem; + return targetElem; } } } // return the empty node - return Arabica::DOM::Node(); + return Arabica::DOM::Element(); } Arabica::XPath::NodeSet InterpreterImpl::getAllStates() { @@ -2029,7 +2034,7 @@ Arabica::XPath::NodeSet InterpreterImpl::getAllStates() { return states; } -Arabica::DOM::Node InterpreterImpl::getSourceState(const Arabica::DOM::Node& transition) { +Arabica::DOM::Node InterpreterImpl::getSourceState(const Arabica::DOM::Element& transition) { if (iequals(TAGNAME(transition.getParentNode()), _nsInfo.xmlNSPrefix + "initial")) return transition.getParentNode().getParentNode(); return transition.getParentNode(); @@ -2042,7 +2047,7 @@ Arabica::DOM::Node InterpreterImpl::getSourceState(const Arabica::D * attribute nor an element is specified, the SCXML Processor must use * the first child state in document order as the default initial state. */ -Arabica::XPath::NodeSet InterpreterImpl::getInitialStates(Arabica::DOM::Node state) { +Arabica::XPath::NodeSet InterpreterImpl::getInitialStates(Arabica::DOM::Element state) { if (!state) { state = _scxml; } @@ -2063,14 +2068,16 @@ Arabica::XPath::NodeSet InterpreterImpl::getInitialStates(Arabica:: NodeSet initElems = filterChildElements(_nsInfo.xmlNSPrefix + "initial", state); if(initElems.size() == 1 && !iequals(ATTR(initElems[0], "generated"), "true")) { NodeSet initTrans = filterChildElements(_nsInfo.xmlNSPrefix + "transition", initElems[0]); - return getTargetStates(initTrans[0]); + return getTargetStates(Element(initTrans[0])); } // first child state Arabica::XPath::NodeSet initStates; NodeList childs = state.getChildNodes(); for (int i = 0; i < childs.getLength(); i++) { - if (isState(childs.item(i))) { + if (childs.item(i).getNodeType() != Node_base::ELEMENT_NODE) + continue; + if (isState(Element(childs.item(i)))) { initStates.push_back(childs.item(i)); return initStates; } @@ -2080,7 +2087,7 @@ Arabica::XPath::NodeSet InterpreterImpl::getInitialStates(Arabica:: return Arabica::XPath::NodeSet(); } -NodeSet InterpreterImpl::getTargetStates(const Arabica::DOM::Node& transition) { +NodeSet InterpreterImpl::getTargetStates(const Arabica::DOM::Element& transition) { NodeSet targetStates; assert(boost::ends_with(TAGNAME(transition), "transition")); @@ -2089,8 +2096,10 @@ NodeSet InterpreterImpl::getTargetStates(const Arabica::DOM::Node childs = transition.getChildNodes(); for (int i = 0; i < childs.getLength(); i++) { - if (childs.item(i).getNodeType() == Node_base::ELEMENT_NODE && iequals(TAGNAME(childs.item(i)), _nsInfo.xmlNSPrefix + "transition")) { - targetStates.push_back(getTargetStates(childs.item(i))); + if (childs.item(i).getNodeType() != Node_base::ELEMENT_NODE) + continue; + if (iequals(TAGNAME(childs.item(i)), _nsInfo.xmlNSPrefix + "transition")) { + targetStates.push_back(getTargetStates(Element(childs.item(i)))); } } return targetStates; @@ -2111,7 +2120,7 @@ NodeSet InterpreterImpl::getTargetStates(const Arabica::DOM::Node InterpreterImpl::getTargetStates(const Arabica::XPath::NodeSet& transitions) { NodeSet targets; for (unsigned int i = 0; i < transitions.size(); i++) { - targets.push_back(getTargetStates(transitions[i])); + targets.push_back(getTargetStates(Element(transitions[i]))); } return targets; } @@ -2187,11 +2196,11 @@ NodeSet InterpreterImpl::filterChildElements(const std::string& tag NodeList childs = node.getChildNodes(); for (unsigned int i = 0; i < childs.getLength(); i++) { - if (childs.item(i).getNodeType() == Node_base::ELEMENT_NODE) { + if (childs.item(i).getNodeType() != Node_base::ELEMENT_NODE) + continue; // std::cout << TAGNAME(childs.item(i)) << std::endl; - if(iequals(TAGNAME(childs.item(i)), tagName)) { - filteredChildElems.push_back(childs.item(i)); - } + if(iequals(TAGNAME(childs.item(i)), tagName)) { + filteredChildElems.push_back(childs.item(i)); } if (recurse) { filteredChildElems.push_back(filterChildElements(tagName, childs.item(i), recurse)); @@ -2229,16 +2238,20 @@ NodeSet InterpreterImpl::filterChildType(const Node_base::Type type NodeSet InterpreterImpl::getProperAncestors(const Arabica::DOM::Node& s1, const Arabica::DOM::Node& s2) { NodeSet ancestors; - if (isState(s1)) { + if (isState(Element(s1))) { Arabica::DOM::Node node = s1; while((node = node.getParentNode())) { - if (!isState(node)) + if (node.getNodeType() != Node_base::ELEMENT_NODE) + continue; + + Element nodeElem(node); + if (!isState(nodeElem)) break; - if (iequals(TAGNAME(node), _nsInfo.xmlNSPrefix + "scxml")) // do not return scxml root itself - this is somewhat ill-defined + if (iequals(TAGNAME(nodeElem), _nsInfo.xmlNSPrefix + "scxml")) // do not return scxml root itself - this is somewhat ill-defined break; - if (!iequals(TAGNAME(node), _nsInfo.xmlNSPrefix + "parallel") && - !iequals(TAGNAME(node), _nsInfo.xmlNSPrefix + "state") && - !iequals(TAGNAME(node), _nsInfo.xmlNSPrefix + "scxml")) + if (!iequals(TAGNAME(nodeElem), _nsInfo.xmlNSPrefix + "parallel") && + !iequals(TAGNAME(nodeElem), _nsInfo.xmlNSPrefix + "state") && + !iequals(TAGNAME(nodeElem), _nsInfo.xmlNSPrefix + "scxml")) break; if (node == s2) break; @@ -2259,7 +2272,7 @@ bool InterpreterImpl::isDescendant(const Arabica::DOM::Node& s1, return false; } -bool InterpreterImpl::isTargetless(const Arabica::DOM::Node& transition) { +bool InterpreterImpl::isTargetless(const Arabica::DOM::Element& transition) { if (transition.hasAttributes()) { if (((Arabica::DOM::Element)transition).hasAttribute("target")) return false; @@ -2267,11 +2280,9 @@ bool InterpreterImpl::isTargetless(const Arabica::DOM::Node& transi return true; } -bool InterpreterImpl::isState(const Arabica::DOM::Node& state) { +bool InterpreterImpl::isState(const Arabica::DOM::Element& state) { if (!state) return false; - if (state.getNodeType() != Arabica::DOM::Node_base::ELEMENT_NODE) - return false; std::string tagName = LOCALNAME(state); if (iequals("state", tagName)) @@ -2287,7 +2298,7 @@ bool InterpreterImpl::isState(const Arabica::DOM::Node& state) { return false; } -bool InterpreterImpl::isFinal(const Arabica::DOM::Node& state) { +bool InterpreterImpl::isFinal(const Arabica::DOM::Element& state) { std::string tagName = LOCALNAME(state); if (iequals("final", tagName)) return true; @@ -2311,11 +2322,11 @@ bool InterpreterImpl::isInEmbeddedDocument(const Node& node) { return false; } -bool InterpreterImpl::isInitial(const Arabica::DOM::Node& state) { +bool InterpreterImpl::isInitial(const Arabica::DOM::Element& state) { if (!isState(state)) return false; - Arabica::DOM::Node parent = state.getParentNode(); + Arabica::DOM::Element parent = (Element)state.getParentNode(); if (!isState(parent)) return true; // scxml element @@ -2325,7 +2336,7 @@ bool InterpreterImpl::isInitial(const Arabica::DOM::Node& state) { return false; } -bool InterpreterImpl::isPseudoState(const Arabica::DOM::Node& state) { +bool InterpreterImpl::isPseudoState(const Arabica::DOM::Element& state) { std::string tagName = LOCALNAME(state); if (iequals("initial", tagName)) return true; @@ -2334,11 +2345,11 @@ bool InterpreterImpl::isPseudoState(const Arabica::DOM::Node& state return false; } -bool InterpreterImpl::isTransitionTarget(const Arabica::DOM::Node& elem) { +bool InterpreterImpl::isTransitionTarget(const Arabica::DOM::Element& elem) { return (isState(elem) || iequals(LOCALNAME(elem), "history")); } -bool InterpreterImpl::isAtomic(const Arabica::DOM::Node& state) { +bool InterpreterImpl::isAtomic(const Arabica::DOM::Element& state) { if (iequals("final", LOCALNAME(state))) return true; @@ -2347,19 +2358,22 @@ bool InterpreterImpl::isAtomic(const Arabica::DOM::Node& state) { Arabica::DOM::NodeList childs = state.getChildNodes(); for (unsigned int i = 0; i < childs.getLength(); i++) { - if (isState(childs.item(i))) + if (childs.item(i).getNodeType() != Node_base::ELEMENT_NODE) + continue; + + if (isState(Element(childs.item(i)))) return false; } return true; } -bool InterpreterImpl::isHistory(const Arabica::DOM::Node& state) { +bool InterpreterImpl::isHistory(const Arabica::DOM::Element& state) { if (iequals("history", LOCALNAME(state))) return true; return false; } -bool InterpreterImpl::isParallel(const Arabica::DOM::Node& state) { +bool InterpreterImpl::isParallel(const Arabica::DOM::Element& state) { if (!isState(state)) return false; if (iequals("parallel", LOCALNAME(state))) @@ -2368,7 +2382,7 @@ bool InterpreterImpl::isParallel(const Arabica::DOM::Node& state) { } -bool InterpreterImpl::isCompound(const Arabica::DOM::Node& state) { +bool InterpreterImpl::isCompound(const Arabica::DOM::Element& state) { if (!isState(state)) return false; @@ -2377,7 +2391,9 @@ bool InterpreterImpl::isCompound(const Arabica::DOM::Node& state) { Arabica::DOM::NodeList childs = state.getChildNodes(); for (unsigned int i = 0; i < childs.getLength(); i++) { - if (isState(childs.item(i))) + if (childs.item(i).getNodeType() != Node_base::ELEMENT_NODE) + continue; + if (isState(Element(childs.item(i)))) return true; } return false; @@ -2463,7 +2479,7 @@ bool InterpreterImpl::hasLegalConfiguration() { bool InterpreterImpl::isLegalConfiguration(const std::list& config) { NodeSet states; for (std::list::const_iterator confIter = config.begin(); confIter != config.end(); confIter++) { - Node state = getState(*confIter); + Element state = getState(*confIter); if (!state) { LOG(INFO) << "No state with id '" << *confIter << "'"; return false; @@ -2507,7 +2523,7 @@ bool InterpreterImpl::isLegalConfiguration(const NodeSet& config) { // The configuration contains one or more atomic states. bool foundAtomicState = false; for (int i = 0; i < config.size(); i++) { - if (isAtomic(config[i])) { + if (isAtomic(Element(config[i]))) { foundAtomicState = true; break; } @@ -2517,10 +2533,10 @@ bool InterpreterImpl::isLegalConfiguration(const NodeSet& config) { // When the configuration contains an atomic state, it contains all of its and ancestors. for (int i = 0; i < config.size(); i++) { - if (isAtomic(config[i])) { + if (isAtomic(Element(config[i]))) { Node parent = config[i]; while((parent = parent.getParentNode())) { - if (isState(parent) && + if (isState(Element(parent)) && (iequals(LOCALNAME(parent), "state") || iequals(LOCALNAME(parent), "parallel"))) { if (!isMember(parent, config)) @@ -2532,7 +2548,8 @@ bool InterpreterImpl::isLegalConfiguration(const NodeSet& config) { // When the configuration contains a non-atomic , it contains one and only one of the state's children for (int i = 0; i < config.size(); i++) { - if (!isAtomic(config[i]) && !isParallel(config[i])) { + Element configElem(config[i]); + if (!isAtomic(configElem) && !isParallel(configElem)) { bool foundChildState = false; //std::cout << config[i] << std::endl; NodeSet childs = getChildStates(config[i]); @@ -2551,10 +2568,10 @@ bool InterpreterImpl::isLegalConfiguration(const NodeSet& config) { // If the configuration contains a state, it contains all of its children for (int i = 0; i < config.size(); i++) { - if (isParallel(config[i])) { + if (isParallel(Element(config[i]))) { NodeSet childs = getChildStates(config[i]); for (int j = 0; j < childs.size(); j++) { - if (!isMember(childs[j], config) && !isHistory(childs[j])) { + if (!isMember(childs[j], config) && !isHistory(Element(childs[j]))) { return false; } } diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h index 2ad1039..1bdae5c 100644 --- a/src/uscxml/Interpreter.h +++ b/src/uscxml/Interpreter.h @@ -323,7 +323,7 @@ public: tthread::lock_guard lock(_mutex); Arabica::XPath::NodeSet basicConfig; for (int i = 0; i < _configuration.size(); i++) { - if (isAtomic(_configuration[i])) + if (isAtomic(Arabica::DOM::Element(_configuration[i]))) basicConfig.push_back(_configuration[i]); } return basicConfig; @@ -372,33 +372,33 @@ public: bool isLegalConfiguration(const Arabica::XPath::NodeSet&); bool isLegalConfiguration(const std::list&); - static bool isState(const Arabica::DOM::Node& state); - static bool isPseudoState(const Arabica::DOM::Node& state); - static bool isTransitionTarget(const Arabica::DOM::Node& elem); - static bool isTargetless(const Arabica::DOM::Node& transition); - static bool isAtomic(const Arabica::DOM::Node& state); - static bool isFinal(const Arabica::DOM::Node& state); - static bool isHistory(const Arabica::DOM::Node& state); - static bool isParallel(const Arabica::DOM::Node& state); - static bool isCompound(const Arabica::DOM::Node& state); + static bool isState(const Arabica::DOM::Element& state); + static bool isPseudoState(const Arabica::DOM::Element& state); + static bool isTransitionTarget(const Arabica::DOM::Element& elem); + static bool isTargetless(const Arabica::DOM::Element& transition); + static bool isAtomic(const Arabica::DOM::Element& state); + static bool isFinal(const Arabica::DOM::Element& state); + static bool isHistory(const Arabica::DOM::Element& state); + static bool isParallel(const Arabica::DOM::Element& state); + static bool isCompound(const Arabica::DOM::Element& state); static bool isDescendant(const Arabica::DOM::Node& s1, const Arabica::DOM::Node& s2); bool isInEmbeddedDocument(const Arabica::DOM::Node& node); - bool isInitial(const Arabica::DOM::Node& state); + bool isInitial(const Arabica::DOM::Element& state); static std::string stateToString(InterpreterState state); - Arabica::DOM::Node getState(const std::string& stateId); + Arabica::DOM::Element getState(const std::string& stateId); Arabica::XPath::NodeSet getStates(const std::list& stateIds); Arabica::XPath::NodeSet getAllStates(); - Arabica::XPath::NodeSet getInitialStates(Arabica::DOM::Node state = Arabica::DOM::Node()); + Arabica::XPath::NodeSet getInitialStates(Arabica::DOM::Element state = Arabica::DOM::Element()); static Arabica::XPath::NodeSet getChildStates(const Arabica::DOM::Node& state); static Arabica::XPath::NodeSet getChildStates(const Arabica::XPath::NodeSet& state); - static Arabica::DOM::Node getParentState(const Arabica::DOM::Node& element); + static Arabica::DOM::Element getParentState(const Arabica::DOM::Node& element); static Arabica::DOM::Node getAncestorElement(const Arabica::DOM::Node& node, const std::string tagName); - virtual Arabica::XPath::NodeSet getTargetStates(const Arabica::DOM::Node& transition); + virtual Arabica::XPath::NodeSet getTargetStates(const Arabica::DOM::Element& transition); virtual Arabica::XPath::NodeSet getTargetStates(const Arabica::XPath::NodeSet& transitions); - virtual Arabica::DOM::Node getSourceState(const Arabica::DOM::Node& transition); + virtual Arabica::DOM::Node getSourceState(const Arabica::DOM::Element& transition); static Arabica::XPath::NodeSet filterChildElements(const std::string& tagname, const Arabica::DOM::Node& node, bool recurse = false); static Arabica::XPath::NodeSet filterChildElements(const std::string& tagName, const Arabica::XPath::NodeSet& nodeSet, bool recurse = false); @@ -482,7 +482,7 @@ protected: Data _cmdLineOptions; - virtual void executeContent(const Arabica::DOM::Node& content, bool rethrow = false); + virtual void executeContent(const Arabica::DOM::Element& content, bool rethrow = false); virtual void executeContent(const Arabica::DOM::NodeList& content, bool rethrow = false); virtual void executeContent(const Arabica::XPath::NodeSet& content, bool rethrow = false); @@ -499,13 +499,13 @@ protected: virtual void send(const Arabica::DOM::Node& element); virtual void invoke(const Arabica::DOM::Node& element); virtual void cancelInvoke(const Arabica::DOM::Node& element); - virtual void internalDoneSend(const Arabica::DOM::Node& state); + virtual void internalDoneSend(const Arabica::DOM::Element& state); static void delayedSend(void* userdata, std::string eventName); void returnDoneEvent(const Arabica::DOM::Node& state); - bool hasConditionMatch(const Arabica::DOM::Node& conditional); - bool isInFinalState(const Arabica::DOM::Node& state); - bool parentIsScxmlState(const Arabica::DOM::Node& state); + bool hasConditionMatch(const Arabica::DOM::Element& conditional); + bool isInFinalState(const Arabica::DOM::Element& state); + bool parentIsScxmlState(const Arabica::DOM::Element& state); IOProcessor getIOProcessor(const std::string& type); @@ -515,7 +515,7 @@ protected: std::map, ExecutableContent> _executableContent; /// TODO: We need to adapt them when the DOM is operated upon - std::map > _cachedStates; + std::map > _cachedStates; std::map _cachedURLs; friend class USCXMLInvoker; diff --git a/src/uscxml/debug/SCXMLDotWriter.cpp b/src/uscxml/debug/SCXMLDotWriter.cpp index 2bccb14..d5471de 100644 --- a/src/uscxml/debug/SCXMLDotWriter.cpp +++ b/src/uscxml/debug/SCXMLDotWriter.cpp @@ -176,7 +176,7 @@ void SCXMLDotWriter::writeStateElement(std::ostream& os, const Arabica::DOM::Ele os << "]" << std::endl; } } - if (InterpreterImpl::isState(childElems.item(i))) { + if (InterpreterImpl::isState(Element(childElems.item(i)))) { writeStateElement(os, (Arabica::DOM::Element)childElems.item(i)); } if (childElems.item(i).getNodeType() == Node_base::ELEMENT_NODE && iequals(TAGNAME(childElems.item(i)), "initial")) { @@ -256,7 +256,7 @@ std::string SCXMLDotWriter::getDetailedLabel(const Arabica::DOM::Element(childElems.item(i))) || iequals(TAGNAME(childElems.item(i)), "transition") || iequals(TAGNAME(childElems.item(i)), "initial") || false) diff --git a/src/uscxml/interpreter/InterpreterDraft6.cpp b/src/uscxml/interpreter/InterpreterDraft6.cpp index fdbd21b..20f89d2 100644 --- a/src/uscxml/interpreter/InterpreterDraft6.cpp +++ b/src/uscxml/interpreter/InterpreterDraft6.cpp @@ -360,7 +360,7 @@ Arabica::XPath::NodeSet InterpreterDraft6::selectTransitions(const NodeSet states; for (unsigned int i = 0; i < _configuration.size(); i++) { - if (isAtomic(_configuration[i])) + if (isAtomic(Element(_configuration[i]))) states.push_back(_configuration[i]); } states.to_document_order(); @@ -378,7 +378,7 @@ Arabica::XPath::NodeSet InterpreterDraft6::selectTransitions(const bool foundTransition = false; NodeSet transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", states[index]); for (unsigned int k = 0; k < transitions.size(); k++) { - if (isEnabledTransition(transitions[k], event)) { + if (isEnabledTransition(Element(transitions[k]), event)) { enabledTransitions.push_back(transitions[k]); foundTransition = true; goto LOOP; @@ -407,7 +407,7 @@ LOOP: return enabledTransitions; } -bool InterpreterDraft6::isEnabledTransition(const Node& transition, const std::string& event) { +bool InterpreterDraft6::isEnabledTransition(const Element& transition, const std::string& event) { std::string eventName; if (HAS_ATTR(transition, "event")) { eventName = ATTR(transition, "event"); @@ -438,7 +438,7 @@ Arabica::XPath::NodeSet InterpreterDraft6::selectEventlessTransitio NodeSet states; for (unsigned int i = 0; i < _configuration.size(); i++) { - if (isAtomic(_configuration[i])) + if (isAtomic(Element(_configuration[i]))) states.push_back(_configuration[i]); } states.to_document_order(); @@ -456,7 +456,8 @@ Arabica::XPath::NodeSet InterpreterDraft6::selectEventlessTransitio bool foundTransition = false; NodeSet transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", states[index]); for (unsigned int k = 0; k < transitions.size(); k++) { - if (!HAS_ATTR(transitions[k], "event") && hasConditionMatch(transitions[k])) { + Element transElem(transitions[k]); + if (!HAS_ATTR(transElem, "event") && hasConditionMatch(transElem)) { enabledTransitions.push_back(transitions[k]); foundTransition = true; goto LOOP; @@ -487,12 +488,12 @@ LOOP: Arabica::XPath::NodeSet InterpreterDraft6::filterPreempted(const Arabica::XPath::NodeSet& enabledTransitions) { Arabica::XPath::NodeSet filteredTransitions; for (unsigned int i = 0; i < enabledTransitions.size(); i++) { - Node t = enabledTransitions[i]; + Element t(enabledTransitions[i]); if (!isTargetless(t)) { for (unsigned int j = 0; j < filteredTransitions.size(); j++) { if (j == i) continue; - Node t2 = filteredTransitions[j]; + Element t2(filteredTransitions[j]); if (isPreemptingTransition(t2, t)) { #if 0 std::cout << "#####" << std::endl << "Transition " << std::endl @@ -518,7 +519,7 @@ LOOP: /** * Is t1 preempting t2? */ -bool InterpreterDraft6::isPreemptingTransition(const Node& t1, const Node& t2) { +bool InterpreterDraft6::isPreemptingTransition(const Element& t1, const Element& t2) { assert(t1); assert(t2); @@ -538,13 +539,13 @@ bool InterpreterDraft6::isPreemptingTransition(const Node& t1, cons return false; } -bool InterpreterDraft6::isCrossingBounds(const Node& transition) { +bool InterpreterDraft6::isCrossingBounds(const Element& transition) { if (!isTargetless(transition) && !isWithinParallel(transition)) return true; return false; } -bool InterpreterDraft6::isWithinParallel(const Node& transition) { +bool InterpreterDraft6::isWithinParallel(const Element& transition) { if (isTargetless(transition)) return false; @@ -565,7 +566,7 @@ Node InterpreterDraft6::findLCPA(const Arabica::XPath::NodeSet ancestors = getProperAncestors(states[0], Node()); Node ancestor; for (int i = 0; i < ancestors.size(); i++) { - if (!isParallel(ancestors[i])) + if (!isParallel(Element(ancestors[i]))) continue; for (int j = 0; j < states.size(); j++) { if (!isDescendant(states[j], ancestors[i]) && (states[j] != ancestors[i])) @@ -623,14 +624,15 @@ void InterpreterDraft6::exitInterpreter() { for (int i = 0; i < statesToExit.size(); i++) { Arabica::XPath::NodeSet onExitElems = filterChildElements(_nsInfo.xmlNSPrefix + "onexit", statesToExit[i]); for (int j = 0; j < onExitElems.size(); j++) { - executeContent(onExitElems[j]); + executeContent(Element(onExitElems[j])); } Arabica::XPath::NodeSet invokeElems = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", statesToExit[i]); // TODO: we ought to cancel all remaining invokers just to be sure with the persist extension for (int j = 0; j < invokeElems.size(); j++) { cancelInvoke(invokeElems[j]); } - if (isFinal(statesToExit[i]) && parentIsScxmlState(statesToExit[i])) { + Element stateElem(statesToExit[i]); + if (isFinal(stateElem) && parentIsScxmlState(stateElem)) { returnDoneEvent(statesToExit[i]); } } @@ -664,7 +666,7 @@ void InterpreterDraft6::exitStates(const Arabica::XPath::NodeSet& e break; } } - if (isInternal && allDescendants && isCompound(source)) { + if (isInternal && allDescendants && isCompound(Element(source))) { ancestor = source; } else { NodeSet tmpStates; @@ -717,7 +719,7 @@ void InterpreterDraft6::exitStates(const Arabica::XPath::NodeSet& e NodeSet historyNodes; for (int k = 0; k < _configuration.size(); k++) { if (iequals(historyType, "deep")) { - if (isAtomic(_configuration[k]) && isDescendant(_configuration[k], statesToExit[i])) + if (isAtomic(Element(_configuration[k])) && isDescendant(_configuration[k], statesToExit[i])) historyNodes.push_back(_configuration[k]); } else { if (_configuration[k].getParentNode() == statesToExit[i]) @@ -812,7 +814,7 @@ void InterpreterDraft6::enterStates(const Arabica::XPath::NodeSet& } } if (iequals(transitionType, "internal") && - isCompound(source) && + isCompound(Element(source)) && allDescendants) { ancestor = source; } else { @@ -828,7 +830,7 @@ void InterpreterDraft6::enterStates(const Arabica::XPath::NodeSet& #endif for (int j = 0; j < tStates.size(); j++) { - addStatesToEnter(tStates[j], statesToEnter, statesForDefaultEntry, defaultHistoryContent); + addStatesToEnter(Element(tStates[j]), statesToEnter, statesForDefaultEntry, defaultHistoryContent); } #if VERBOSE @@ -852,7 +854,7 @@ void InterpreterDraft6::enterStates(const Arabica::XPath::NodeSet& for (int k = 0; k < ancestors.size(); k++) { statesToEnter.push_back(ancestors[k]); - if(isParallel(ancestors[k])) { + if(isParallel(Element(ancestors[k]))) { NodeSet childs = getChildStates(ancestors[k]); for (int l = 0; l < childs.size(); l++) { bool someIsDescendant = false; @@ -863,7 +865,7 @@ void InterpreterDraft6::enterStates(const Arabica::XPath::NodeSet& } } if (!someIsDescendant) { - addStatesToEnter(childs[l], statesToEnter, statesForDefaultEntry, defaultHistoryContent); + addStatesToEnter(Element(childs[l]), statesToEnter, statesForDefaultEntry, defaultHistoryContent); } } } @@ -929,7 +931,7 @@ void InterpreterDraft6::enterStates(const Arabica::XPath::NodeSet& // execute initial transition content for compound states Arabica::XPath::NodeSet transitions = _xpath.evaluate("" + _nsInfo.xpathPrefix + "initial/" + _nsInfo.xpathPrefix + "transition", stateElem).asNodeSet(); for (int j = 0; j < transitions.size(); j++) { - executeContent(transitions[j]); + executeContent(Element(transitions[j])); } } @@ -945,21 +947,23 @@ void InterpreterDraft6::enterStates(const Arabica::XPath::NodeSet& #endif if (isFinal(stateElem)) { internalDoneSend(stateElem); - Element parent = (Element)stateElem.getParentNode(); - - if (isParallel(parent.getParentNode())) { + Node parent = stateElem.getParentNode(); + + if (parent.getNodeType() == Node_base::ELEMENT_NODE && + parent.getParentNode().getNodeType() == Node_base::ELEMENT_NODE && + isParallel(Element(parent.getParentNode()))) { Element grandParent = (Element)parent.getParentNode(); Arabica::XPath::NodeSet childs = getChildStates(grandParent); bool inFinalState = true; for (int j = 0; j < childs.size(); j++) { - if (!isInFinalState(childs[j])) { + if (!isInFinalState(Element(childs[j]))) { inFinalState = false; break; } } if (inFinalState) { - internalDoneSend(parent); + internalDoneSend(Element(parent)); } } } @@ -972,7 +976,7 @@ void InterpreterDraft6::enterStates(const Arabica::XPath::NodeSet& } } -void InterpreterDraft6::addStatesToEnter(const Node& state, +void InterpreterDraft6::addStatesToEnter(const Element& state, Arabica::XPath::NodeSet& statesToEnter, Arabica::XPath::NodeSet& statesForDefaultEntry, Arabica::XPath::NodeSet& defaultHistoryContent) { @@ -994,7 +998,7 @@ void InterpreterDraft6::addStatesToEnter(const Node& state, #endif for (int i = 0; i < historyValue.size(); i++) { - addStatesToEnter(historyValue[i], statesToEnter, statesForDefaultEntry, defaultHistoryContent); + addStatesToEnter(Element(historyValue[i]), statesToEnter, statesForDefaultEntry, defaultHistoryContent); NodeSet ancestors = getProperAncestors(historyValue[i], state); #if VERBOSE @@ -1013,9 +1017,9 @@ void InterpreterDraft6::addStatesToEnter(const Node& state, defaultHistoryContent.push_back(getParentState(state)); NodeSet transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", state); for (int i = 0; i < transitions.size(); i++) { - NodeSet targets = getTargetStates(transitions[i]); + NodeSet targets = getTargetStates(Element(transitions[i])); for (int j = 0; j < targets.size(); j++) { - addStatesToEnter(targets[j], statesToEnter, statesForDefaultEntry, defaultHistoryContent); + addStatesToEnter(Element(targets[j]), statesToEnter, statesForDefaultEntry, defaultHistoryContent); // Modifications from chris nuernberger NodeSet ancestors = getProperAncestors(targets[j], state); @@ -1032,7 +1036,7 @@ void InterpreterDraft6::addStatesToEnter(const Node& state, NodeSet tStates = getInitialStates(state); for (int i = 0; i < tStates.size(); i++) { - addStatesToEnter(tStates[i], statesToEnter, statesForDefaultEntry, defaultHistoryContent); + addStatesToEnter(Element(tStates[i]), statesToEnter, statesForDefaultEntry, defaultHistoryContent); } // addStatesToEnter(getInitialState(state), statesToEnter, statesForDefaultEntry); @@ -1041,7 +1045,7 @@ void InterpreterDraft6::addStatesToEnter(const Node& state, } else if(isParallel(state)) { NodeSet childStates = getChildStates(state); for (int i = 0; i < childStates.size(); i++) { - addStatesToEnter(childStates[i], statesToEnter, statesForDefaultEntry, defaultHistoryContent); + addStatesToEnter(Element(childStates[i]), statesToEnter, statesForDefaultEntry, defaultHistoryContent); } } } diff --git a/src/uscxml/interpreter/InterpreterDraft6.h b/src/uscxml/interpreter/InterpreterDraft6.h index cf73d4b..297434f 100644 --- a/src/uscxml/interpreter/InterpreterDraft6.h +++ b/src/uscxml/interpreter/InterpreterDraft6.h @@ -35,7 +35,7 @@ protected: void microstep(const Arabica::XPath::NodeSet& enabledTransitions); void enterStates(const Arabica::XPath::NodeSet& enabledTransitions); - void addStatesToEnter(const Arabica::DOM::Node& state, + void addStatesToEnter(const Arabica::DOM::Element& state, Arabica::XPath::NodeSet& statesToEnter, Arabica::XPath::NodeSet& statesForDefaultEntry, Arabica::XPath::NodeSet& defaultHistoryContent); @@ -46,13 +46,13 @@ protected: Arabica::XPath::NodeSet selectEventlessTransitions(); Arabica::XPath::NodeSet selectTransitions(const std::string& event); Arabica::XPath::NodeSet filterPreempted(const Arabica::XPath::NodeSet& enabledTransitions); - bool isPreemptingTransition(const Arabica::DOM::Node& t1, const Arabica::DOM::Node& t2); - bool isEnabledTransition(const Arabica::DOM::Node& transition, const std::string& event); + bool isPreemptingTransition(const Arabica::DOM::Element& t1, const Arabica::DOM::Element& t2); + bool isEnabledTransition(const Arabica::DOM::Element& transition, const std::string& event); Arabica::XPath::NodeSet getDocumentInitialTransitions(); - bool isCrossingBounds(const Arabica::DOM::Node& transition); - bool isWithinParallel(const Arabica::DOM::Node& transition); + bool isCrossingBounds(const Arabica::DOM::Element& transition); + bool isWithinParallel(const Arabica::DOM::Element& transition); Arabica::DOM::Node findLCPA(const Arabica::XPath::NodeSet& states); }; diff --git a/src/uscxml/interpreter/InterpreterRC.cpp b/src/uscxml/interpreter/InterpreterRC.cpp index 53feae8..3d17c87 100644 --- a/src/uscxml/interpreter/InterpreterRC.cpp +++ b/src/uscxml/interpreter/InterpreterRC.cpp @@ -111,7 +111,7 @@ InterpreterState InterpreterRC::interpret() { NodeSet globalScriptElems = filterChildElements(_nsInfo.xmlNSPrefix + "script", _scxml); for (unsigned int i = 0; i < globalScriptElems.size(); i++) { if (_dataModel) { - executeContent(globalScriptElems[i]); + executeContent(Element(globalScriptElems[i])); } } @@ -414,14 +414,15 @@ void InterpreterRC::exitInterpreter() { for (int i = 0; i < statesToExit.size(); i++) { Arabica::XPath::NodeSet onExitElems = filterChildElements(_nsInfo.xmlNSPrefix + "onexit", statesToExit[i]); for (int j = 0; j < onExitElems.size(); j++) { - executeContent(onExitElems[j]); + executeContent(Element(onExitElems[j])); } Arabica::XPath::NodeSet invokeElems = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", statesToExit[i]); for (int j = 0; j < invokeElems.size(); j++) { cancelInvoke(invokeElems[j]); } - if (isFinal(statesToExit[i]) && parentIsScxmlState(statesToExit[i])) { - returnDoneEvent(statesToExit[i]); + Element stateElem(statesToExit[i]); + if (isFinal(stateElem) && parentIsScxmlState(stateElem)) { + returnDoneEvent(stateElem); } } _configuration = NodeSet(); @@ -445,7 +446,7 @@ Arabica::XPath::NodeSet InterpreterRC::selectEventlessTransitions() NodeSet atomicStates; for (unsigned int i = 0; i < _configuration.size(); i++) { - if (isAtomic(_configuration[i])) + if (isAtomic(Element(_configuration[i]))) atomicStates.push_back(_configuration[i]); } atomicStates.to_document_order(); @@ -459,7 +460,8 @@ Arabica::XPath::NodeSet InterpreterRC::selectEventlessTransitions() const Node& ancestor = withAncestors[i]; NodeSet transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", ancestor); for (unsigned int k = 0; k < transitions.size(); k++) { - if (!HAS_ATTR(transitions[k], "event") && hasConditionMatch(transitions[k])) { + Element transElem(transitions[k]); + if (!HAS_ATTR(transElem, "event") && hasConditionMatch(transElem)) { enabledTransitions.push_back(transitions[k]); goto BREAK_LOOP; } @@ -491,7 +493,7 @@ Arabica::XPath::NodeSet InterpreterRC::selectTransitions(const std: NodeSet atomicStates; for (unsigned int i = 0; i < _configuration.size(); i++) { - if (isAtomic(_configuration[i])) + if (isAtomic(Element(_configuration[i]))) atomicStates.push_back(_configuration[i]); } atomicStates.to_document_order(); @@ -512,7 +514,7 @@ Arabica::XPath::NodeSet InterpreterRC::selectTransitions(const std: const Node& ancestor = withAncestors[j]; NodeSet transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", ancestor); for (unsigned int k = 0; k < transitions.size(); k++) { - if (isEnabledTransition(transitions[k], event)) { + if (isEnabledTransition(Element(transitions[k]), event)) { enabledTransitions.push_back(transitions[k]); goto BREAK_LOOP; } @@ -535,7 +537,7 @@ BREAK_LOOP: return enabledTransitions; } -bool InterpreterRC::isEnabledTransition(const Node& transition, const std::string& event) { +bool InterpreterRC::isEnabledTransition(const Element& transition, const std::string& event) { std::string eventName; if (HAS_ATTR(transition, "event")) { eventName = ATTR(transition, "event"); @@ -587,12 +589,12 @@ Arabica::XPath::NodeSet InterpreterRC::removeConflictingTransitions Arabica::XPath::NodeSet filteredTransitions; for (unsigned int i = 0; i < enabledTransitions.size(); i++) { - const Node& t1 = enabledTransitions[i]; + Element t1(enabledTransitions[i]); bool t1Preempted = false; Arabica::XPath::NodeSet transitionsToRemove; for (unsigned int j = 0; j < filteredTransitions.size(); j++) { - const Node& t2 = enabledTransitions[j]; + Element t2(enabledTransitions[j]); if (hasIntersection(computeExitSet(t1), computeExitSet(t2))) { if (isDescendant(getSourceState(t1), getSourceState(t2))) { transitionsToRemove.push_back(t2); @@ -702,7 +704,7 @@ void InterpreterRC::exitStates(const Arabica::XPath::NodeSet& enabl NodeSet historyNodes; for (int k = 0; k < _configuration.size(); k++) { if (iequals(historyType, "deep")) { - if (isAtomic(_configuration[k]) && isDescendant(_configuration[k], statesToExit[i])) + if (isAtomic(Element(_configuration[k])) && isDescendant(_configuration[k], statesToExit[i])) historyNodes.push_back(_configuration[k]); } else { if (_configuration[k].getParentNode() == statesToExit[i]) @@ -757,7 +759,7 @@ function computeExitSet(transitions) Arabica::XPath::NodeSet InterpreterRC::computeExitSet(const Arabica::XPath::NodeSet& transitions) { NodeSet statesToExit; for (unsigned int i = 0; i < transitions.size(); i++) { - const Node& t = transitions[i]; + Element t(transitions[i]); if (isTargetless(t)) continue; Arabica::DOM::Node domain = getTransitionDomain(t); @@ -852,12 +854,10 @@ void InterpreterRC::enterStates(const Arabica::XPath::NodeSet& enab if (isMember(s, statesForDefaultEntry)) { // execute initial transition content for compound states Arabica::XPath::NodeSet transitions = _xpath.evaluate("" + _nsInfo.xpathPrefix + "initial/" + _nsInfo.xpathPrefix + "transition", s).asNodeSet(); - for (int j = 0; j < transitions.size(); j++) { - executeContent(transitions[j]); - } + executeContent(transitions); } if (defaultHistoryContent.find(ATTR(s, "id")) != defaultHistoryContent.end()) { - executeContent(defaultHistoryContent[ATTR(s, "id")]); + executeContent(Element(defaultHistoryContent[ATTR(s, "id")])); } /** @@ -920,7 +920,7 @@ void InterpreterRC::computeEntrySet(const Arabica::XPath::NodeSet& NodeSet& statesForDefaultEntry, std::map > defaultHistoryContent) { for (int i = 0; i < transitions.size(); i++) { - const Node& t = transitions[i]; + Element t(transitions[i]); NodeSet targets = getTargetStates(t); for (int j = 0; j < targets.size(); j++) { @@ -1010,7 +1010,7 @@ void InterpreterRC::addDescendantStatesToEnter(const Arabica::DOM::Node& statesToEnter, Arabica::XPath::NodeSet& statesForDefaultEntry, std::map > defaultHistoryContent) { - if (isHistory(state)) { + if (isHistory(Element(state))) { std::string stateId = ATTR(state, "id"); if (_historyValue.find(stateId) != _historyValue.end()) { const Arabica::XPath::NodeSet& historyValue = _historyValue[stateId]; @@ -1028,7 +1028,7 @@ void InterpreterRC::addDescendantStatesToEnter(const Arabica::DOM::Node targets = getTargetStates(transitions[i]); + NodeSet targets = getTargetStates(Element(transitions[i])); for (int j = 0; j < targets.size(); j++) { const Node& s = targets[i]; addDescendantStatesToEnter(s,statesToEnter,statesForDefaultEntry, defaultHistoryContent); @@ -1040,15 +1040,15 @@ void InterpreterRC::addDescendantStatesToEnter(const Arabica::DOM::Node(state))) { statesForDefaultEntry.push_back(state); - NodeSet targets = getInitialStates(state); + NodeSet targets = getInitialStates(Element(state)); for (int i = 0; i < targets.size(); i++) { const Node& s = targets[i]; addDescendantStatesToEnter(s,statesToEnter,statesForDefaultEntry, defaultHistoryContent); addAncestorStatesToEnter(s, getParentState(s), statesToEnter, statesForDefaultEntry, defaultHistoryContent); } - } else if(isParallel(state)) { + } else if(isParallel(Element(state))) { // if state is a parallel state, recursively call addStatesToEnter on any of its child // states that don't already have a descendant on statesToEnter. NodeSet childStates = getChildStates(state); @@ -1087,7 +1087,7 @@ void InterpreterRC::addAncestorStatesToEnter(const Arabica::DOM::Node& anc = ancestors[i]; statesToEnter.push_back(anc); - if (isParallel(anc)) { + if (isParallel(Element(anc))) { NodeSet childStates = getChildStates(anc); for (int j = 0; j < childStates.size(); j++) { const Node& child = childStates[j]; @@ -1115,13 +1115,13 @@ function isInFinalState(s): return false */ bool InterpreterRC::isInFinalState(const Arabica::DOM::Node& state) { - if (isCompound(state)) { + if (isCompound(Element(state))) { Arabica::XPath::NodeSet childs = getChildStates(state); for (int i = 0; i < childs.size(); i++) { - if (isFinal(childs[i]) && isMember(childs[i], _configuration)) + if (isFinal(Element(childs[i])) && isMember(childs[i], _configuration)) return true; } - } else if (isParallel(state)) { + } else if (isParallel(Element(state))) { Arabica::XPath::NodeSet childs = getChildStates(state); for (int i = 0; i < childs.size(); i++) { if (!isInFinalState(childs[i])) @@ -1143,7 +1143,7 @@ function getTransitionDomain(t) else: return findLCCA([t.source].append(tstates)) */ -Arabica::DOM::Node InterpreterRC::getTransitionDomain(const Arabica::DOM::Node& transition) { +Arabica::DOM::Node InterpreterRC::getTransitionDomain(const Arabica::DOM::Element& transition) { NodeSet tStates = getTargetStates(transition); Node source = getSourceState(transition); @@ -1156,7 +1156,7 @@ Arabica::DOM::Node InterpreterRC::getTransitionDomain(const Arabica } std::string transitionType = (HAS_ATTR(transition, "type") ? ATTR(transition, "type") : "external"); - if (iequals(transitionType, "internal") && isCompound(source)) { + if (iequals(transitionType, "internal") && isCompound(Element(source))) { for (int i = 0; i < tStates.size(); i++) { const Node& s = tStates[i]; if (!isDescendant(s, source)) @@ -1184,7 +1184,7 @@ Arabica::DOM::Node InterpreterRC::findLCCA(const Arabica::XPath::No // ancestors.push_back(states[0]); // state[0] may already be the ancestor - bug in W3C spec? Arabica::DOM::Node ancestor; for (int i = 0; i < ancestors.size(); i++) { - if (!isCompound(ancestors[i])) + if (!isCompound(Element(ancestors[i]))) continue; for (int j = 0; j < states.size(); j++) { if (!isDescendant(states[j], ancestors[i]) && (states[j] != ancestors[i])) @@ -1215,7 +1215,7 @@ NEXT_ANCESTOR: Arabica::XPath::NodeSet InterpreterRC::getProperAncestors(const Arabica::DOM::Node& state1, const Arabica::DOM::Node& state2) { NodeSet ancestors; - if (!state1 || !isState(state1)) + if (!state1 || !isState(Element(state1))) return ancestors; if (!state2) { @@ -1225,7 +1225,7 @@ Arabica::XPath::NodeSet InterpreterRC::getProperAncestors(const Ara including the element). */ Arabica::DOM::Node parent = state1.getParentNode(); - while(parent && isState(parent)) { + while(parent && isState(Element(parent))) { ancestors.push_back(parent); parent = parent.getParentNode(); } @@ -1245,14 +1245,14 @@ Arabica::XPath::NodeSet InterpreterRC::getProperAncestors(const Ara of state1, up to but not including state2. */ Arabica::DOM::Node parent = state1.getParentNode(); - while(parent && isState(parent) && parent != state2) { + while(parent && isState(Element(parent)) && parent != state2) { ancestors.push_back(parent); parent = parent.getParentNode(); } return ancestors; } -NodeSet InterpreterRC::getTargetStates(const Arabica::DOM::Node& transition) { +NodeSet InterpreterRC::getTargetStates(const Arabica::DOM::Element& transition) { NodeSet targetStates; std::string targetId = ((Arabica::DOM::Element)transition).getAttribute("target"); diff --git a/src/uscxml/interpreter/InterpreterRC.h b/src/uscxml/interpreter/InterpreterRC.h index 2cd2662..9afc2e6 100644 --- a/src/uscxml/interpreter/InterpreterRC.h +++ b/src/uscxml/interpreter/InterpreterRC.h @@ -33,7 +33,7 @@ class InterpreterRC : public InterpreterImpl { Arabica::XPath::NodeSet selectEventlessTransitions(); Arabica::XPath::NodeSet selectTransitions(const std::string& event); - bool isEnabledTransition(const Arabica::DOM::Node& transition, const std::string& event); + bool isEnabledTransition(const Arabica::DOM::Element& transition, const std::string& event); bool hasIntersection(const Arabica::XPath::NodeSet& nodeSet1, const Arabica::XPath::NodeSet& nodeSet2); void enterStates(const Arabica::XPath::NodeSet& enabledTransitions); @@ -52,7 +52,7 @@ class InterpreterRC : public InterpreterImpl { std::map > defaultHistoryContent); Arabica::XPath::NodeSet removeConflictingTransitions(const Arabica::XPath::NodeSet& enabledTransitions); - Arabica::DOM::Node getTransitionDomain(const Arabica::DOM::Node& transition); + Arabica::DOM::Node getTransitionDomain(const Arabica::DOM::Element& transition); void addDescendantStatesToEnter(const Arabica::DOM::Node& state, Arabica::XPath::NodeSet& statesToEnter, @@ -71,7 +71,7 @@ class InterpreterRC : public InterpreterImpl { Arabica::XPath::NodeSet getProperAncestors(const Arabica::DOM::Node& s1, const Arabica::DOM::Node& s2); - Arabica::XPath::NodeSet getTargetStates(const Arabica::DOM::Node& transition); + Arabica::XPath::NodeSet getTargetStates(const Arabica::DOM::Element& transition); #if 0 bool isDescendant(const Arabica::DOM::Node& state1, const Arabica::DOM::Node& state2); diff --git a/src/uscxml/transform/ChartToFSM.cpp b/src/uscxml/transform/ChartToFSM.cpp index fea97d8..cc94434 100644 --- a/src/uscxml/transform/ChartToFSM.cpp +++ b/src/uscxml/transform/ChartToFSM.cpp @@ -182,7 +182,7 @@ InterpreterState FlatteningInterpreter::interpret() { return _state; } -void FlatteningInterpreter::executeContent(const Arabica::DOM::Node& content, bool rethrow) { +void FlatteningInterpreter::executeContent(const Arabica::DOM::Element& content, bool rethrow) { // std::cout << content << std::endl; GlobalTransition::Action action; @@ -199,19 +199,6 @@ void FlatteningInterpreter::executeContent(const Arabica::DOM::Node _currGlobalTransition->actions.push_back(action); } -void FlatteningInterpreter::executeContent(const Arabica::DOM::NodeList& content, bool rethrow) { - for (int i = 0; i < content.getLength(); i++) { - executeContent(content.item(i)); - } - assert(false); -} - -void FlatteningInterpreter::executeContent(const Arabica::XPath::NodeSet& content, bool rethrow) { - for (int i = 0; i < content.size(); i++) { - executeContent(content[i]); - } -} - void FlatteningInterpreter::invoke(const Arabica::DOM::Node& element) { GlobalTransition::Action action; action.invoke = element; @@ -226,10 +213,8 @@ void FlatteningInterpreter::cancelInvoke(const Arabica::DOM::Node& _currGlobalTransition->uninvoke.push_back(element); } -void FlatteningInterpreter::internalDoneSend(const Arabica::DOM::Node& state) { +void FlatteningInterpreter::internalDoneSend(const Arabica::DOM::Element& state) { - if (!isState(state)) - return; Arabica::DOM::Element stateElem = (Arabica::DOM::Element)state; // if (parentIsScxmlState(state)) @@ -906,7 +891,7 @@ GlobalState::GlobalState(const Arabica::XPath::NodeSet& activeState std::ostringstream idSS; idSS << "active-"; for (int i = 0; i < activeStates.size(); i++) { - if (!InterpreterImpl::isFinal(activeStates[i])) + if (!InterpreterImpl::isFinal(Element(activeStates[i]))) isFinal = false; idSS << ATTR(activeStates[i], "id") << "-"; } diff --git a/src/uscxml/transform/ChartToFSM.h b/src/uscxml/transform/ChartToFSM.h index 07531e2..dba8d4d 100644 --- a/src/uscxml/transform/ChartToFSM.h +++ b/src/uscxml/transform/ChartToFSM.h @@ -109,9 +109,7 @@ public: protected: // gather executable content per microstep - void executeContent(const Arabica::DOM::Node& content, bool rethrow = false); - void executeContent(const Arabica::DOM::NodeList& content, bool rethrow = false); - void executeContent(const Arabica::XPath::NodeSet& content, bool rethrow = false); + void executeContent(const Arabica::DOM::Element& content, bool rethrow = false); // invoke and uninvoke virtual void invoke(const Arabica::DOM::Node& element); @@ -119,7 +117,7 @@ protected: // override to do nothing void send(const Arabica::DOM::Node& element) {} - void internalDoneSend(const Arabica::DOM::Node& state); + void internalDoneSend(const Arabica::DOM::Element& state); // InterpreterMonitor virtual void beforeMicroStep(Interpreter interpreter); diff --git a/src/uscxml/transform/FSMToPromela.cpp b/src/uscxml/transform/FSMToPromela.cpp index d72dccb..3607071 100644 --- a/src/uscxml/transform/FSMToPromela.cpp +++ b/src/uscxml/transform/FSMToPromela.cpp @@ -317,7 +317,7 @@ void FSMToPromela::writeExecutableContent(std::ostream& stream, const Arabica::D } stream << padding << "}" << std::endl; - if (isFinal(newState)) { + if (isFinal(Element(newState))) { stream << padding << "goto terminate;" << std::endl; } else { stream << padding << "goto nextStep;" << std::endl; -- cgit v0.12
Test#StatusDescriptionComment
- 326 / - 329 - + 326 / + 329 + Failed for v8 "test that _ioprocessors stays bound till the session ends" / "test that none of the system variables can be modified" The v8 implementation will return a new _ioprocessor object for each access.