diff options
author | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2014-08-03 12:10:57 (GMT) |
---|---|---|
committer | Stefan Radomski <radomski@tk.informatik.tu-darmstadt.de> | 2014-08-03 12:10:57 (GMT) |
commit | 6e1a4a67d5b17e92135cd3f5daf51bf044d76e40 (patch) | |
tree | 63d8de9a5ba99dbcd16c6bd867241a7e7466c559 | |
parent | 37f8735a66aadd0e3f019f5edbb9356cf4a7b974 (diff) | |
download | uscxml-6e1a4a67d5b17e92135cd3f5daf51bf044d76e40.zip uscxml-6e1a4a67d5b17e92135cd3f5daf51bf044d76e40.tar.gz uscxml-6e1a4a67d5b17e92135cd3f5daf51bf044d76e40.tar.bz2 |
Got rid of more dynamic_casts
49 files changed, 503 insertions, 380 deletions
diff --git a/apps/uscxml-browser.cpp b/apps/uscxml-browser.cpp index 4e21ec6..1b9df1b 100644 --- a/apps/uscxml-browser.cpp +++ b/apps/uscxml-browser.cpp @@ -39,7 +39,7 @@ class VerboseMonitor : public uscxml::InterpreterMonitor { std::string seperator; std::cout << "Config: {"; for (int i = 0; i < config.size(); i++) { - std::cout << seperator << ATTR(config[i], "id"); + std::cout << seperator << ATTR_CAST(config[i], "id"); seperator = ", "; } std::cout << "}" << std::endl; diff --git a/apps/uscxml-transform.cpp b/apps/uscxml-transform.cpp index fc33617..401ba87 100644 --- a/apps/uscxml-transform.cpp +++ b/apps/uscxml-transform.cpp @@ -40,7 +40,7 @@ class VerboseMonitor : public uscxml::InterpreterMonitor { std::string seperator; std::cerr << "Config: {"; for (int i = 0; i < config.size(); i++) { - std::cerr << seperator << ATTR(config[i], "id"); + std::cerr << seperator << ATTR_CAST(config[i], "id"); seperator = ", "; } std::cerr << "}" << std::endl; diff --git a/src/bindings/swig/wrapped/WrappedDataModel.h b/src/bindings/swig/wrapped/WrappedDataModel.h index 481f0ea..e988dc0 100644 --- a/src/bindings/swig/wrapped/WrappedDataModel.h +++ b/src/bindings/swig/wrapped/WrappedDataModel.h @@ -89,7 +89,7 @@ public: return evalAsBool("", expr); } - virtual bool evalAsBool(const Arabica::DOM::Node<std::string>& node, const std::string& expr) { + virtual bool evalAsBool(const Arabica::DOM::Element<std::string>& node, const std::string& expr) { std::ostringstream ssNode; ssNode << node; return evalAsBool(ssNode.str(), expr); diff --git a/src/bindings/swig/wrapped/WrappedExecutableContent.h b/src/bindings/swig/wrapped/WrappedExecutableContent.h index b1ce4f9..d194f0d 100644 --- a/src/bindings/swig/wrapped/WrappedExecutableContent.h +++ b/src/bindings/swig/wrapped/WrappedExecutableContent.h @@ -55,13 +55,13 @@ public: return "http://www.w3.org/2005/07/scxml"; } - virtual void enterElement(const Arabica::DOM::Node<std::string>& node) { + virtual void enterElement(const Arabica::DOM::Element<std::string>& node) { std::ostringstream ssElement; ssElement << node; enterElement(ssElement.str()); } - virtual void exitElement(const Arabica::DOM::Node<std::string>& node) { + virtual void exitElement(const Arabica::DOM::Element<std::string>& node) { std::ostringstream ssElement; ssElement << node; exitElement(ssElement.str()); diff --git a/src/bindings/swig/wrapped/WrappedInterpreterMonitor.h b/src/bindings/swig/wrapped/WrappedInterpreterMonitor.h index 0aac660..60fa5a5 100644 --- a/src/bindings/swig/wrapped/WrappedInterpreterMonitor.h +++ b/src/bindings/swig/wrapped/WrappedInterpreterMonitor.h @@ -129,10 +129,10 @@ public: std::list<std::string> targets; for (int i = 0; i < targetStates.size(); i++) { - targets.push_back(ATTR(targetStates[i], "id")); + targets.push_back(ATTR_CAST(targetStates[i], "id")); } - beforeTakingTransition(interpreter, DOMUtils::xPathForNode(transition), ATTR(sourceState, "id"), targets, ss.str(), moreComing); + beforeTakingTransition(interpreter, DOMUtils::xPathForNode(transition), ATTR_CAST(sourceState, "id"), targets, ss.str(), moreComing); } virtual void beforeTakingTransition(Interpreter interpreter, const std::string& xpath, @@ -152,10 +152,10 @@ public: std::list<std::string> targets; for (int i = 0; i < targetStates.size(); i++) { - targets.push_back(ATTR(targetStates[i], "id")); + targets.push_back(ATTR_CAST(targetStates[i], "id")); } - afterTakingTransition(interpreter, DOMUtils::xPathForNode(transition), ATTR(sourceState, "id"), targets, ss.str(), moreComing); + afterTakingTransition(interpreter, DOMUtils::xPathForNode(transition), ATTR_CAST(sourceState, "id"), targets, ss.str(), moreComing); } virtual void afterTakingTransition(Interpreter interpreter, const std::string& xpath, diff --git a/src/uscxml/DOMUtils.cpp b/src/uscxml/DOMUtils.cpp index 0a6e350..aebe943 100644 --- a/src/uscxml/DOMUtils.cpp +++ b/src/uscxml/DOMUtils.cpp @@ -48,12 +48,13 @@ std::string DOMUtils::xPathForNode(const Arabica::DOM::Node<std::string>& node, while(curr) { switch (curr.getNodeType()) { case Arabica::DOM::Node_base::ELEMENT_NODE: { - if (HAS_ATTR(curr, "id")) { + Arabica::DOM::Element<std::string> elem = Arabica::DOM::Element<std::string>(curr); + if (HAS_ATTR(elem, "id")) { // we assume ids to be unique and return immediately if (ns == "*") { - xPath.insert(0, "//*[local-name() = \"" + TAGNAME(curr) + "\"][@id=\"" + ATTR(curr, "id") + "\"]"); + xPath.insert(0, "//*[local-name() = \"" + TAGNAME(elem) + "\"][@id=\"" + ATTR(elem, "id") + "\"]"); } else { - xPath.insert(0, "//" + nsPrefix + TAGNAME(curr) + "[@id=\"" + ATTR(curr, "id") + "\"]"); + xPath.insert(0, "//" + nsPrefix + TAGNAME(elem) + "[@id=\"" + ATTR(elem, "id") + "\"]"); } return xPath; } else { @@ -62,16 +63,16 @@ std::string DOMUtils::xPathForNode(const Arabica::DOM::Node<std::string>& node, int index = 1; // xpath indices start at 1 while(sibling) { if (sibling.getNodeType() == Arabica::DOM::Node_base::ELEMENT_NODE) { - if (iequals(TAGNAME(sibling), TAGNAME(curr))) { + if (iequals(TAGNAME_CAST(sibling), TAGNAME(elem))) { index++; } } sibling = sibling.getPreviousSibling(); } if (ns == "*") { - xPath.insert(0, "/*[local-name() = \"" + TAGNAME(curr) + "\"][" + toStr(index) + "]"); + xPath.insert(0, "/*[local-name() = \"" + TAGNAME(elem) + "\"][" + toStr(index) + "]"); } else { - xPath.insert(0, "/" + nsPrefix + TAGNAME(curr) + "[" + toStr(index) + "]"); + xPath.insert(0, "/" + nsPrefix + TAGNAME(elem) + "[" + toStr(index) + "]"); } } break; diff --git a/src/uscxml/DOMUtils.h b/src/uscxml/DOMUtils.h index 7748f48..7fd291c 100644 --- a/src/uscxml/DOMUtils.h +++ b/src/uscxml/DOMUtils.h @@ -26,11 +26,17 @@ #include <SAX/helpers/CatchErrorHandler.hpp> #include <DOM/io/Stream.hpp> // operator<< for nodes -#define TAGNAME(elem) ((Arabica::DOM::Element<std::string>)elem).getTagName() -#define LOCALNAME(elem) ((Arabica::DOM::Element<std::string>)elem).getLocalName() -#define ATTR(elem, attr) ((Arabica::DOM::Element<std::string>)elem).getAttribute(attr) -#define ATTR_NODE(elem, attr) ((Arabica::DOM::Element<std::string>)elem).getAttributeNode(attr) -#define HAS_ATTR(elem, attr) ((Arabica::DOM::Element<std::string>)elem).hasAttribute(attr) +#define TAGNAME_CAST(elem) ((Arabica::DOM::Element<std::string>)elem).getTagName() +#define LOCALNAME_CAST(elem) ((Arabica::DOM::Element<std::string>)elem).getLocalName() +#define ATTR_CAST(elem, attr) ((Arabica::DOM::Element<std::string>)elem).getAttribute(attr) +#define ATTR_NODE_CAST(elem, attr) ((Arabica::DOM::Element<std::string>)elem).getAttributeNode(attr) +#define HAS_ATTR_CAST(elem, attr) ((Arabica::DOM::Element<std::string>)elem).hasAttribute(attr) + +#define TAGNAME(elem) elem.getTagName() +#define LOCALNAME(elem) elem.getLocalName() +#define ATTR(elem, attr) elem.getAttribute(attr) +#define ATTR_NODE(elem, attr) elem.getAttributeNode(attr) +#define HAS_ATTR(elem, attr) elem.hasAttribute(attr) namespace uscxml { diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp index c202246..ba20981 100644 --- a/src/uscxml/Interpreter.cpp +++ b/src/uscxml/Interpreter.cpp @@ -902,14 +902,14 @@ void InterpreterImpl::internalDoneSend(const Arabica::DOM::Element<std::string>& Arabica::XPath::NodeSet<std::string> doneDatas = filterChildElements(_nsInfo.xmlNSPrefix + "donedata", state); if (doneDatas.size() > 0) { // only process first donedata element - Arabica::DOM::Node<std::string> doneData = doneDatas[0]; + Arabica::DOM::Element<std::string> doneData = Element<std::string>(doneDatas[0]); processParamChilds(doneData, event.params); Arabica::XPath::NodeSet<std::string> contents = filterChildElements(_nsInfo.xmlNSPrefix + "content", doneDatas[0]); if (contents.size() > 1) LOG(ERROR) << "Only a single content element is allowed for send elements - using first one"; if (contents.size() > 0) { std::string expr; - processContentElement(contents[0], event.dom, event.content, expr); + processContentElement(Element<std::string>(contents[0]), event.dom, event.content, expr); if (expr.length() > 0) { try { event.content =_dataModel.evalAsString(expr); @@ -922,12 +922,12 @@ void InterpreterImpl::internalDoneSend(const Arabica::DOM::Element<std::string>& } } - event.name = "done.state." + ATTR(state.getParentNode(), "id"); // parent?! + event.name = "done.state." + ATTR_CAST(state.getParentNode(), "id"); // parent?! receiveInternal(event); } -void InterpreterImpl::processContentElement(const Arabica::DOM::Node<std::string>& content, +void InterpreterImpl::processContentElement(const Arabica::DOM::Element<std::string>& content, Arabica::DOM::Node<std::string>& dom, std::string& text, std::string& expr) { @@ -940,7 +940,7 @@ void InterpreterImpl::processContentElement(const Arabica::DOM::Node<std::string } } -void InterpreterImpl::processDOMorText(const Arabica::DOM::Node<std::string>& element, +void InterpreterImpl::processDOMorText(const Arabica::DOM::Element<std::string>& element, Arabica::DOM::Node<std::string>& dom, std::string& text) { // do we need to download? @@ -1036,24 +1036,25 @@ void InterpreterImpl::processDOMorText(const Arabica::DOM::Node<std::string>& el } } -void InterpreterImpl::processParamChilds(const Arabica::DOM::Node<std::string>& element, std::multimap<std::string, Data>& params) { +void InterpreterImpl::processParamChilds(const Arabica::DOM::Element<std::string>& element, std::multimap<std::string, Data>& params) { NodeSet<std::string> paramElems = filterChildElements(_nsInfo.xmlNSPrefix + "param", element); for (int i = 0; i < paramElems.size(); i++) { try { - if (!HAS_ATTR(paramElems[i], "name")) { + Element<std::string> paramElem = Element<std::string>(paramElems[i]); + if (!HAS_ATTR(paramElem, "name")) { LOG(ERROR) << "param element is missing name attribute"; continue; } Data paramValue; - if (HAS_ATTR(paramElems[i], "expr")) { - paramValue = _dataModel.getStringAsData(ATTR(paramElems[i], "expr")); - } else if(HAS_ATTR(paramElems[i], "location")) { - paramValue = _dataModel.getStringAsData(ATTR(paramElems[i], "location")); + if (HAS_ATTR(paramElem, "expr")) { + paramValue = _dataModel.getStringAsData(ATTR(paramElem, "expr")); + } else if(HAS_ATTR(paramElem, "location")) { + paramValue = _dataModel.getStringAsData(ATTR(paramElem, "location")); } else { LOG(ERROR) << "param element is missing expr or location or no datamodel is specified"; continue; } - std::string paramKey = ATTR(paramElems[i], "name"); + std::string paramKey = ATTR(paramElem, "name"); params.insert(std::make_pair(paramKey, paramValue)); } catch(Event e) { LOG(ERROR) << "Syntax error while processing params " << DOMUtils::xPathForNode(paramElems[i]) << ":" << std::endl << e << std::endl; @@ -1069,7 +1070,7 @@ void InterpreterImpl::processParamChilds(const Arabica::DOM::Node<std::string>& } } -void InterpreterImpl::send(const Arabica::DOM::Node<std::string>& element) { +void InterpreterImpl::send(const Arabica::DOM::Element<std::string>& element) { SendRequest sendReq; // test 331 sendReq.Event::eventType = Event::EXTERNAL; @@ -1204,7 +1205,7 @@ void InterpreterImpl::send(const Arabica::DOM::Node<std::string>& element) { LOG(ERROR) << "Only a single content element is allowed for send elements " << DOMUtils::xPathForNode(element) << " - using first one"; if (contents.size() > 0) { std::string expr; - processContentElement(contents[0], sendReq.dom, sendReq.content, expr); + processContentElement(Element<std::string>(contents[0]), sendReq.dom, sendReq.content, expr); if (expr.length() > 0) { try { sendReq.data = _dataModel.getStringAsData(expr); @@ -1277,7 +1278,7 @@ void InterpreterImpl::delayedSend(void* userdata, std::string eventName) { INSTANCE->_sendIds.erase(sendReq.sendid); } -void InterpreterImpl::invoke(const Arabica::DOM::Node<std::string>& element) { +void InterpreterImpl::invoke(const Arabica::DOM::Element<std::string>& element) { InvokeRequest invokeReq; invokeReq.Event::eventType = Event::EXTERNAL; try { @@ -1354,7 +1355,7 @@ void InterpreterImpl::invoke(const Arabica::DOM::Node<std::string>& element) { LOG(ERROR) << "Only a single content element is allowed for send elements - using first one"; if (contents.size() > 0) { std::string expr; - processContentElement(contents[0], invokeReq.dom, invokeReq.content, expr); + processContentElement(Element<std::string>(contents[0]), invokeReq.dom, invokeReq.content, expr); if (expr.length() > 0) { try { invokeReq.data =_dataModel.getStringAsData(expr); @@ -1444,7 +1445,7 @@ void InterpreterImpl::invoke(const Arabica::DOM::Node<std::string>& element) { } } -void InterpreterImpl::cancelInvoke(const Arabica::DOM::Node<std::string>& element) { +void InterpreterImpl::cancelInvoke(const Arabica::DOM::Element<std::string>& element) { std::string invokeId; if (HAS_ATTR(element, "idlocation")) { invokeId = _dataModel.evalAsString(ATTR(element, "idlocation")); @@ -1581,7 +1582,7 @@ bool InterpreterImpl::nameMatch(const std::string& transitionEvent, const std::s bool InterpreterImpl::hasConditionMatch(const Arabica::DOM::Element<std::string>& conditional) { if (HAS_ATTR(conditional, "cond") && ATTR(conditional, "cond").length() > 0) { try { - return _dataModel.evalAsBool(ATTR_NODE(conditional, "cond"), ATTR(conditional, "cond")); + return _dataModel.evalAsBool(conditional, ATTR(conditional, "cond")); } catch (Event e) { LOG(ERROR) << "Syntax error in cond attribute of " << TAGNAME(conditional) << " element " << DOMUtils::xPathForNode(conditional) << ":" << std::endl << e << std::endl; e.name = "error.execution"; @@ -1618,8 +1619,6 @@ void InterpreterImpl::executeContent(const NodeSet<std::string>& content, bool r } void InterpreterImpl::executeContent(const Arabica::DOM::Element<std::string>& content, bool rethrow) { - if (content.getNodeType() != Node_base::ELEMENT_NODE) - return; if (iequals(TAGNAME(content), _nsInfo.xmlNSPrefix + "onentry") || iequals(TAGNAME(content), _nsInfo.xmlNSPrefix + "onexit") || @@ -1628,9 +1627,10 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Element<std::string>& c // --- CONVENIENCE LOOP -------------------------- NodeList<std::string> executable = content.getChildNodes(); for (int i = 0; i < executable.getLength(); i++) { - if (executable.item(i).getNodeType() != Node_base::ELEMENT_NODE) + const Arabica::DOM::Node<std::string>& childNode = executable.item(i); + if (childNode.getNodeType() != Node_base::ELEMENT_NODE) continue; - executeContent(Element<std::string>(executable.item(i)), rethrow); + executeContent(Element<std::string>(childNode), rethrow); } return; } @@ -1656,7 +1656,7 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Element<std::string>& c LOG(ERROR) << "Only a single content element is allowed for raise elements " << DOMUtils::xPathForNode(content) << " - using first one"; if (contents.size() > 0) { std::string expr; - processContentElement(contents[0], raised.dom, raised.content, expr); + processContentElement(Element<std::string>(contents[0]), raised.dom, raised.content, expr); if (expr.length() > 0) { try { raised.data = _dataModel.getStringAsData(expr); @@ -1704,8 +1704,8 @@ void InterpreterImpl::executeContent(const Arabica::DOM::Element<std::string>& c if (childs.item(i).getNodeType() != Node_base::ELEMENT_NODE) continue; Element<std::string> childElem(childs.item(i)); - if (iequals(TAGNAME(childs.item(i)), _nsInfo.xmlNSPrefix + "elseif") || - iequals(TAGNAME(childs.item(i)), _nsInfo.xmlNSPrefix + "else")) { + if (iequals(TAGNAME_CAST(childs.item(i)), _nsInfo.xmlNSPrefix + "elseif") || + iequals(TAGNAME_CAST(childs.item(i)), _nsInfo.xmlNSPrefix + "else")) { if (blockIsTrue) { // last block was true, break here break; @@ -1989,7 +1989,7 @@ Arabica::DOM::Node<std::string> InterpreterImpl::getAncestorElement(const Arabic Arabica::DOM::Node<std::string> parent = node.getParentNode(); while(parent) { if (parent.getNodeType() == Node_base::ELEMENT_NODE && - iequals(TAGNAME(parent), tagName)) { + iequals(TAGNAME_CAST(parent), tagName)) { return parent; } parent = parent.getParentNode(); @@ -2106,7 +2106,7 @@ Arabica::XPath::NodeSet<std::string> InterpreterImpl::getAllStates() { } Arabica::DOM::Node<std::string> InterpreterImpl::getSourceState(const Arabica::DOM::Element<std::string>& transition) { - if (iequals(TAGNAME(transition.getParentNode()), _nsInfo.xmlNSPrefix + "initial")) + if (iequals(TAGNAME_CAST(transition.getParentNode()), _nsInfo.xmlNSPrefix + "initial")) return transition.getParentNode().getParentNode(); return transition.getParentNode(); } @@ -2137,7 +2137,7 @@ Arabica::XPath::NodeSet<std::string> InterpreterImpl::getInitialStates(Arabica:: // initial element as child - but not the implicit generated one NodeSet<std::string> initElems = filterChildElements(_nsInfo.xmlNSPrefix + "initial", state); - if(initElems.size() == 1 && !iequals(ATTR(initElems[0], "generated"), "true")) { + if(initElems.size() == 1 && !iequals(ATTR_CAST(initElems[0], "generated"), "true")) { NodeSet<std::string> initTrans = filterChildElements(_nsInfo.xmlNSPrefix + "transition", initElems[0]); return getTargetStates(Element<std::string>(initTrans[0])); } @@ -2159,6 +2159,9 @@ Arabica::XPath::NodeSet<std::string> InterpreterImpl::getInitialStates(Arabica:: } NodeSet<std::string> InterpreterImpl::getTargetStates(const Arabica::DOM::Element<std::string>& transition) { + if (_cachedTargets.find(transition) != _cachedTargets.end()) + return _cachedTargets[transition]; + NodeSet<std::string> targetStates; assert(boost::ends_with(TAGNAME(transition), "transition")); @@ -2169,10 +2172,12 @@ NodeSet<std::string> InterpreterImpl::getTargetStates(const Arabica::DOM::Elemen for (int i = 0; i < childs.getLength(); 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<std::string>(childs.item(i)))); + Element<std::string> childElem = Element<std::string>(childs.item(i)); + if (iequals(TAGNAME(childElem), _nsInfo.xmlNSPrefix + "transition")) { + targetStates.push_back(getTargetStates(childElem)); } } + _cachedTargets[transition] = targetStates; return targetStates; } @@ -2181,10 +2186,11 @@ NodeSet<std::string> InterpreterImpl::getTargetStates(const Arabica::DOM::Elemen for (std::list<std::string>::const_iterator targetIter = targetIds.begin(); targetIter != targetIds.end(); targetIter++) { Arabica::DOM::Node<std::string> state = getState(*targetIter); if (state) { - assert(HAS_ATTR(state, "id")); + assert(HAS_ATTR_CAST(state, "id")); targetStates.push_back(state); } } + _cachedTargets[transition] = targetStates; return targetStates; } @@ -2203,7 +2209,7 @@ std::list<std::string> InterpreterImpl::tokenizeIdRefs(const std::string& idRefs size_t start = 0; for (int i = 0; i < idRefs.size(); i++) { if (isspace(idRefs[i])) { - if (i > 0 && start < i - 1) { + if (i > 0 && start < i) { ids.push_back(idRefs.substr(start, i - start)); } while(isspace(idRefs[++i])); // skip whitespaces @@ -2236,8 +2242,31 @@ std::list<std::string> InterpreterImpl::tokenizeIdRefs(const std::string& idRefs } std::string InterpreterImpl::spaceNormalize(const std::string& text) { - std::istringstream iss(text); std::stringstream content; + +#if 1 + // 195ms with test-performance-events.scml + std::string seperator; + + size_t start = 0; + for (int i = 0; i < text.size(); i++) { + if (isspace(text[i])) { + if (i > 0 && start < i) { + content << seperator << text.substr(start, i - start); + seperator = " "; + } + while(isspace(text[++i])); // skip whitespaces + start = i; + } else if (i + 1 == text.size()) { + content << seperator << text.substr(start, i + 1 - start); + } + } +// std::cout << ">>" << content.str() << "<<" << std::endl; + +#else + +// 291ms with test-performance-events.scml + std::istringstream iss(text); std::string seperator; do { std::string token; @@ -2247,6 +2276,8 @@ std::string InterpreterImpl::spaceNormalize(const std::string& text) { seperator = " "; } } while (iss); + +#endif return content.str(); } @@ -2270,7 +2301,7 @@ NodeSet<std::string> InterpreterImpl::filterChildElements(const std::string& tag 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)) { + if(iequals(TAGNAME_CAST(childs.item(i)), tagName)) { filteredChildElems.push_back(childs.item(i)); } if (recurse) { @@ -2308,6 +2339,11 @@ NodeSet<std::string> InterpreterImpl::filterChildType(const Node_base::Type type NodeSet<std::string> InterpreterImpl::getProperAncestors(const Arabica::DOM::Node<std::string>& s1, const Arabica::DOM::Node<std::string>& s2) { + + std::pair<Arabica::DOM::Node<std::string>, Arabica::DOM::Node<std::string> > ancPair = std::make_pair(s1, s2); + if (_cachedProperAncestors.find(ancPair) != _cachedProperAncestors.end()) + return _cachedProperAncestors[ancPair]; + NodeSet<std::string> ancestors; if (isState(Element<std::string>(s1))) { Arabica::DOM::Node<std::string> node = s1; @@ -2329,6 +2365,7 @@ NodeSet<std::string> InterpreterImpl::getProperAncestors(const Arabica::DOM::Nod ancestors.push_back(node); } } + _cachedProperAncestors[ancPair] = ancestors; return ancestors; } @@ -2433,6 +2470,18 @@ bool InterpreterImpl::isAtomic(const Arabica::DOM::Element<std::string>& state) if (iequals("parallel", LOCALNAME(state))) return false; +#if 0 + Arabica::DOM::Node<std::string> child = state.getFirstChild(); + while(child) { + if (child.getNodeType() == Node_base::ELEMENT_NODE) { + if (isState(Element<std::string>(child))) + return false; + } + child = child.getNextSibling(); + } + +#else + Arabica::DOM::NodeList<std::string> childs = state.getChildNodes(); for (unsigned int i = 0; i < childs.getLength(); i++) { if (childs.item(i).getNodeType() != Node_base::ELEMENT_NODE) @@ -2441,6 +2490,8 @@ bool InterpreterImpl::isAtomic(const Arabica::DOM::Element<std::string>& state) if (isState(Element<std::string>(childs.item(i)))) return false; } +#endif + return true; } @@ -2665,9 +2716,9 @@ bool InterpreterImpl::isLegalConfiguration(const NodeSet<std::string>& config) { bool InterpreterImpl::isInState(const std::string& stateId) { if (HAS_ATTR(_scxml, "flat") && DOMUtils::attributeIsTrue(ATTR(_scxml, "flat"))) { // extension for flattened SCXML documents - if (_configuration.size() > 0 && HAS_ATTR(_configuration[0], "id")) { + if (_configuration.size() > 0 && HAS_ATTR_CAST(_configuration[0], "id")) { // all states are encoded in the current statename - std::string encStateList = ATTR(_configuration[0], "id"); + std::string encStateList = ATTR_CAST(_configuration[0], "id"); size_t startActive = encStateList.find_first_of("-"); size_t endActive = encStateList.find_first_of(";"); encStateList = encStateList.substr(startActive, endActive - startActive); @@ -2685,8 +2736,8 @@ bool InterpreterImpl::isInState(const std::string& stateId) { } else { for (int i = 0; i < _configuration.size(); i++) { - if (HAS_ATTR(_configuration[i], "id") && - iequals(ATTR(_configuration[i], "id"), stateId)) { + if (HAS_ATTR_CAST(_configuration[i], "id") && + iequals(ATTR_CAST(_configuration[i], "id"), stateId)) { return true; } } @@ -2694,17 +2745,27 @@ bool InterpreterImpl::isInState(const std::string& stateId) { return false; } -void InterpreterImpl::DOMEventListener::handleEvent(Arabica::DOM::Events::Event<std::string>& event) { - // remove modified states from cache - if (event.getType().compare("DOMAttrModified") == 0) // we do not care about attributes +void InterpreterImpl::handleDOMEvent(Arabica::DOM::Events::Event<std::string>& event) { + // clear targets + _cachedTargets.clear(); + + if (event.getType().compare("DOMAttrModified") == 0) // we do not care about other attributes return; + + // remove modified states from cache Node<std::string> target = Arabica::DOM::Node<std::string>(event.getTarget()); - NodeSet<std::string> childs = InterpreterImpl::filterChildElements(_interpreter->_nsInfo.xmlNSPrefix + "state", target); + NodeSet<std::string> childs = InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "state", target); for (int i = 0; i < childs.size(); i++) { - if (HAS_ATTR(childs[i], "id")) { - _interpreter->_cachedStates.erase(ATTR(childs[i], "id")); + if (HAS_ATTR_CAST(childs[i], "id")) { + _cachedStates.erase(ATTR_CAST(childs[i], "id")); } } + // it's more stress to search through all pairs, just have them recalculated + _cachedProperAncestors.clear(); +} + +void InterpreterImpl::DOMEventListener::handleEvent(Arabica::DOM::Events::Event<std::string>& event) { + _interpreter->handleDOMEvent(event); } std::ostream& operator<< (std::ostream& os, const InterpreterState& interpreterState) { diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h index 3cd6016..c3acc98 100644 --- a/src/uscxml/Interpreter.h +++ b/src/uscxml/Interpreter.h @@ -435,6 +435,8 @@ public: Arabica::DOM::Node<std::string> findLCCA(const Arabica::XPath::NodeSet<std::string>& states); virtual Arabica::XPath::NodeSet<std::string> getProperAncestors(const Arabica::DOM::Node<std::string>& s1, const Arabica::DOM::Node<std::string>& s2); + virtual void handleDOMEvent(Arabica::DOM::Events::Event<std::string>& event); + protected: static void run(void*); // static method for thread to run @@ -512,19 +514,19 @@ protected: virtual void executeContent(const Arabica::DOM::NodeList<std::string>& content, bool rethrow = false); virtual void executeContent(const Arabica::XPath::NodeSet<std::string>& content, bool rethrow = false); - void processContentElement(const Arabica::DOM::Node<std::string>& element, + void processContentElement(const Arabica::DOM::Element<std::string>& element, Arabica::DOM::Node<std::string>& dom, std::string& text, std::string& expr); - void processParamChilds(const Arabica::DOM::Node<std::string>& element, + void processParamChilds(const Arabica::DOM::Element<std::string>& element, std::multimap<std::string, Data>& params); - void processDOMorText(const Arabica::DOM::Node<std::string>& element, + void processDOMorText(const Arabica::DOM::Element<std::string>& element, Arabica::DOM::Node<std::string>& dom, std::string& text); - virtual void send(const Arabica::DOM::Node<std::string>& element); - virtual void invoke(const Arabica::DOM::Node<std::string>& element); - virtual void cancelInvoke(const Arabica::DOM::Node<std::string>& element); + virtual void send(const Arabica::DOM::Element<std::string>& element); + virtual void invoke(const Arabica::DOM::Element<std::string>& element); + virtual void cancelInvoke(const Arabica::DOM::Element<std::string>& element); virtual void internalDoneSend(const Arabica::DOM::Element<std::string>& state); static void delayedSend(void* userdata, std::string eventName); void returnDoneEvent(const Arabica::DOM::Node<std::string>& state); @@ -540,7 +542,8 @@ protected: std::map<std::string, Invoker> _invokers; std::map<Arabica::DOM::Node<std::string>, ExecutableContent> _executableContent; - /// TODO: We need to adapt them when the DOM is operated upon + std::map<std::pair<Arabica::DOM::Node<std::string>, Arabica::DOM::Node<std::string> >, Arabica::XPath::NodeSet<std::string> > _cachedProperAncestors; + std::map<Arabica::DOM::Element<std::string>, Arabica::XPath::NodeSet<std::string> > _cachedTargets; std::map<std::string, Arabica::DOM::Element<std::string> > _cachedStates; std::map<std::string, URL> _cachedURLs; diff --git a/src/uscxml/debug/SCXMLDotWriter.cpp b/src/uscxml/debug/SCXMLDotWriter.cpp index e833a10..be053d7 100644 --- a/src/uscxml/debug/SCXMLDotWriter.cpp +++ b/src/uscxml/debug/SCXMLDotWriter.cpp @@ -401,7 +401,7 @@ void SCXMLDotWriter::writeStateElement(std::ostream& os, const Element<std::stri // write history states NodeSet<std::string> histories = InterpreterImpl::filterChildElements(_xmlNSPrefix + "history", stateElem); for (int i = 0; i < histories.size(); i++) { - os << " <tr><td port=\"" << ATTR(histories[i], "id") << "\" balign=\"left\" colspan=\"" << (nrOutPorts == 0 ? 1 : 2) << "\"><b>history: </b>" << ATTR(histories[i], "id") << "</td></tr>" << std::endl; + os << " <tr><td port=\"" << ATTR_CAST(histories[i], "id") << "\" balign=\"left\" colspan=\"" << (nrOutPorts == 0 ? 1 : 2) << "\"><b>history: </b>" << ATTR_CAST(histories[i], "id") << "</td></tr>" << std::endl; } @@ -548,41 +548,42 @@ std::string SCXMLDotWriter::getDetailedLabel(const Element<std::string>& elem, i for (int i = 0; i < childElems.getLength(); i++) { if (childElems.item(i).getNodeType() != Node_base::ELEMENT_NODE) continue; + Element<std::string> elem = Element<std::string>(childElems.item(i)); - if (InterpreterImpl::isState(Element<std::string>(childElems.item(i))) || - iequals(TAGNAME(childElems.item(i)), "transition") || - iequals(TAGNAME(childElems.item(i)), "initial") || + if (InterpreterImpl::isState(elem) || + iequals(TAGNAME(elem), "transition") || + iequals(TAGNAME(elem), "initial") || false) continue; struct ElemDetails details; - details.name = "<b>" + TAGNAME(childElems.item(i)) + ":</b>"; + details.name = "<b>" + TAGNAME(elem) + ":</b>"; - if (iequals(TAGNAME(childElems.item(i)), "history")) { + if (iequals(TAGNAME(elem), "history")) { continue; } // provide details for special elements here // param --------- - if (iequals(TAGNAME(childElems.item(i)), "param")) { - if (HAS_ATTR(childElems.item(i), "name")) - details.name += " " + ATTR(childElems.item(i), "name") + " = "; - if (HAS_ATTR(childElems.item(i), "expr")) - details.name += ATTR(childElems.item(i), "expr"); - if (HAS_ATTR(childElems.item(i), "location")) - details.name += ATTR(childElems.item(i), "location"); + if (iequals(TAGNAME(elem), "param")) { + if (HAS_ATTR(elem, "name")) + details.name += " " + ATTR(elem, "name") + " = "; + if (HAS_ATTR(elem, "expr")) + details.name += ATTR(elem, "expr"); + if (HAS_ATTR(elem, "location")) + details.name += ATTR(elem, "location"); } // data --------- - if (iequals(TAGNAME(childElems.item(i)), "data")) { - if (HAS_ATTR(childElems.item(i), "id")) - details.name += " " + ATTR(childElems.item(i), "id"); - if (HAS_ATTR(childElems.item(i), "src")) - details.name += ATTR(childElems.item(i), "src"); - if (HAS_ATTR(childElems.item(i), "expr")) - details.name += " = " + ATTR(childElems.item(i), "expr"); - NodeList<std::string > grandChildElems = childElems.item(i).getChildNodes(); + if (iequals(TAGNAME(elem), "data")) { + if (HAS_ATTR(elem, "id")) + details.name += " " + ATTR(elem, "id"); + if (HAS_ATTR(elem, "src")) + details.name += ATTR(elem, "src"); + if (HAS_ATTR(elem, "expr")) + details.name += " = " + ATTR(elem, "expr"); + NodeList<std::string > grandChildElems = elem.getChildNodes(); for (int j = 0; j < grandChildElems.getLength(); j++) { if (grandChildElems.item(j).getNodeType() == Node_base::TEXT_NODE) { details.name += dotEscape(grandChildElems.item(j).getNodeValue()); @@ -591,60 +592,60 @@ std::string SCXMLDotWriter::getDetailedLabel(const Element<std::string>& elem, i } // invoke --------- - if (iequals(TAGNAME(childElems.item(i)), "invoke")) { - if (HAS_ATTR(childElems.item(i), "type")) - details.name += "<br />type = " + ATTR(childElems.item(i), "type"); - if (HAS_ATTR(childElems.item(i), "typeexpr")) - details.name += "<br />type = " + ATTR(childElems.item(i), "typeexpr"); - if (HAS_ATTR(childElems.item(i), "src")) - details.name += "<br />src = " + ATTR(childElems.item(i), "src"); - if (HAS_ATTR(childElems.item(i), "srcexpr")) - details.name += "<br />src = " + ATTR(childElems.item(i), "srcexpr"); - if (HAS_ATTR(childElems.item(i), "id")) - details.name += "<br />id = " + ATTR(childElems.item(i), "id"); - if (HAS_ATTR(childElems.item(i), "idlocation")) - details.name += "<br />id = " + ATTR(childElems.item(i), "idlocation"); + if (iequals(TAGNAME(elem), "invoke")) { + if (HAS_ATTR(elem, "type")) + details.name += "<br />type = " + ATTR(elem, "type"); + if (HAS_ATTR(elem, "typeexpr")) + details.name += "<br />type = " + ATTR(elem, "typeexpr"); + if (HAS_ATTR(elem, "src")) + details.name += "<br />src = " + ATTR(elem, "src"); + if (HAS_ATTR(elem, "srcexpr")) + details.name += "<br />src = " + ATTR(elem, "srcexpr"); + if (HAS_ATTR(elem, "id")) + details.name += "<br />id = " + ATTR(elem, "id"); + if (HAS_ATTR(elem, "idlocation")) + details.name += "<br />id = " + ATTR(elem, "idlocation"); } // send --------- - if (iequals(TAGNAME(childElems.item(i)), "raise")) { - if (HAS_ATTR(childElems.item(i), "event ")) - details.name += "<br />event = " + ATTR(childElems.item(i), "event"); + if (iequals(TAGNAME(elem), "raise")) { + if (HAS_ATTR(elem, "event ")) + details.name += "<br />event = " + ATTR(elem, "event"); } // send --------- - if (iequals(TAGNAME(childElems.item(i)), "send")) { - if (HAS_ATTR(childElems.item(i), "id")) - details.name += "<br />id = " + ATTR(childElems.item(i), "id"); - if (HAS_ATTR(childElems.item(i), "type")) - details.name += "<br />type = " + ATTR(childElems.item(i), "type"); - if (HAS_ATTR(childElems.item(i), "typeexpr")) - details.name += "<br />type = " + ATTR(childElems.item(i), "typeexpr"); - if (HAS_ATTR(childElems.item(i), "event")) - details.name += "<br />event = " + ATTR(childElems.item(i), "event"); - if (HAS_ATTR(childElems.item(i), "eventexpr")) - details.name += "<br />event = " + ATTR(childElems.item(i), "eventexpr"); - if (HAS_ATTR(childElems.item(i), "target")) - details.name += "<br />target = " + ATTR(childElems.item(i), "target"); - if (HAS_ATTR(childElems.item(i), "targetexpr")) - details.name += "<br />target = " + ATTR(childElems.item(i), "targetexpr"); - if (HAS_ATTR(childElems.item(i), "delay")) - details.name += "<br />delay = " + ATTR(childElems.item(i), "delay"); - if (HAS_ATTR(childElems.item(i), "delayexpr")) - details.name += "<br />delay = " + ATTR(childElems.item(i), "delayexpr"); + if (iequals(TAGNAME(elem), "send")) { + if (HAS_ATTR(elem, "id")) + details.name += "<br />id = " + ATTR(elem, "id"); + if (HAS_ATTR(elem, "type")) + details.name += "<br />type = " + ATTR(elem, "type"); + if (HAS_ATTR(elem, "typeexpr")) + details.name += "<br />type = " + ATTR(elem, "typeexpr"); + if (HAS_ATTR(elem, "event")) + details.name += "<br />event = " + ATTR(elem, "event"); + if (HAS_ATTR(elem, "eventexpr")) + details.name += "<br />event = " + ATTR(elem, "eventexpr"); + if (HAS_ATTR(elem, "target")) + details.name += "<br />target = " + ATTR(elem, "target"); + if (HAS_ATTR(elem, "targetexpr")) + details.name += "<br />target = " + ATTR(elem, "targetexpr"); + if (HAS_ATTR(elem, "delay")) + details.name += "<br />delay = " + ATTR(elem, "delay"); + if (HAS_ATTR(elem, "delayexpr")) + details.name += "<br />delay = " + ATTR(elem, "delayexpr"); } // cancel --------- - if (iequals(TAGNAME(childElems.item(i)), "cancel")) { - if (HAS_ATTR(childElems.item(i), "sendid")) - details.name += " " + ATTR(childElems.item(i), "sendid"); + if (iequals(TAGNAME(elem), "cancel")) { + if (HAS_ATTR(elem, "sendid")) + details.name += " " + ATTR(elem, "sendid"); } // script --------- - if (iequals(TAGNAME(childElems.item(i)), "script")) { + if (iequals(TAGNAME(elem), "script")) { details.name += " "; - if (HAS_ATTR(childElems.item(i), "src")) - details.name += ATTR(childElems.item(i), "src"); + if (HAS_ATTR(elem, "src")) + details.name += ATTR(elem, "src"); NodeList<std::string > grandChildElems = childElems.item(i).getChildNodes(); for (int j = 0; j < grandChildElems.getLength(); j++) { if (grandChildElems.item(j).getNodeType() == Node_base::TEXT_NODE) { @@ -654,34 +655,34 @@ std::string SCXMLDotWriter::getDetailedLabel(const Element<std::string>& elem, i } // if --------- - if (iequals(TAGNAME(childElems.item(i)), "if")) { - if (HAS_ATTR(childElems.item(i), "cond")) - details.name += " cond = " + dotEscape(ATTR(childElems.item(i), "cond")); + if (iequals(TAGNAME(elem), "if")) { + if (HAS_ATTR(elem, "cond")) + details.name += " cond = " + dotEscape(ATTR(elem, "cond")); } // elseif --------- - if (iequals(TAGNAME(childElems.item(i)), "elseif")) { - if (HAS_ATTR(childElems.item(i), "cond")) - details.name += " cond = " + dotEscape(ATTR(childElems.item(i), "cond")); + if (iequals(TAGNAME(elem), "elseif")) { + if (HAS_ATTR(elem, "cond")) + details.name += " cond = " + dotEscape(ATTR(elem, "cond")); } // log --------- - if (iequals(TAGNAME(childElems.item(i)), "log")) { + if (iequals(TAGNAME(elem), "log")) { details.name += " "; - if (HAS_ATTR(childElems.item(i), "label")) - details.name += ATTR(childElems.item(i), "label") + " = "; - if (HAS_ATTR(childElems.item(i), "expr")) - details.name += ATTR(childElems.item(i), "expr"); + if (HAS_ATTR(elem, "label")) + details.name += ATTR(elem, "label") + " = "; + if (HAS_ATTR(elem, "expr")) + details.name += ATTR(elem, "expr"); } // foreach --------- - if (iequals(TAGNAME(childElems.item(i)), "foreach")) { - if (HAS_ATTR(childElems.item(i), "item")) - details.name += "<br /> item = " + ATTR(childElems.item(i), "item"); - if (HAS_ATTR(childElems.item(i), "array")) - details.name += "<br /> array = " + ATTR(childElems.item(i), "array"); - if (HAS_ATTR(childElems.item(i), "index")) - details.name += "<br /> index = " + ATTR(childElems.item(i), "index"); + if (iequals(TAGNAME(elem), "foreach")) { + if (HAS_ATTR(elem, "item")) + details.name += "<br /> item = " + ATTR(elem, "item"); + if (HAS_ATTR(elem, "array")) + details.name += "<br /> array = " + ATTR(elem, "array"); + if (HAS_ATTR(elem, "index")) + details.name += "<br /> index = " + ATTR(elem, "index"); } // recurse @@ -814,7 +815,7 @@ std::string SCXMLDotWriter::idForNode(const Node<std::string>& node) { index++; std::stringstream ssElemId; - ssElemId << TAGNAME(tmpParent) << index << "."; + ssElemId << TAGNAME_CAST(tmpParent) << index << "."; elemId = ssElemId.str() + elemId; } while ((tmpParent = tmpParent.getParentNode())); // elemId = ssElemId.str(); diff --git a/src/uscxml/interpreter/InterpreterDraft6.cpp b/src/uscxml/interpreter/InterpreterDraft6.cpp index 554cd28..92333f1 100644 --- a/src/uscxml/interpreter/InterpreterDraft6.cpp +++ b/src/uscxml/interpreter/InterpreterDraft6.cpp @@ -105,7 +105,7 @@ NodeSet<std::string> InterpreterDraft6::getDocumentInitialTransitions() { Element<std::string> transitionElem = _document.createElementNS(_nsInfo.nsURL, "transition"); _nsInfo.setPrefix(transitionElem); - transitionElem.setAttribute("target", ATTR(initialStates[i], "id")); + transitionElem.setAttribute("target", ATTR_CAST(initialStates[i], "id")); initialElem.appendChild(transitionElem); _scxml.appendChild(initialElem); initialTransitions.push_back(transitionElem); @@ -138,13 +138,6 @@ InterpreterState InterpreterDraft6::step(int waitForMS = 0) { setInterpreterState(USCXML_MICROSTEPPED); } - if (!isLegalConfiguration(_configuration)) { - std:: cout << "Illegal configuration: {"; - for (int i = 0; i < _configuration.size(); i++) { - std::cout << ATTR(_configuration[i], "id") << ", " << std::endl; - } - std:: cout << "}" << std::endl; - } assert(isLegalConfiguration(_configuration)); // are there spontaneous transitions? @@ -203,8 +196,9 @@ InterpreterState InterpreterDraft6::step(int waitForMS = 0) { for (unsigned int i = 0; i < _statesToInvoke.size(); i++) { NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _statesToInvoke[i]); for (unsigned int j = 0; j < invokes.size(); j++) { - if (!HAS_ATTR(invokes[j], "persist") || !DOMUtils::attributeIsTrue(ATTR(invokes[j], "persist"))) { - invoke(invokes[j]); + Element<std::string> invokeElem = Element<std::string>(invokes[j]); + if (!HAS_ATTR(invokeElem, "persist") || !DOMUtils::attributeIsTrue(ATTR(invokeElem, "persist"))) { + invoke(invokeElem); } } } @@ -354,8 +348,9 @@ void InterpreterDraft6::stabilize() { for (unsigned int i = 0; i < _statesToInvoke.size(); i++) { NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _statesToInvoke[i]); for (unsigned int j = 0; j < invokes.size(); j++) { - if (!HAS_ATTR(invokes[j], "persist") || !DOMUtils::attributeIsTrue(ATTR(invokes[j], "persist"))) { - invoke(invokes[j]); + Element<std::string> invokeElem = Element<std::string>(invokes[j]); + if (!HAS_ATTR(invokeElem, "persist") || !DOMUtils::attributeIsTrue(ATTR(invokeElem, "persist"))) { + invoke(invokeElem); } } } @@ -641,7 +636,7 @@ void InterpreterDraft6::exitInterpreter() { Arabica::XPath::NodeSet<std::string> 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]); + cancelInvoke(Element<std::string>(invokeElems[j])); } Element<std::string> stateElem(statesToExit[i]); if (isFinal(stateElem) && parentIsScxmlState(stateElem)) { @@ -902,8 +897,9 @@ void InterpreterDraft6::enterStates(const Arabica::XPath::NodeSet<std::string>& for (unsigned int k = 0; k < statesToEnter.size(); k++) { NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", statesToEnter[k]); for (unsigned int j = 0; j < invokes.size(); j++) { - if (HAS_ATTR(invokes[j], "persist") && DOMUtils::attributeIsTrue(ATTR(invokes[j], "persist"))) { - invoke(invokes[j]); + Element<std::string> invokeElem = Element<std::string>(invokes[j]); + if (HAS_ATTR(invokeElem, "persist") && DOMUtils::attributeIsTrue(ATTR(invokeElem, "persist"))) { + invoke(invokeElem); } } } @@ -1063,5 +1059,20 @@ void InterpreterDraft6::addStatesToEnter(const Element<std::string>& state, } } +void InterpreterDraft6::handleDOMEvent(Arabica::DOM::Events::Event<std::string>& event) { + InterpreterImpl::handleDOMEvent(event); + + // remove modified states from cache + if (event.getType().compare("DOMAttrModified") == 0) // we do not care about attributes + return; + Node<std::string> target = Arabica::DOM::Node<std::string>(event.getTarget()); + NodeSet<std::string> transitions = InterpreterImpl::filterChildElements(_nsInfo.xmlNSPrefix + "transition", target); + for (int i = 0; i < transitions.size(); i++) { + const Element<std::string> transElem = Element<std::string>(transitions[i]); + if (_transWithinParallel.find(transElem) != _transWithinParallel.end()) + _transWithinParallel.erase(transElem); + } +} + }
\ No newline at end of file diff --git a/src/uscxml/interpreter/InterpreterDraft6.h b/src/uscxml/interpreter/InterpreterDraft6.h index 062d79a..3414e5e 100644 --- a/src/uscxml/interpreter/InterpreterDraft6.h +++ b/src/uscxml/interpreter/InterpreterDraft6.h @@ -56,6 +56,9 @@ protected: Arabica::DOM::Node<std::string> findLCPA(const Arabica::XPath::NodeSet<std::string>& states); std::map<Arabica::DOM::Element<std::string>, bool> _transWithinParallel; // this is costly to calculate + + virtual void handleDOMEvent(Arabica::DOM::Events::Event<std::string>& event); + }; } diff --git a/src/uscxml/interpreter/InterpreterRC.cpp b/src/uscxml/interpreter/InterpreterRC.cpp.deactivated index 24b9003..9993227 100644 --- a/src/uscxml/interpreter/InterpreterRC.cpp +++ b/src/uscxml/interpreter/InterpreterRC.cpp.deactivated @@ -161,7 +161,7 @@ InterpreterState InterpreterRC::interpret() { Element<std::string> transitionElem = _document.createElementNS(_nsInfo.nsURL, "transition"); _nsInfo.setPrefix(transitionElem); - transitionElem.setAttribute("target", ATTR(initialStates[i], "id")); + transitionElem.setAttribute("target", ATTR_CAST(initialStates[i], "id")); initialElem.appendChild(transitionElem); _scxml.appendChild(initialElem); initialTransitions.push_back(transitionElem); @@ -286,7 +286,7 @@ void InterpreterRC::mainEventLoop() { if (!hasLegalConfiguration()) { std::cout << "Illegal configuration!" << std::endl; for (unsigned int j = 0; j < _configuration.size(); j++) { - std::cout << ATTR(_configuration[j], "id") << " "; + std::cout << ATTR_CAST(_configuration[j], "id") << " "; } std::cout << std::endl; } diff --git a/src/uscxml/interpreter/InterpreterRC.h b/src/uscxml/interpreter/InterpreterRC.h.deactivated index 9afc2e6..9afc2e6 100644 --- a/src/uscxml/interpreter/InterpreterRC.h +++ b/src/uscxml/interpreter/InterpreterRC.h.deactivated diff --git a/src/uscxml/messages/Data.cpp b/src/uscxml/messages/Data.cpp index 911730a..7afad43 100644 --- a/src/uscxml/messages/Data.cpp +++ b/src/uscxml/messages/Data.cpp @@ -97,7 +97,7 @@ Data::Data(const Arabica::DOM::Node<std::string>& dom) { std::string key; switch (child.getNodeType()) { case Arabica::DOM::Node_base::ELEMENT_NODE: - key = TAGNAME(child); + key = TAGNAME_CAST(child); break; case Arabica::DOM::Node_base::ATTRIBUTE_NODE: key = ((Arabica::DOM::Attr<std::string>)child).getName(); diff --git a/src/uscxml/messages/Event.cpp b/src/uscxml/messages/Event.cpp index f8a880f..43c6600 100644 --- a/src/uscxml/messages/Event.cpp +++ b/src/uscxml/messages/Event.cpp @@ -121,8 +121,8 @@ Event Event::fromXML(const std::string& xmlString) { Arabica::DOM::NodeList<std::string> properties = payloadElem.getElementsByTagName("scxml:property"); if (properties.getLength() > 0) { for (int i = 0; i < properties.getLength(); i++) { - if (HAS_ATTR(properties.item(i), "name")) { - std::string key = ATTR(properties.item(i), "name"); + if (HAS_ATTR_CAST(properties.item(i), "name")) { + std::string key = ATTR_CAST(properties.item(i), "name"); std::string value; Arabica::DOM::NodeList<std::string> childs = properties.item(i).getChildNodes(); for (int j = 0; j < childs.getLength(); j++) { diff --git a/src/uscxml/plugins/DataModel.h b/src/uscxml/plugins/DataModel.h index 1a4deba..b1eafb9 100644 --- a/src/uscxml/plugins/DataModel.h +++ b/src/uscxml/plugins/DataModel.h @@ -61,10 +61,10 @@ public: virtual std::string evalAsString(const std::string& expr) = 0; - virtual bool evalAsBool(const Arabica::DOM::Node<std::string>& scriptNode, + virtual bool evalAsBool(const Arabica::DOM::Element<std::string>& scriptNode, const std::string& expr) = 0; virtual bool evalAsBool(const std::string& expr) { - return evalAsBool(Arabica::DOM::Node<std::string>(), expr); + return evalAsBool(Arabica::DOM::Element<std::string>(), expr); } virtual bool isDeclared(const std::string& expr) = 0; @@ -150,7 +150,7 @@ public: virtual bool evalAsBool(const std::string& expr) { return _impl->evalAsBool(expr); } - virtual bool evalAsBool(const Arabica::DOM::Node<std::string>& scriptNode, + virtual bool evalAsBool(const Arabica::DOM::Element<std::string>& scriptNode, const std::string& expr) { return _impl->evalAsBool(scriptNode, expr); } diff --git a/src/uscxml/plugins/ExecutableContent.h b/src/uscxml/plugins/ExecutableContent.h index 6f4335b..6916b5f 100644 --- a/src/uscxml/plugins/ExecutableContent.h +++ b/src/uscxml/plugins/ExecutableContent.h @@ -44,8 +44,8 @@ public: virtual std::string getNamespace() { return "http://www.w3.org/2005/07/scxml"; ///< The namespace of the element. } - virtual void enterElement(const Arabica::DOM::Node<std::string>& node) = 0; ///< Invoked when entering the element as part of evaluating executable content. - virtual void exitElement(const Arabica::DOM::Node<std::string>& node) = 0; ///< Invoked when exiting the element as part of evaluating executable content. + virtual void enterElement(const Arabica::DOM::Element<std::string>& node) = 0; ///< Invoked when entering the element as part of evaluating executable content. + virtual void exitElement(const Arabica::DOM::Element<std::string>& node) = 0; ///< Invoked when exiting the element as part of evaluating executable content. virtual bool processChildren() = 0; ///< Whether or not the interpreter should process this elements children. protected: @@ -86,10 +86,10 @@ public: std::string getNamespace() { return _impl->getNamespace(); } - void enterElement(const Arabica::DOM::Node<std::string>& node) { + void enterElement(const Arabica::DOM::Element<std::string>& node) { return _impl->enterElement(node); } - void exitElement(const Arabica::DOM::Node<std::string>& node) { + void exitElement(const Arabica::DOM::Element<std::string>& node) { return _impl->exitElement(node); } bool processChildren() { diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp index 6d15f72..3a9cb27 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.cpp @@ -514,7 +514,7 @@ void JSCDataModel::eval(const Element<std::string>& scriptElem, evalAsValue(expr); } -bool JSCDataModel::evalAsBool(const Arabica::DOM::Node<std::string>& node, const std::string& expr) { +bool JSCDataModel::evalAsBool(const Arabica::DOM::Element<std::string>& node, const std::string& expr) { JSValueRef result = evalAsValue(expr); return JSValueToBoolean(_ctx, result); } diff --git a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h index fea2234..6792130 100644 --- a/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h +++ b/src/uscxml/plugins/datamodel/ecmascript/JavaScriptCore/JSCDataModel.h @@ -66,7 +66,7 @@ public: const std::string& expr); virtual std::string evalAsString(const std::string& expr); - virtual bool evalAsBool(const Arabica::DOM::Node<std::string>& node, const std::string& expr); + virtual bool evalAsBool(const Arabica::DOM::Element<std::string>& node, const std::string& expr); virtual bool isDeclared(const std::string& expr); diff --git a/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp b/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp index bf8b538..a36a5f7 100644 --- a/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp +++ b/src/uscxml/plugins/datamodel/lua/LuaDataModel.cpp @@ -435,7 +435,7 @@ void LuaDataModel::init(const std::string& location, const Data& data) { * The predicate must return 'true' if and only if that state is in the current * state configuration. */ -bool LuaDataModel::evalAsBool(const Arabica::DOM::Node<std::string>& node, const std::string& expr) { +bool LuaDataModel::evalAsBool(const Arabica::DOM::Element<std::string>& node, const std::string& expr) { // we need the result of the expression on the lua stack -> has to "return"! std::string trimmedExpr = boost::trim_copy(expr); if (!boost::starts_with(trimmedExpr, "return")) { diff --git a/src/uscxml/plugins/datamodel/lua/LuaDataModel.h b/src/uscxml/plugins/datamodel/lua/LuaDataModel.h index 86e7e17..69b8d57 100644 --- a/src/uscxml/plugins/datamodel/lua/LuaDataModel.h +++ b/src/uscxml/plugins/datamodel/lua/LuaDataModel.h @@ -83,7 +83,7 @@ public: virtual void eval(const Arabica::DOM::Element<std::string>& scriptElem, const std::string& expr); virtual std::string evalAsString(const std::string& expr); - virtual bool evalAsBool(const Arabica::DOM::Node<std::string>& node, const std::string& expr); + virtual bool evalAsBool(const Arabica::DOM::Element<std::string>& node, const std::string& expr); virtual std::string andExpressions(std::list<std::string>); diff --git a/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp b/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp index d86bdb2..ae75c88 100644 --- a/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp +++ b/src/uscxml/plugins/datamodel/null/NULLDataModel.cpp @@ -104,7 +104,7 @@ bool NULLDataModel::isDeclared(const std::string& expr) { * The predicate must return 'true' if and only if that state is in the current * state configuration. */ -bool NULLDataModel::evalAsBool(const Arabica::DOM::Node<std::string>& node, const std::string& expr) { +bool NULLDataModel::evalAsBool(const Arabica::DOM::Element<std::string>& node, const std::string& expr) { std::string trimmedExpr = expr; boost::trim(trimmedExpr); if (!boost::istarts_with(trimmedExpr, "in")) diff --git a/src/uscxml/plugins/datamodel/null/NULLDataModel.h b/src/uscxml/plugins/datamodel/null/NULLDataModel.h index 2870388..da0374e 100644 --- a/src/uscxml/plugins/datamodel/null/NULLDataModel.h +++ b/src/uscxml/plugins/datamodel/null/NULLDataModel.h @@ -77,7 +77,7 @@ public: virtual void eval(const Arabica::DOM::Element<std::string>& scriptElem, const std::string& expr); virtual std::string evalAsString(const std::string& expr); - virtual bool evalAsBool(const Arabica::DOM::Node<std::string>& node, const std::string& expr); + virtual bool evalAsBool(const Arabica::DOM::Element<std::string>& node, const std::string& expr); protected: diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp index 924e14a..f6131f8 100644 --- a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp +++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.cpp @@ -676,10 +676,10 @@ void SWIDataModel::eval(const Element<std::string>& scriptElem, const std::strin } bool SWIDataModel::evalAsBool(const std::string& expr) { - return evalAsBool(Arabica::DOM::Node<std::string>(), expr); + return evalAsBool(Arabica::DOM::Element<std::string>(), expr); } -bool SWIDataModel::evalAsBool(const Arabica::DOM::Node<std::string>& node, const std::string& expr) { +bool SWIDataModel::evalAsBool(const Arabica::DOM::Element<std::string>& node, const std::string& expr) { SWIEngineLock engineLock; try { PlCompound compound(expr.c_str()); diff --git a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h index a673a40..1bf7b6a 100644 --- a/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h +++ b/src/uscxml/plugins/datamodel/prolog/swi/SWIDataModel.h @@ -97,7 +97,7 @@ public: virtual Data getStringAsData(const std::string& content); virtual std::string evalAsString(const std::string& expr); - virtual bool evalAsBool(const Arabica::DOM::Node<std::string>& node, const std::string& expr); + virtual bool evalAsBool(const Arabica::DOM::Element<std::string>& node, const std::string& expr); virtual bool evalAsBool(const std::string& expr); static foreign_t inPredicate(term_t a0, int arity, void* context); diff --git a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp index 6d34677..f83d0c8 100644 --- a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp +++ b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.cpp @@ -141,10 +141,10 @@ void PromelaDataModel::eval(const Element<std::string>& scriptElem, const std::s } bool PromelaDataModel::evalAsBool(const std::string& expr) { - return evalAsBool(Arabica::DOM::Node<std::string>(), expr); + return evalAsBool(Arabica::DOM::Element<std::string>(), expr); } -bool PromelaDataModel::evalAsBool(const Arabica::DOM::Node<std::string>& node, const std::string& expr) { +bool PromelaDataModel::evalAsBool(const Arabica::DOM::Element<std::string>& node, const std::string& expr) { PromelaParser parser(expr, PromelaParser::PROMELA_EXPR); // parser.dump(); return evaluateExpr(parser.ast) > 0; diff --git a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h index ca6b19d..89078bd 100644 --- a/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h +++ b/src/uscxml/plugins/datamodel/promela/PromelaDataModel.h @@ -78,7 +78,7 @@ public: virtual Data getStringAsData(const std::string& content); virtual std::string evalAsString(const std::string& expr); - virtual bool evalAsBool(const Arabica::DOM::Node<std::string>& node, const std::string& expr); + virtual bool evalAsBool(const Arabica::DOM::Element<std::string>& node, const std::string& expr); virtual bool evalAsBool(const std::string& expr); virtual std::string andExpressions(std::list<std::string> expressions); diff --git a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp index 41e015e..06461aa 100644 --- a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp +++ b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.cpp @@ -229,7 +229,7 @@ void XPathDataModel::setEvent(const Event& event) { Node<std::string> oldEventElem = _datamodel.getFirstChild(); while(oldEventElem) { if (oldEventElem.getNodeType() == Node_base::ELEMENT_NODE) { - if (HAS_ATTR(oldEventElem, "id") && iequals(ATTR(oldEventElem, "id"), "_event")) + if (HAS_ATTR_CAST(oldEventElem, "id") && iequals(ATTR_CAST(oldEventElem, "id"), "_event")) break; } oldEventElem = oldEventElem.getNextSibling(); @@ -393,10 +393,10 @@ bool XPathDataModel::isDeclared(const std::string& expr) { } bool XPathDataModel::evalAsBool(const std::string& expr) { - return evalAsBool(Arabica::DOM::Node<std::string>(), expr); + return evalAsBool(Arabica::DOM::Element<std::string>(), expr); } -bool XPathDataModel::evalAsBool(const Arabica::DOM::Node<std::string>& node, const std::string& expr) { +bool XPathDataModel::evalAsBool(const Arabica::DOM::Element<std::string>& node, const std::string& expr) { // std::cout << std::endl << evalAsString(expr); XPathValue<std::string> result; try { diff --git a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.h b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.h index 09d63fa..fe454b3 100644 --- a/src/uscxml/plugins/datamodel/xpath/XPathDataModel.h +++ b/src/uscxml/plugins/datamodel/xpath/XPathDataModel.h @@ -123,7 +123,7 @@ public: virtual std::string evalAsString(const std::string& expr); virtual bool evalAsBool(const std::string& expr); - virtual bool evalAsBool(const Arabica::DOM::Node<std::string>& node, const std::string& expr); + virtual bool evalAsBool(const Arabica::DOM::Element<std::string>& node, const std::string& expr); virtual double evalAsNumber(const std::string& expr); protected: diff --git a/src/uscxml/plugins/element/fetch/FetchElement.cpp b/src/uscxml/plugins/element/fetch/FetchElement.cpp index b40f487..9f97ca9 100644 --- a/src/uscxml/plugins/element/fetch/FetchElement.cpp +++ b/src/uscxml/plugins/element/fetch/FetchElement.cpp @@ -80,7 +80,7 @@ void FetchElement::downloadFailed(const URL& url, int errorCode) { } -void FetchElement::enterElement(const Arabica::DOM::Node<std::string>& node) { +void FetchElement::enterElement(const Arabica::DOM::Element<std::string>& node) { if (!HAS_ATTR(node, "target") && !HAS_ATTR(node, "targetexpr")) { LOG(ERROR) << "Fetch element requires target or targetexpr"; return; @@ -123,7 +123,7 @@ void FetchElement::enterElement(const Arabica::DOM::Node<std::string>& node) { } -void FetchElement::exitElement(const Arabica::DOM::Node<std::string>& node) { +void FetchElement::exitElement(const Arabica::DOM::Element<std::string>& node) { } diff --git a/src/uscxml/plugins/element/fetch/FetchElement.h b/src/uscxml/plugins/element/fetch/FetchElement.h index 433f3f5..e3e5008 100644 --- a/src/uscxml/plugins/element/fetch/FetchElement.h +++ b/src/uscxml/plugins/element/fetch/FetchElement.h @@ -46,8 +46,8 @@ public: return false; } - void enterElement(const Arabica::DOM::Node<std::string>& node); - void exitElement(const Arabica::DOM::Node<std::string>& node); + void enterElement(const Arabica::DOM::Element<std::string>& node); + void exitElement(const Arabica::DOM::Element<std::string>& node); void downloadCompleted(const URL& url); void downloadFailed(const URL& url, int errorCode); diff --git a/src/uscxml/plugins/element/file/FileElement.cpp b/src/uscxml/plugins/element/file/FileElement.cpp index 247c3c8..decd5ca 100644 --- a/src/uscxml/plugins/element/file/FileElement.cpp +++ b/src/uscxml/plugins/element/file/FileElement.cpp @@ -48,7 +48,7 @@ boost::shared_ptr<ExecutableContentImpl> FileElement::create(InterpreterImpl* in FileElement::~FileElement() { } -void FileElement::enterElement(const Arabica::DOM::Node<std::string>& node) { +void FileElement::enterElement(const Arabica::DOM::Element<std::string>& node) { if (!HAS_ATTR(node, "url") && !HAS_ATTR(node, "urlexpr")) { LOG(ERROR) << "File element requires url or urlexpr"; return; @@ -251,7 +251,7 @@ void FileElement::enterElement(const Arabica::DOM::Node<std::string>& node) { } -void FileElement::exitElement(const Arabica::DOM::Node<std::string>& node) { +void FileElement::exitElement(const Arabica::DOM::Element<std::string>& node) { } diff --git a/src/uscxml/plugins/element/file/FileElement.h b/src/uscxml/plugins/element/file/FileElement.h index e236918..b1b3426 100644 --- a/src/uscxml/plugins/element/file/FileElement.h +++ b/src/uscxml/plugins/element/file/FileElement.h @@ -62,8 +62,8 @@ public: return false; } - void enterElement(const Arabica::DOM::Node<std::string>& node); - void exitElement(const Arabica::DOM::Node<std::string>& node); + void enterElement(const Arabica::DOM::Element<std::string>& node); + void exitElement(const Arabica::DOM::Element<std::string>& node); protected: diff --git a/src/uscxml/plugins/element/postpone/PostponeElement.cpp b/src/uscxml/plugins/element/postpone/PostponeElement.cpp index 7a18b38..a041a9e 100644 --- a/src/uscxml/plugins/element/postpone/PostponeElement.cpp +++ b/src/uscxml/plugins/element/postpone/PostponeElement.cpp @@ -44,7 +44,7 @@ boost::shared_ptr<ExecutableContentImpl> PostponeElement::create(InterpreterImpl return invoker; } -void PostponeElement::enterElement(const Arabica::DOM::Node<std::string>& node) { +void PostponeElement::enterElement(const Arabica::DOM::Element<std::string>& node) { if (!_interpreter->getDataModel()) { LOG(ERROR) << "Postpone element requires a datamodel"; return; @@ -116,7 +116,7 @@ void PostponeElement::enterElement(const Arabica::DOM::Node<std::string>& node) Resubmitter::postpone(currEvent, until, 0, chained, _interpreter); } -void PostponeElement::exitElement(const Arabica::DOM::Node<std::string>& node) { +void PostponeElement::exitElement(const Arabica::DOM::Element<std::string>& node) { } void PostponeElement::Resubmitter::postpone(const Event& event, std::string until, uint64_t timeout, bool chained, InterpreterImpl* interpreter) { diff --git a/src/uscxml/plugins/element/postpone/PostponeElement.h b/src/uscxml/plugins/element/postpone/PostponeElement.h index 56464e2..9840c75 100644 --- a/src/uscxml/plugins/element/postpone/PostponeElement.h +++ b/src/uscxml/plugins/element/postpone/PostponeElement.h @@ -56,8 +56,8 @@ public: return false; } - void enterElement(const Arabica::DOM::Node<std::string>& node); - void exitElement(const Arabica::DOM::Node<std::string>& node); + void enterElement(const Arabica::DOM::Element<std::string>& node); + void exitElement(const Arabica::DOM::Element<std::string>& node); protected: // once per interpreter diff --git a/src/uscxml/plugins/element/respond/RespondElement.cpp b/src/uscxml/plugins/element/respond/RespondElement.cpp index 6445249..a62f934 100644 --- a/src/uscxml/plugins/element/respond/RespondElement.cpp +++ b/src/uscxml/plugins/element/respond/RespondElement.cpp @@ -43,7 +43,7 @@ boost::shared_ptr<ExecutableContentImpl> RespondElement::create(InterpreterImpl* return invoker; } -void RespondElement::enterElement(const Arabica::DOM::Node<std::string>& node) { +void RespondElement::enterElement(const Arabica::DOM::Element<std::string>& node) { // try to get the request id if (!HAS_ATTR(node, "to")) { LOG(ERROR) << "Respond element requires to attribute"; @@ -81,10 +81,11 @@ void RespondElement::enterElement(const Arabica::DOM::Node<std::string>& node) { // extract the content Arabica::XPath::NodeSet<std::string> contents = InterpreterImpl::filterChildElements(_interpreter->getNameSpaceInfo().getXMLPrefixForNS(getNamespace()) + "content", node); if (contents.size() > 0) { - if (HAS_ATTR(contents[0], "expr")) { // -- content is evaluated string from datamodel ------ + Arabica::DOM::Element<std::string> contentElem = Arabica::DOM::Element<std::string>(contents[0]); + if (HAS_ATTR(contentElem, "expr")) { // -- content is evaluated string from datamodel ------ if (_interpreter->getDataModel()) { try { - Data contentData = _interpreter->getDataModel().getStringAsData(ATTR(contents[0], "expr")); + Data contentData = _interpreter->getDataModel().getStringAsData(ATTR(contentElem, "expr")); if (contentData.atom.length() > 0) { httpReply.content = contentData.atom; httpReply.headers["Content-Type"] = "text/plain"; @@ -108,19 +109,19 @@ void RespondElement::enterElement(const Arabica::DOM::Node<std::string>& node) { LOG(ERROR) << "content element has expr attribute but no datamodel is specified."; return; } - } else if (HAS_ATTR(contents[0], "file") || HAS_ATTR(contents[0], "fileexpr")) { // -- content is from file ------ + } else if (HAS_ATTR(contentElem, "file") || HAS_ATTR(contentElem, "fileexpr")) { // -- content is from file ------ URL file; - if (HAS_ATTR(contents[0], "fileexpr")) { + if (HAS_ATTR(contentElem, "fileexpr")) { if (_interpreter->getDataModel()) { try { - file = "file://" + _interpreter->getDataModel().evalAsString(ATTR(contents[0], "fileexpr")); + file = "file://" + _interpreter->getDataModel().evalAsString(ATTR(contentElem, "fileexpr")); } catch (Event e) { LOG(ERROR) << "Syntax error with fileexpr in content child of Respond element:" << std::endl << e << std::endl; return; } } } else { - file = "file://" + ATTR(contents[0], "fileexpr"); + file = "file://" + ATTR(contentElem, "fileexpr"); } if (file) { httpReply.content = file.getInContent(); @@ -144,13 +145,15 @@ void RespondElement::enterElement(const Arabica::DOM::Node<std::string>& node) { // process headers Arabica::XPath::NodeSet<std::string> headers = InterpreterImpl::filterChildElements(_interpreter->getNameSpaceInfo().getXMLPrefixForNS(getNamespace()) + "header", node); for (int i = 0; i < headers.size(); i++) { + Arabica::DOM::Element<std::string> headerElem = Arabica::DOM::Element<std::string>(headers[i]); + std::string name; - if (HAS_ATTR(headers[i], "name")) { - name = ATTR(headers[i], "name"); - } else if(HAS_ATTR(headers[i], "nameexpr")) { + if (HAS_ATTR(headerElem, "name")) { + name = ATTR(headerElem, "name"); + } else if(HAS_ATTR(headerElem, "nameexpr")) { if (_interpreter->getDataModel()) { try { - name = _interpreter->getDataModel().evalAsString(ATTR(headers[i], "nameexpr")); + name = _interpreter->getDataModel().evalAsString(ATTR(headerElem, "nameexpr")); } catch (Event e) { LOG(ERROR) << "Syntax error with nameexpr in header child of Respond element:" << std::endl << e << std::endl; return; @@ -165,12 +168,12 @@ void RespondElement::enterElement(const Arabica::DOM::Node<std::string>& node) { } std::string value; - if (HAS_ATTR(headers[i], "value")) { - value = ATTR(headers[i], "value"); - } else if(HAS_ATTR(headers[i], "valueexpr")) { + if (HAS_ATTR(headerElem, "value")) { + value = ATTR(headerElem, "value"); + } else if(HAS_ATTR(headerElem, "valueexpr")) { if (_interpreter->getDataModel()) { try { - value = _interpreter->getDataModel().evalAsString(ATTR(headers[i], "valueexpr")); + value = _interpreter->getDataModel().evalAsString(ATTR(headerElem, "valueexpr")); } catch (Event e) { LOG(ERROR) << "Syntax error with valueexpr in header child of Respond element:" << std::endl << e << std::endl; return; @@ -192,7 +195,7 @@ void RespondElement::enterElement(const Arabica::DOM::Node<std::string>& node) { servlet->getRequests().erase(requestId); } -void RespondElement::exitElement(const Arabica::DOM::Node<std::string>& node) { +void RespondElement::exitElement(const Arabica::DOM::Element<std::string>& node) { } diff --git a/src/uscxml/plugins/element/respond/RespondElement.h b/src/uscxml/plugins/element/respond/RespondElement.h index 71b7fec..2e8cec7 100644 --- a/src/uscxml/plugins/element/respond/RespondElement.h +++ b/src/uscxml/plugins/element/respond/RespondElement.h @@ -46,8 +46,8 @@ public: return false; } - void enterElement(const Arabica::DOM::Node<std::string>& node); - void exitElement(const Arabica::DOM::Node<std::string>& node); + void enterElement(const Arabica::DOM::Element<std::string>& node); + void exitElement(const Arabica::DOM::Element<std::string>& node); }; diff --git a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp index 9e435d2..dac4f99 100644 --- a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp +++ b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.cpp @@ -66,9 +66,9 @@ bool pluginConnect(pluma::Host& host) { #endif #define OSG_TAG_HANDLE(tagName, procFunc) \ -} else if (iequals(LOCALNAME(childs.item(i)), tagName) && \ +} else if (iequals(LOCALNAME(childElem), tagName) && \ validChildren.find(tagName) != validChildren.end()) { \ - procFunc(childs.item(i));\ + procFunc(childElem);\ OSGInvoker::OSGInvoker() { @@ -167,7 +167,7 @@ void OSGInvoker::handleEvent(Arabica::DOM::Events::Event<std::string>& event) { } } -void OSGInvoker::processDisplay(const Arabica::DOM::Node<std::string>& element) { +void OSGInvoker::processDisplay(const Arabica::DOM::Element<std::string>& element) { // std::cout << element << std::endl; if (_displays.find(element) == _displays.end()) { @@ -188,7 +188,7 @@ void OSGInvoker::processDisplay(const Arabica::DOM::Node<std::string>& element) } } -void OSGInvoker::processViewport(const Arabica::DOM::Node<std::string>& element) { +void OSGInvoker::processViewport(const Arabica::DOM::Element<std::string>& element) { if (_displays.find(element.getParentNode()) == _displays.end()) return; @@ -236,7 +236,7 @@ void OSGInvoker::processViewport(const Arabica::DOM::Node<std::string>& element) void OSGInvoker::processCamera(const Arabica::DOM::Node<std::string>& element) {} void OSGInvoker::updateCamera(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event) {} -void OSGInvoker::processTranslation(const Arabica::DOM::Node<std::string>& element) { +void OSGInvoker::processTranslation(const Arabica::DOM::Element<std::string>& element) { assert(_nodes.find(element.getParentNode()) != _nodes.end()); osg::ref_ptr<osg::Node> node = _nodes[element.getParentNode()]; @@ -269,7 +269,7 @@ void OSGInvoker::processTranslation(const Arabica::DOM::Node<std::string>& eleme processChildren(validChilds, element); } -void OSGInvoker::processRotation(const Arabica::DOM::Node<std::string>& element) { +void OSGInvoker::processRotation(const Arabica::DOM::Element<std::string>& element) { assert(_nodes.find(element.getParentNode()) != _nodes.end()); osg::ref_ptr<osg::Node> node = _nodes[element.getParentNode()]; @@ -296,12 +296,12 @@ void OSGInvoker::updateRotation(osg::ref_ptr<osg::Node> node, Arabica::DOM::Even osg::ref_ptr<osg::MatrixTransform> transform = static_cast<osg::MatrixTransform*>(node->asTransform()); if (false) { } else if (iequals(event.getType(), "DOMAttrModified")) { - osg::Matrix rotation = rotationFromElement(Arabica::DOM::Node<std::string>(event.getTarget())); + osg::Matrix rotation = rotationFromElement(Arabica::DOM::Element<std::string>(Arabica::DOM::Node<std::string>(event.getTarget()))); transform->setMatrix(rotation); } } -osg::Matrix OSGInvoker::rotationFromElement(const Arabica::DOM::Node<std::string>& element) { +osg::Matrix OSGInvoker::rotationFromElement(const Arabica::DOM::Element<std::string>& element) { double pitch = 0, roll = 0, yaw = 0; if (HAS_ATTR(element, "pitch")) { NumAttr pitchAttr = NumAttr(ATTR(element, "pitch")); @@ -342,7 +342,7 @@ osg::Matrix OSGInvoker::rotationFromElement(const Arabica::DOM::Node<std::string return rotation; } -void OSGInvoker::processScale(const Arabica::DOM::Node<std::string>& element) { +void OSGInvoker::processScale(const Arabica::DOM::Element<std::string>& element) { assert(_nodes.find(element.getParentNode()) != _nodes.end()); osg::ref_ptr<osg::Node> node = _nodes[element.getParentNode()]; @@ -375,7 +375,7 @@ void OSGInvoker::processScale(const Arabica::DOM::Node<std::string>& element) { processChildren(validChilds, element); } -void OSGInvoker::processNode(const Arabica::DOM::Node<std::string>& element) { +void OSGInvoker::processNode(const Arabica::DOM::Element<std::string>& element) { _nodes_t::iterator nodeIter = _nodes.find(element.getParentNode()); assert(nodeIter != _nodes.end()); @@ -407,7 +407,7 @@ void OSGInvoker::processNode(const Arabica::DOM::Node<std::string>& element) { } } -void OSGInvoker::processSphere(const Arabica::DOM::Node<std::string>& element) { +void OSGInvoker::processSphere(const Arabica::DOM::Element<std::string>& element) { assert(_nodes.find(element.getParentNode()) != _nodes.end()); osg::ref_ptr<osg::Node> parent = _nodes[element.getParentNode()]; @@ -434,7 +434,7 @@ void OSGInvoker::processSphere(const Arabica::DOM::Node<std::string>& element) { void OSGInvoker::updateSphere(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event) { } -void OSGInvoker::processBox(const Arabica::DOM::Node<std::string>& element) { +void OSGInvoker::processBox(const Arabica::DOM::Element<std::string>& element) { assert(_nodes.find(element.getParentNode()) != _nodes.end()); osg::ref_ptr<osg::Node> parent = _nodes[element.getParentNode()]; @@ -462,7 +462,7 @@ void OSGInvoker::processBox(const Arabica::DOM::Node<std::string>& element) { } void OSGInvoker::updateBox(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event) { } -void OSGInvoker::processCapsule(const Arabica::DOM::Node<std::string>& element) { +void OSGInvoker::processCapsule(const Arabica::DOM::Element<std::string>& element) { assert(_nodes.find(element.getParentNode()) != _nodes.end()); osg::ref_ptr<osg::Node> parent = _nodes[element.getParentNode()]; @@ -487,7 +487,7 @@ void OSGInvoker::processCapsule(const Arabica::DOM::Node<std::string>& element) void OSGInvoker::updateCapsule(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event) { } -void OSGInvoker::processCone(const Arabica::DOM::Node<std::string>& element) { +void OSGInvoker::processCone(const Arabica::DOM::Element<std::string>& element) { assert(_nodes.find(element.getParentNode()) != _nodes.end()); osg::ref_ptr<osg::Node> parent = _nodes[element.getParentNode()]; @@ -514,7 +514,7 @@ void OSGInvoker::processCone(const Arabica::DOM::Node<std::string>& element) { void OSGInvoker::updateCone(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event) { } -void OSGInvoker::processCylinder(const Arabica::DOM::Node<std::string>& element) { +void OSGInvoker::processCylinder(const Arabica::DOM::Element<std::string>& element) { assert(_nodes.find(element.getParentNode()) != _nodes.end()); osg::ref_ptr<osg::Node> parent = _nodes[element.getParentNode()]; @@ -541,7 +541,7 @@ void OSGInvoker::processCylinder(const Arabica::DOM::Node<std::string>& element) void OSGInvoker::updateCylinder(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event) { } -osg::Vec4 OSGInvoker::getColor(const Arabica::DOM::Node<std::string>& element, const std::string& attr, bool& valid) { +osg::Vec4 OSGInvoker::getColor(const Arabica::DOM::Element<std::string>& element, const std::string& attr, bool& valid) { if (HAS_ATTR(element, attr)) { std::string color = ATTR(element, attr); @@ -576,7 +576,7 @@ osg::Vec4 OSGInvoker::getColor(const Arabica::DOM::Node<std::string>& element, c return osg::Vec4(); } -osg::ref_ptr<osg::Material> OSGInvoker::getMaterial(const Arabica::DOM::Node<std::string>& element) { +osg::ref_ptr<osg::Material> OSGInvoker::getMaterial(const Arabica::DOM::Element<std::string>& element) { osg::ref_ptr<osg::Material> nodeMat; @@ -630,6 +630,7 @@ void OSGInvoker::processChildren(const std::set<std::string>& validChildren, con for (int i = 0; i < childs.getLength(); ++i) { if (childs.item(i).getNodeType() != Arabica::DOM::Node_base::ELEMENT_NODE) continue; + Arabica::DOM::Element<std::string> childElem = Arabica::DOM::Element<std::string>(childs.item(i)); if (false) { OSG_TAG_HANDLE("node", processNode); OSG_TAG_HANDLE("translation", processTranslation); @@ -644,12 +645,12 @@ void OSGInvoker::processChildren(const std::set<std::string>& validChildren, con OSG_TAG_HANDLE("capsule", processCapsule); OSG_TAG_HANDLE("cylinder", processCylinder); } else { - LOG(INFO) << "Unknown XML element " << TAGNAME(childs.item(i)); + LOG(INFO) << "Unknown XML element " << TAGNAME(childElem); } } } -void OSGInvoker::getViewport(const Arabica::DOM::Node<std::string>& element, +void OSGInvoker::getViewport(const Arabica::DOM::Element<std::string>& element, unsigned int& x, unsigned int& y, unsigned int& width, @@ -659,7 +660,7 @@ void OSGInvoker::getViewport(const Arabica::DOM::Node<std::string>& element, } -void OSGInvoker::getViewport(const Arabica::DOM::Node<std::string>& element, +void OSGInvoker::getViewport(const Arabica::DOM::Element<std::string>& element, unsigned int& x, unsigned int& y, unsigned int& width, @@ -674,7 +675,7 @@ void OSGInvoker::getViewport(const Arabica::DOM::Node<std::string>& element, getViewport(element, x, y, width, height, fullWidth, fullHeight); } -void OSGInvoker::getViewport(const Arabica::DOM::Node<std::string>& element, +void OSGInvoker::getViewport(const Arabica::DOM::Element<std::string>& element, unsigned int& x, unsigned int& y, unsigned int& width, diff --git a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.h b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.h index af06e23..30be8ca 100644 --- a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.h +++ b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.h @@ -61,58 +61,58 @@ public: virtual void runOnMainThread(); protected: - void processDisplay(const Arabica::DOM::Node<std::string>& element); + void processDisplay(const Arabica::DOM::Element<std::string>& element); void updateDisplay(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event); - void processViewport(const Arabica::DOM::Node<std::string>& element); + void processViewport(const Arabica::DOM::Element<std::string>& element); void updateViewport(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event); void processCamera(const Arabica::DOM::Node<std::string>& element); void updateCamera(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event); - void processTranslation(const Arabica::DOM::Node<std::string>& element); + void processTranslation(const Arabica::DOM::Element<std::string>& element); void updateTranslation(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event); - void processRotation(const Arabica::DOM::Node<std::string>& element); + void processRotation(const Arabica::DOM::Element<std::string>& element); void updateRotation(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event); - static osg::Matrix rotationFromElement(const Arabica::DOM::Node<std::string>& element); + static osg::Matrix rotationFromElement(const Arabica::DOM::Element<std::string>& element); - void processScale(const Arabica::DOM::Node<std::string>& element); + void processScale(const Arabica::DOM::Element<std::string>& element); void updateScale(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event); - void processNode(const Arabica::DOM::Node<std::string>& element); + void processNode(const Arabica::DOM::Element<std::string>& element); void updateNode(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event); - void processSphere(const Arabica::DOM::Node<std::string>& element); + void processSphere(const Arabica::DOM::Element<std::string>& element); void updateSphere(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event); - void processBox(const Arabica::DOM::Node<std::string>& element); + void processBox(const Arabica::DOM::Element<std::string>& element); void updateBox(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event); - void processCapsule(const Arabica::DOM::Node<std::string>& element); + void processCapsule(const Arabica::DOM::Element<std::string>& element); void updateCapsule(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event); - void processCone(const Arabica::DOM::Node<std::string>& element); + void processCone(const Arabica::DOM::Element<std::string>& element); void updateCone(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event); - void processCylinder(const Arabica::DOM::Node<std::string>& element); + void processCylinder(const Arabica::DOM::Element<std::string>& element); void updateCylinder(osg::ref_ptr<osg::Node> node, Arabica::DOM::Events::Event<std::string>& event); - osg::Vec4 getColor(const Arabica::DOM::Node<std::string>& element, const std::string& attr, bool& valid); - osg::ref_ptr<osg::Material> getMaterial(const Arabica::DOM::Node<std::string>& element); + osg::Vec4 getColor(const Arabica::DOM::Element<std::string>& element, const std::string& attr, bool& valid); + osg::ref_ptr<osg::Material> getMaterial(const Arabica::DOM::Element<std::string>& element); osg::Vec4 parseVec4(const std::string& coeffs, int& number); void processChildren(const std::set<std::string>& validChildren, const Arabica::DOM::Node<std::string>& element); - void getViewport(const Arabica::DOM::Node<std::string>& element, + void getViewport(const Arabica::DOM::Element<std::string>& element, unsigned int& x, unsigned int& y, unsigned int& width, unsigned int& height, int& screenId); - void getViewport(const Arabica::DOM::Node<std::string>& element, + void getViewport(const Arabica::DOM::Element<std::string>& element, unsigned int& x, unsigned int& y, unsigned int& width, unsigned int& height, CompositeDisplay* display); - void getViewport(const Arabica::DOM::Node<std::string>& element, + void getViewport(const Arabica::DOM::Element<std::string>& element, unsigned int& x, unsigned int& y, unsigned int& width, diff --git a/src/uscxml/plugins/invoker/xhtml/XHTMLInvoker.cpp b/src/uscxml/plugins/invoker/xhtml/XHTMLInvoker.cpp index 5b67f7c..285db72 100644 --- a/src/uscxml/plugins/invoker/xhtml/XHTMLInvoker.cpp +++ b/src/uscxml/plugins/invoker/xhtml/XHTMLInvoker.cpp @@ -186,11 +186,12 @@ void XHTMLInvoker::reply(const SendRequest& req, const HTTPServer::Request& long std::stringstream ss; // Arabica::DOM::Node<std::string> content = req.dom.getDocumentElement(); Arabica::DOM::Node<std::string> content = req.dom; - if (content && iequals(content.getLocalName(), "content")) { - reply.headers["X-SCXML-Type"] = (HAS_ATTR(content, "type") ? ATTR(content, "type") : "replacechildren"); - reply.headers["X-SCXML-XPath"] = (HAS_ATTR(content, "xpath") ? ATTR(content, "xpath") : "/html/body"); - if (HAS_ATTR(content, "attr")) - reply.headers["X-SCXML-Attr"] = ATTR(content, "attr"); + if (content && content.getNodeType() == Arabica::DOM::Node_base::ELEMENT_NODE && iequals(content.getLocalName(), "content")) { + Arabica::DOM::Element<std::string> contentElem = Arabica::DOM::Element<std::string>(content); + reply.headers["X-SCXML-Type"] = (HAS_ATTR(contentElem, "type") ? ATTR(contentElem, "type") : "replacechildren"); + reply.headers["X-SCXML-XPath"] = (HAS_ATTR(contentElem, "xpath") ? ATTR(contentElem, "xpath") : "/html/body"); + if (HAS_ATTR(contentElem, "attr")) + reply.headers["X-SCXML-Attr"] = ATTR(contentElem, "attr"); } // ss << req.getFirstDOMElement(); ss << req.dom; diff --git a/src/uscxml/transform/ChartToFSM.cpp b/src/uscxml/transform/ChartToFSM.cpp index 820e3bc..83b8195 100644 --- a/src/uscxml/transform/ChartToFSM.cpp +++ b/src/uscxml/transform/ChartToFSM.cpp @@ -216,7 +216,7 @@ InterpreterState FlatteningInterpreter::interpret() { initialElem.setAttribute("generated", "true"); Element<std::string> transitionElem = _document.createElementNS(_nsInfo.nsURL, "transition"); _nsInfo.setPrefix(transitionElem); - transitionElem.setAttribute("target", ATTR(initialStates[i], "id")); + transitionElem.setAttribute("target", ATTR_CAST(initialStates[i], "id")); initialElem.appendChild(transitionElem); _scxml.appendChild(initialElem); initialTransitions.push_back(transitionElem); @@ -277,14 +277,14 @@ void FlatteningInterpreter::executeContent(const Arabica::DOM::Element<std::stri _currGlobalTransition->actions.push_back(action); } -void FlatteningInterpreter::invoke(const Arabica::DOM::Node<std::string>& element) { +void FlatteningInterpreter::invoke(const Arabica::DOM::Element<std::string>& element) { GlobalTransition::Action action; action.invoke = element; _currGlobalTransition->actions.push_back(action); _currGlobalTransition->invoke.push_back(element); } -void FlatteningInterpreter::cancelInvoke(const Arabica::DOM::Node<std::string>& element) { +void FlatteningInterpreter::cancelInvoke(const Arabica::DOM::Element<std::string>& element) { GlobalTransition::Action action; action.uninvoke = element; _currGlobalTransition->actions.push_back(action); @@ -323,7 +323,7 @@ void FlatteningInterpreter::internalDoneSend(const Arabica::DOM::Element<std::st } } - raise.setAttribute("event", "done.state." + ATTR(stateElem.getParentNode(), "id")); // parent?! + raise.setAttribute("event", "done.state." + ATTR_CAST(stateElem.getParentNode(), "id")); // parent?! GlobalTransition::Action action; action.onEntry = onentry; @@ -379,8 +379,8 @@ static bool filterChildEnabled(const NodeSet<std::string>& transitions) { p2 = p2.getParentNode(); // TODO: think about again! while(p2) { if (p1 == p2) { - std::string eventDesc1 = ATTR(t1, "event"); - std::string eventDesc2 = ATTR(t2, "event"); + std::string eventDesc1 = ATTR_CAST(t1, "event"); + std::string eventDesc2 = ATTR_CAST(t2, "event"); if (InterpreterImpl::nameMatch(eventDesc1, eventDesc2)) { return false; } @@ -453,7 +453,7 @@ void FlatteningInterpreter::explode() { for (unsigned int i = 0; i < _statesToInvoke.size(); i++) { NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _statesToInvoke[i]); for (unsigned int j = 0; j < invokes.size(); j++) { - invoke(invokes[j]); + invoke(Element<std::string>(invokes[j])); } } _statesToInvoke = NodeSet<std::string>(); @@ -595,11 +595,11 @@ void FlatteningInterpreter::explode() { int nrDepth = 0; int prioPerLevel = 0; for (int i = 0; i < transitions.size(); i++) { - int depth = strTo<int>(ATTR(transitions[i], "depth")); + int depth = strTo<int>(ATTR_CAST(transitions[i], "depth")); if (depth != currDepth) continue; nrDepth++; - int order = strTo<int>(ATTR(transitions[i], "order")); + int order = strTo<int>(ATTR_CAST(transitions[i], "order")); if (order < lowestOrder) lowestOrder = order; prioPerLevel += pow(static_cast<double>(maxOrder), maxOrder - order); @@ -673,7 +673,7 @@ NEXT_DEPTH: } void FlatteningInterpreter::createDocument() { - Node<std::string> _origSCXML = _scxml; + Element<std::string> _origSCXML = _scxml; _scxml = _flatDoc.createElementNS(_nsInfo.nsURL, "scxml"); _nsInfo.setPrefix(_scxml); @@ -952,10 +952,11 @@ void FlatteningInterpreter::labelTransitions() { Arabica::XPath::NodeSet<std::string> states = getAllStates(); states.push_back(_scxml); for (int i = 0; i < states.size(); i++) { - std::string stateId = ATTR(states[i], "id"); - NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", states[i]); + Arabica::DOM::Element<std::string> stateElem = Arabica::DOM::Element<std::string>(states[i]); + std::string stateId = ATTR(stateElem, "id"); + NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", stateElem); // some transitions are in the inital elements - NodeSet<std::string> initials = filterChildElements(_nsInfo.xmlNSPrefix + "initial", states[i]); + NodeSet<std::string> initials = filterChildElements(_nsInfo.xmlNSPrefix + "initial", stateElem); transitions.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "transition", initials)); for (int j = 0; j < transitions.size(); j++) { Element<std::string> transition = Element<std::string>(transitions[j]); @@ -1014,12 +1015,12 @@ GlobalState::GlobalState(const Arabica::XPath::NodeSet<std::string>& activeState for (int i = 0; i < activeStates.size(); i++) { if (!InterpreterImpl::isFinal(Element<std::string>(activeStates[i]))) isFinal = false; - idSS << ATTR(activeStates[i], "id") << "-"; + idSS << ATTR_CAST(activeStates[i], "id") << "-"; } idSS << ";"; idSS << "entered-"; for (int i = 0; i < alreadyEnteredStates.size(); i++) { - idSS << ATTR(alreadyEnteredStates[i], "id") << "-"; + idSS << ATTR_CAST(alreadyEnteredStates[i], "id") << "-"; } idSS << ";"; @@ -1030,7 +1031,7 @@ GlobalState::GlobalState(const Arabica::XPath::NodeSet<std::string>& activeState idSS << "history--"; idSS << histIter->first << "-"; for (int i = 0; i < histStates.size(); i++) { - idSS << ATTR(histStates[i], "id") << "-"; + idSS << ATTR_CAST(histStates[i], "id") << "-"; } } @@ -1053,13 +1054,14 @@ GlobalTransition::GlobalTransition(const Arabica::XPath::NodeSet<std::string>& t std::list<std::string> conditions; std::ostringstream setId; // also build id for subset for (int i = 0; i < transitions.size(); i++) { + Arabica::DOM::Element<std::string> transElem = Arabica::DOM::Element<std::string>(transitions[i]); // get a unique string for the transition - we assume it is sorted - assert(HAS_ATTR(transitions[i], "id")); - setId << ATTR(transitions[i], "id") << "-"; + assert(HAS_ATTR(transElem, "id")); + setId << ATTR(transElem, "id") << "-"; // gather conditions while we are iterating anyway - if (HAS_ATTR(transitions[i], "cond")) { - conditions.push_back(ATTR(transitions[i], "cond")); + if (HAS_ATTR(transElem, "cond")) { + conditions.push_back(ATTR(transElem, "cond")); } } transitionId = setId.str(); @@ -1077,10 +1079,11 @@ GlobalTransition::GlobalTransition(const Arabica::XPath::NodeSet<std::string>& t bool foundTargetLess = false; for (int i = 0; i < transitions.size(); i++) { - if (HAS_ATTR(transitions[i], "eventexpr")) { + Arabica::DOM::Element<std::string> transElem = Arabica::DOM::Element<std::string>(transitions[i]); + if (HAS_ATTR(transElem, "eventexpr")) { ERROR_EXECUTION_THROW("Cannot flatten document with eventexpr attributes"); } - if (HAS_ATTR(transitions[i], "event")) { + if (HAS_ATTR(transElem, "event")) { foundWithEvent = true; if (foundEventLess) break; @@ -1089,7 +1092,7 @@ GlobalTransition::GlobalTransition(const Arabica::XPath::NodeSet<std::string>& t if (foundWithEvent) break; } - if (HAS_ATTR(transitions[i], "target")) { + if (HAS_ATTR(transElem, "target")) { foundWithTarget = true; if (foundTargetLess) break; @@ -1151,7 +1154,7 @@ std::list<std::string> GlobalTransition::getCommonEvents(const NodeSet<std::stri for (int i = 0; i < transitions.size(); i++) { // for every transition - std::list<std::string> eventNames = InterpreterImpl::tokenizeIdRefs(ATTR(transitions[i], "event")); + std::list<std::string> eventNames = InterpreterImpl::tokenizeIdRefs(ATTR_CAST(transitions[i], "event")); for (std::list<std::string>::iterator eventNameIter = eventNames.begin(); eventNameIter != eventNames.end(); @@ -1170,7 +1173,7 @@ std::list<std::string> GlobalTransition::getCommonEvents(const NodeSet<std::stri // check if token would activate all other transitions if (i == j) continue; - if (!InterpreterImpl::nameMatch(ATTR(transitions[j], "event"), eventName)) { + if (!InterpreterImpl::nameMatch(ATTR_CAST(transitions[j], "event"), eventName)) { isMatching = false; break; } diff --git a/src/uscxml/transform/ChartToFSM.h b/src/uscxml/transform/ChartToFSM.h index 0808a40..aeeb058 100644 --- a/src/uscxml/transform/ChartToFSM.h +++ b/src/uscxml/transform/ChartToFSM.h @@ -56,13 +56,13 @@ class USCXML_API GlobalTransition { public: class Action { public: - Arabica::DOM::Node<std::string> onEntry; - Arabica::DOM::Node<std::string> onExit; - Arabica::DOM::Node<std::string> transition; - Arabica::DOM::Node<std::string> entered; - Arabica::DOM::Node<std::string> exited; - Arabica::DOM::Node<std::string> invoke; - Arabica::DOM::Node<std::string> uninvoke; + Arabica::DOM::Element<std::string> onEntry; + Arabica::DOM::Element<std::string> onExit; + Arabica::DOM::Element<std::string> transition; + Arabica::DOM::Element<std::string> entered; + Arabica::DOM::Element<std::string> exited; + Arabica::DOM::Element<std::string> invoke; + Arabica::DOM::Element<std::string> uninvoke; }; GlobalTransition(const Arabica::XPath::NodeSet<std::string>& transitions, DataModel dataModel); @@ -112,11 +112,11 @@ protected: void executeContent(const Arabica::DOM::Element<std::string>& content, bool rethrow = false); // invoke and uninvoke - virtual void invoke(const Arabica::DOM::Node<std::string>& element); - virtual void cancelInvoke(const Arabica::DOM::Node<std::string>& element); + virtual void invoke(const Arabica::DOM::Element<std::string>& element); + virtual void cancelInvoke(const Arabica::DOM::Element<std::string>& element); // override to do nothing - void send(const Arabica::DOM::Node<std::string>& element) {} + void send(const Arabica::DOM::Element<std::string>& element) {} void internalDoneSend(const Arabica::DOM::Element<std::string>& state); // InterpreterMonitor diff --git a/src/uscxml/transform/FSMToCPP.cpp b/src/uscxml/transform/FSMToCPP.cpp index 6bf4535..980c389 100644 --- a/src/uscxml/transform/FSMToCPP.cpp +++ b/src/uscxml/transform/FSMToCPP.cpp @@ -56,14 +56,14 @@ void FSMToCPP::writeStates(std::ostream& stream) { stream << "// state name identifiers" << std::endl; for (int i = 0; i < _globalStates.size(); i++) { stream << "#define " << "s" << i << " " << i; - stream << " // from \"" << ATTR(_globalStates[i], "id") << "\"" << std::endl; + stream << " // from \"" << ATTR_CAST(_globalStates[i], "id") << "\"" << std::endl; } } -Arabica::XPath::NodeSet<std::string> FSMToCPP::getTransientContent(const Arabica::DOM::Node<std::string>& state) { +Arabica::XPath::NodeSet<std::string> FSMToCPP::getTransientContent(const Arabica::DOM::Element<std::string>& state) { Arabica::XPath::NodeSet<std::string> content; - Arabica::DOM::Node<std::string> currState = state; + Arabica::DOM::Element<std::string> currState = state; for (;;) { if (!HAS_ATTR(currState, "transient") || !DOMUtils::attributeIsTrue(ATTR(currState, "transient"))) break; @@ -71,24 +71,24 @@ Arabica::XPath::NodeSet<std::string> FSMToCPP::getTransientContent(const Arabica content.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "onentry", currState)); content.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "onexit", currState)); NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", currState); - currState = _states[ATTR(transitions[0], "target")]; + currState = _states[ATTR_CAST(transitions[0], "target")]; } return content; } -Node<std::string> FSMToCPP::getUltimateTarget(const Arabica::DOM::Node<std::string>& transition) { - Arabica::DOM::Node<std::string> currState = _states[ATTR(transition, "target")]; +Node<std::string> FSMToCPP::getUltimateTarget(const Arabica::DOM::Element<std::string>& transition) { + Arabica::DOM::Element<std::string> currState = _states[ATTR(transition, "target")]; for (;;) { if (!HAS_ATTR(currState, "transient") || !DOMUtils::attributeIsTrue(ATTR(currState, "transient"))) return currState; NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", currState); - currState = _states[ATTR(transitions[0], "target")]; + currState = _states[ATTR_CAST(transitions[0], "target")]; } } -void FSMToCPP::writeInlineComment(std::ostream& stream, const Arabica::DOM::Node<std::string>& node) { +void FSMToCPP::writeInlineComment(std::ostream& stream, const Arabica::DOM::Element<std::string>& node) { if (node.getNodeType() != Node_base::COMMENT_NODE) return; @@ -107,7 +107,7 @@ void FSMToCPP::writeInlineComment(std::ostream& stream, const Arabica::DOM::Node } } -void FSMToCPP::writeExecutableContent(std::ostream& stream, const Arabica::DOM::Node<std::string>& node, int indent) { +void FSMToCPP::writeExecutableContent(std::ostream& stream, const Arabica::DOM::Element<std::string>& node, int indent) { std::string padding; for (int i = 0; i < indent; i++) { @@ -140,12 +140,12 @@ void FSMToCPP::writeExecutableContent(std::ostream& stream, const Arabica::DOM:: if (HAS_ATTR(node, "transient") && DOMUtils::attributeIsTrue(ATTR(node, "transient"))) { Arabica::XPath::NodeSet<std::string> execContent = getTransientContent(node); for (int i = 0; i < execContent.size(); i++) { - writeExecutableContent(stream, execContent[i], indent); + writeExecutableContent(stream, Arabica::DOM::Element<std::string>(execContent[i]), indent); } } else { Arabica::DOM::Node<std::string> child = node.getFirstChild(); while(child) { - writeExecutableContent(stream, child, indent); + writeExecutableContent(stream, Arabica::DOM::Element<std::string>(child), indent); child = child.getNextSibling(); } } @@ -173,7 +173,7 @@ void FSMToCPP::writeExecutableContent(std::ostream& stream, const Arabica::DOM:: } else if(TAGNAME(node) == "onentry" || TAGNAME(node) == "onexit") { Arabica::DOM::Node<std::string> child = node.getFirstChild(); while(child) { - writeExecutableContent(stream, child, indent); + writeExecutableContent(stream, Arabica::DOM::Element<std::string>(child), indent); child = child.getNextSibling(); } @@ -192,7 +192,7 @@ void FSMToCPP::writeExecutableContent(std::ostream& stream, const Arabica::DOM:: stream << padding << "for (" << ATTR(node, "item") << " in " << ATTR(node, "array") << ") {" << std::endl; Arabica::DOM::Node<std::string> child = node.getFirstChild(); while(child) { - writeExecutableContent(stream, child, indent + 1); + writeExecutableContent(stream, Arabica::DOM::Element<std::string>(child), indent + 1); child = child.getNextSibling(); } if (HAS_ATTR(node, "index")) @@ -239,7 +239,7 @@ void FSMToCPP::writeIfBlock(std::ostream& stream, const Arabica::XPath::NodeSet< bool noNext = condChain.size() == 1; bool nextIsElse = false; if (condChain.size() > 1) { - if (TAGNAME(condChain[1]) == "else") { + if (TAGNAME_CAST(condChain[1]) == "else") { nextIsElse = true; } } @@ -248,20 +248,20 @@ void FSMToCPP::writeIfBlock(std::ostream& stream, const Arabica::XPath::NodeSet< stream << padding << "if" << std::endl; // we need to nest the elseifs to resolve promela if semantics - stream << padding << ":: (" << ATTR(ifNode, "cond") << ") -> {" << std::endl; + stream << padding << ":: (" << ATTR_CAST(ifNode, "cond") << ") -> {" << std::endl; Arabica::DOM::Node<std::string> child; - if (TAGNAME(ifNode) == "if") { + if (TAGNAME_CAST(ifNode) == "if") { child = ifNode.getFirstChild(); } else { child = ifNode.getNextSibling(); } while(child) { if (child.getNodeType() == Node_base::ELEMENT_NODE) { - if (TAGNAME(child) == "elseif" || TAGNAME(child) == "else") + if (TAGNAME_CAST(child) == "elseif" || TAGNAME_CAST(child) == "else") break; } - writeExecutableContent(stream, child, indent + 1); + writeExecutableContent(stream, Arabica::DOM::Element<std::string>(child), indent + 1); child = child.getNextSibling(); } stream << padding << "}" << std::endl; @@ -271,7 +271,7 @@ void FSMToCPP::writeIfBlock(std::ostream& stream, const Arabica::XPath::NodeSet< child = condChain[1].getNextSibling(); stream << "{" << std::endl; while(child) { - writeExecutableContent(stream, child, indent + 1); + writeExecutableContent(stream, Arabica::DOM::Element<std::string>(child), indent + 1); child = child.getNextSibling(); } stream << padding << "}" << std::endl; @@ -360,14 +360,14 @@ void FSMToCPP::writeFSM(std::ostream& stream) { transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _startState); assert(transitions.size() == 1); stream << " // transition's executable content" << std::endl; - writeExecutableContent(stream, transitions[0], 1); + writeExecutableContent(stream, Arabica::DOM::Element<std::string>(transitions[0]), 1); for (int i = 0; i < _globalStates.size(); i++) { if (_globalStates[i] == _startState) continue; NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _globalStates[i]); for (int j = 0; j < transitions.size(); j++) { - writeExecutableContent(stream, transitions[j], 1); + writeExecutableContent(stream, Arabica::DOM::Element<std::string>(transitions[j]), 1); } } @@ -424,7 +424,7 @@ void FSMToCPP::writeDispatchingBlock(std::ostream& stream, const Arabica::XPath: stream << padding << ":: ((0"; Node<std::string> currTrans = transChain[0]; - std::string eventDesc = ATTR(currTrans, "event"); + std::string eventDesc = ATTR_CAST(currTrans, "event"); if (boost::ends_with(eventDesc, "*")) eventDesc = eventDesc.substr(0, eventDesc.size() - 1); if (boost::ends_with(eventDesc, ".")) @@ -443,8 +443,8 @@ void FSMToCPP::writeDispatchingBlock(std::ostream& stream, const Arabica::XPath: } stream << ") && "; - stream << (HAS_ATTR(currTrans, "cond") ? ATTR(currTrans, "cond") : "1"); - stream << ") -> goto t" << _transitions[currTrans] << ";" << std::endl; + stream << (HAS_ATTR_CAST(currTrans, "cond") ? ATTR_CAST(currTrans, "cond") : "1"); + stream << ") -> goto t" << _transitions[Arabica::DOM::Element<std::string>(currTrans)] << ";" << std::endl; ; stream << padding << ":: else {" << std::endl; @@ -473,8 +473,9 @@ void FSMToCPP::initNodes() { // get all states NodeSet<std::string> states = filterChildElements(_nsInfo.xmlNSPrefix + "state", _scxml); for (int i = 0; i < states.size(); i++) { - _states[ATTR(states[i], "id")] = states[i]; - if (HAS_ATTR(states[i], "transient") && DOMUtils::attributeIsTrue(ATTR(states[i], "transient"))) + Arabica::DOM::Element<std::string> stateElem = Arabica::DOM::Element<std::string>(states[i]); + _states[ATTR(stateElem, "id")] = stateElem; + if (HAS_ATTR(stateElem, "transient") && DOMUtils::attributeIsTrue(ATTR(stateElem, "transient"))) continue; _globalStates.push_back(states[i]); } @@ -487,8 +488,8 @@ void FSMToCPP::initNodes() { internalEventNames.push_back(_xpath.evaluate("//" + _nsInfo.xpathPrefix + "send", _scxml).asNodeSet()); for (int i = 0; i < internalEventNames.size(); i++) { - if (HAS_ATTR(internalEventNames[i], "event")) { - std::string eventNames = ATTR(internalEventNames[i], "event"); + if (HAS_ATTR_CAST(internalEventNames[i], "event")) { + std::string eventNames = ATTR_CAST(internalEventNames[i], "event"); std::list<std::string> events = tokenizeIdRefs(eventNames); for (std::list<std::string>::iterator eventIter = events.begin(); eventIter != events.end(); eventIter++) { @@ -506,7 +507,7 @@ void FSMToCPP::initNodes() { NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true); int index = 0; for (int i = 0; i < transitions.size(); i++) { - _transitions[transitions[i]] = index++; + _transitions[Arabica::DOM::Element<std::string>(transitions[i])] = index++; } } diff --git a/src/uscxml/transform/FSMToCPP.h b/src/uscxml/transform/FSMToCPP.h index 59231b0..18df7c1 100644 --- a/src/uscxml/transform/FSMToCPP.h +++ b/src/uscxml/transform/FSMToCPP.h @@ -47,8 +47,8 @@ protected: void writeEvents(std::ostream& stream); void writeStates(std::ostream& stream); void writeDeclarations(std::ostream& stream); - void writeExecutableContent(std::ostream& stream, const Arabica::DOM::Node<std::string>& node, int indent = 0); - void writeInlineComment(std::ostream& stream, const Arabica::DOM::Node<std::string>& node); + void writeExecutableContent(std::ostream& stream, const Arabica::DOM::Element<std::string>& node, int indent = 0); + void writeInlineComment(std::ostream& stream, const Arabica::DOM::Element<std::string>& node); void writeFSM(std::ostream& stream); void writeEventDispatching(std::ostream& stream); void writeMain(std::ostream& stream); @@ -56,14 +56,14 @@ protected: void writeIfBlock(std::ostream& stream, const Arabica::XPath::NodeSet<std::string>& condChain, int indent = 0); void writeDispatchingBlock(std::ostream& stream, const Arabica::XPath::NodeSet<std::string>& transChain, int indent = 0); - Arabica::XPath::NodeSet<std::string> getTransientContent(const Arabica::DOM::Node<std::string>& state); - Arabica::DOM::Node<std::string> getUltimateTarget(const Arabica::DOM::Node<std::string>& transition); + Arabica::XPath::NodeSet<std::string> getTransientContent(const Arabica::DOM::Element<std::string>& state); + Arabica::DOM::Node<std::string> getUltimateTarget(const Arabica::DOM::Element<std::string>& transition); Trie _eventTrie; Arabica::XPath::NodeSet<std::string> _globalStates; - Arabica::DOM::Node<std::string> _startState; - std::map<std::string, Arabica::DOM::Node<std::string> > _states; - std::map<Arabica::DOM::Node<std::string>, int> _transitions; + Arabica::DOM::Element<std::string> _startState; + std::map<std::string, Arabica::DOM::Element<std::string> > _states; + std::map<Arabica::DOM::Element<std::string>, int> _transitions; }; diff --git a/src/uscxml/transform/FSMToPromela.cpp b/src/uscxml/transform/FSMToPromela.cpp index 3607071..238e40f 100644 --- a/src/uscxml/transform/FSMToPromela.cpp +++ b/src/uscxml/transform/FSMToPromela.cpp @@ -199,14 +199,14 @@ void FSMToPromela::writeStates(std::ostream& stream) { stream << "// state name identifiers" << std::endl; for (int i = 0; i < _globalStates.size(); i++) { stream << "#define " << "s" << i << " " << i; - stream << " // from \"" << ATTR(_globalStates[i], "id") << "\"" << std::endl; + stream << " // from \"" << ATTR_CAST(_globalStates[i], "id") << "\"" << std::endl; } } -Arabica::XPath::NodeSet<std::string> FSMToPromela::getTransientContent(const Arabica::DOM::Node<std::string>& state) { +Arabica::XPath::NodeSet<std::string> FSMToPromela::getTransientContent(const Arabica::DOM::Element<std::string>& state) { Arabica::XPath::NodeSet<std::string> content; - Arabica::DOM::Node<std::string> currState = state; + Arabica::DOM::Element<std::string> currState = state; for (;;) { if (!HAS_ATTR(currState, "transient") || !DOMUtils::attributeIsTrue(ATTR(currState, "transient"))) break; @@ -214,20 +214,20 @@ Arabica::XPath::NodeSet<std::string> FSMToPromela::getTransientContent(const Ara content.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "onentry", currState)); content.push_back(filterChildElements(_nsInfo.xmlNSPrefix + "onexit", currState)); NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", currState); - currState = _states[ATTR(transitions[0], "target")]; + currState = _states[ATTR_CAST(transitions[0], "target")]; } return content; } -Node<std::string> FSMToPromela::getUltimateTarget(const Arabica::DOM::Node<std::string>& transition) { - Arabica::DOM::Node<std::string> currState = _states[ATTR(transition, "target")]; +Node<std::string> FSMToPromela::getUltimateTarget(const Arabica::DOM::Element<std::string>& transition) { + Arabica::DOM::Element<std::string> currState = _states[ATTR_CAST(transition, "target")]; for (;;) { if (!HAS_ATTR(currState, "transient") || !DOMUtils::attributeIsTrue(ATTR(currState, "transient"))) return currState; NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", currState); - currState = _states[ATTR(transitions[0], "target")]; + currState = _states[ATTR_CAST(transitions[0], "target")]; } } @@ -250,7 +250,7 @@ void FSMToPromela::writeInlineComment(std::ostream& stream, const Arabica::DOM:: } } -void FSMToPromela::writeExecutableContent(std::ostream& stream, const Arabica::DOM::Node<std::string>& node, int indent) { +void FSMToPromela::writeExecutableContent(std::ostream& stream, const Arabica::DOM::Element<std::string>& node, int indent) { std::string padding; for (int i = 0; i < indent; i++) { @@ -283,12 +283,12 @@ void FSMToPromela::writeExecutableContent(std::ostream& stream, const Arabica::D if (HAS_ATTR(node, "transient") && DOMUtils::attributeIsTrue(ATTR(node, "transient"))) { Arabica::XPath::NodeSet<std::string> execContent = getTransientContent(node); for (int i = 0; i < execContent.size(); i++) { - writeExecutableContent(stream, execContent[i], indent); + writeExecutableContent(stream, Arabica::DOM::Element<std::string>(execContent[i]), indent); } } else { Arabica::DOM::Node<std::string> child = node.getFirstChild(); while(child) { - writeExecutableContent(stream, child, indent); + writeExecutableContent(stream, Arabica::DOM::Element<std::string>(child), indent); child = child.getNextSibling(); } } @@ -326,7 +326,7 @@ void FSMToPromela::writeExecutableContent(std::ostream& stream, const Arabica::D } else if(TAGNAME(node) == "onentry" || TAGNAME(node) == "onexit") { Arabica::DOM::Node<std::string> child = node.getFirstChild(); while(child) { - writeExecutableContent(stream, child, indent); + writeExecutableContent(stream, Arabica::DOM::Element<std::string>(child), indent); child = child.getNextSibling(); } @@ -345,7 +345,7 @@ void FSMToPromela::writeExecutableContent(std::ostream& stream, const Arabica::D stream << padding << "for (" << ATTR(node, "item") << " in " << ATTR(node, "array") << ") {" << std::endl; Arabica::DOM::Node<std::string> child = node.getFirstChild(); while(child) { - writeExecutableContent(stream, child, indent + 1); + writeExecutableContent(stream, Arabica::DOM::Element<std::string>(child), indent + 1); child = child.getNextSibling(); } if (HAS_ATTR(node, "index")) @@ -483,22 +483,22 @@ void FSMToPromela::writeIfBlock(std::ostream& stream, const Arabica::XPath::Node bool noNext = condChain.size() == 1; bool nextIsElse = false; if (condChain.size() > 1) { - if (TAGNAME(condChain[1]) == "else") { + if (TAGNAME_CAST(condChain[1]) == "else") { nextIsElse = true; } } - Node<std::string> ifNode = condChain[0]; + Element<std::string> ifNode = Element<std::string>(condChain[0]); stream << padding << "if" << std::endl; // we need to nest the elseifs to resolve promela if semantics stream << padding << ":: (" << ATTR(ifNode, "cond") << ") -> {" << std::endl; - Arabica::DOM::Node<std::string> child; + Arabica::DOM::Element<std::string> child; if (TAGNAME(ifNode) == "if") { - child = ifNode.getFirstChild(); + child = Arabica::DOM::Element<std::string>(ifNode.getFirstChild()); } else { - child = ifNode.getNextSibling(); + child = Arabica::DOM::Element<std::string>(ifNode.getNextSibling()); } while(child) { if (child.getNodeType() == Node_base::ELEMENT_NODE) { @@ -506,17 +506,17 @@ void FSMToPromela::writeIfBlock(std::ostream& stream, const Arabica::XPath::Node break; } writeExecutableContent(stream, child, indent + 1); - child = child.getNextSibling(); + child = Arabica::DOM::Element<std::string>(child.getNextSibling()); } stream << padding << "}" << std::endl; stream << padding << ":: else -> "; if (nextIsElse) { - child = condChain[1].getNextSibling(); + child = Arabica::DOM::Element<std::string>(condChain[1].getNextSibling()); stream << "{" << std::endl; while(child) { writeExecutableContent(stream, child, indent + 1); - child = child.getNextSibling(); + child = Arabica::DOM::Element<std::string>(child.getNextSibling()); } stream << padding << "}" << std::endl; @@ -630,14 +630,14 @@ void FSMToPromela::writeFSM(std::ostream& stream) { transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _startState); assert(transitions.size() == 1); stream << " // transition's executable content" << std::endl; - writeExecutableContent(stream, transitions[0], 1); + writeExecutableContent(stream, Arabica::DOM::Element<std::string>(transitions[0]), 1); for (int i = 0; i < _globalStates.size(); i++) { if (_globalStates[i] == _startState) continue; NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _globalStates[i]); for (int j = 0; j < transitions.size(); j++) { - writeExecutableContent(stream, transitions[j], 1); + writeExecutableContent(stream, Arabica::DOM::Element<std::string>(transitions[j]), 1); } } @@ -702,7 +702,7 @@ void FSMToPromela::writeDispatchingBlock(std::ostream& stream, const Arabica::XP stream << padding << "if" << std::endl; stream << padding << ":: ((0"; - Node<std::string> currTrans = transChain[0]; + Element<std::string> currTrans = Element<std::string>(transChain[0]); std::string eventDesc = ATTR(currTrans, "event"); if (boost::ends_with(eventDesc, "*")) eventDesc = eventDesc.substr(0, eventDesc.size() - 1); @@ -754,8 +754,8 @@ void FSMToPromela::initNodes() { // get all states NodeSet<std::string> states = filterChildElements(_nsInfo.xmlNSPrefix + "state", _scxml); for (int i = 0; i < states.size(); i++) { - _states[ATTR(states[i], "id")] = states[i]; - if (HAS_ATTR(states[i], "transient") && DOMUtils::attributeIsTrue(ATTR(states[i], "transient"))) + _states[ATTR_CAST(states[i], "id")] = Element<std::string>(states[i]); + if (HAS_ATTR_CAST(states[i], "transient") && DOMUtils::attributeIsTrue(ATTR_CAST(states[i], "transient"))) continue; _globalStates.push_back(states[i]); } @@ -768,8 +768,8 @@ void FSMToPromela::initNodes() { internalEventNames.push_back(_xpath.evaluate("//" + _nsInfo.xpathPrefix + "send", _scxml).asNodeSet()); for (int i = 0; i < internalEventNames.size(); i++) { - if (HAS_ATTR(internalEventNames[i], "event")) { - std::string eventNames = ATTR(internalEventNames[i], "event"); + if (HAS_ATTR_CAST(internalEventNames[i], "event")) { + std::string eventNames = ATTR_CAST(internalEventNames[i], "event"); std::list<std::string> events = tokenizeIdRefs(eventNames); for (std::list<std::string>::iterator eventIter = events.begin(); eventIter != events.end(); eventIter++) { @@ -793,17 +793,17 @@ void FSMToPromela::initNodes() { PromelaInlines promInls = getInlinePromela(promelaEventSourceComments[i]); PromelaEventSource promES(promInls, promelaEventSourceComments[i].getParentNode()); - if (TAGNAME(promelaEventSourceComments[i].getParentNode()) == "scxml") { + if (TAGNAME_CAST(promelaEventSourceComments[i].getParentNode()) == "scxml") { promES.type = PromelaEventSource::PROMELA_EVENT_SOURCE_GLOBAL; promES.trie = &_eventTrie; promES.name = "global"; _globalEventSource = promES; - } else if (TAGNAME(promelaEventSourceComments[i].getParentNode()) == "invoke") { - if (!HAS_ATTR(promelaEventSourceComments[i].getParentNode(), "invokeid")) { + } else if (TAGNAME_CAST(promelaEventSourceComments[i].getParentNode()) == "invoke") { + if (!HAS_ATTR_CAST(promelaEventSourceComments[i].getParentNode(), "invokeid")) { Element<std::string> invoker = Element<std::string>(promelaEventSourceComments[i].getParentNode()); invoker.setAttribute("invokeid", "invoker" + toStr(_invokers.size())); } - std::string invokeId = ATTR(promelaEventSourceComments[i].getParentNode(), "invokeid"); + std::string invokeId = ATTR_CAST(promelaEventSourceComments[i].getParentNode(), "invokeid"); promES.type = PromelaEventSource::PROMELA_EVENT_SOURCE_INVOKER; promES.trie = &_eventTrie; promES.name = invokeId; @@ -815,7 +815,7 @@ void FSMToPromela::initNodes() { NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", _scxml, true); int index = 0; for (int i = 0; i < transitions.size(); i++) { - _transitions[transitions[i]] = index++; + _transitions[Element<std::string>(transitions[i])] = index++; } } diff --git a/src/uscxml/transform/FSMToPromela.h b/src/uscxml/transform/FSMToPromela.h index e507fdc..62381cd 100644 --- a/src/uscxml/transform/FSMToPromela.h +++ b/src/uscxml/transform/FSMToPromela.h @@ -129,7 +129,7 @@ protected: void writeStates(std::ostream& stream); void writeDeclarations(std::ostream& stream); void writeEventSources(std::ostream& stream); - void writeExecutableContent(std::ostream& stream, const Arabica::DOM::Node<std::string>& node, int indent = 0); + void writeExecutableContent(std::ostream& stream, const Arabica::DOM::Element<std::string>& node, int indent = 0); void writeInlineComment(std::ostream& stream, const Arabica::DOM::Node<std::string>& node); void writeFSM(std::ostream& stream); void writeEventDispatching(std::ostream& stream); @@ -138,8 +138,8 @@ protected: void writeIfBlock(std::ostream& stream, const Arabica::XPath::NodeSet<std::string>& condChain, int indent = 0); void writeDispatchingBlock(std::ostream& stream, const Arabica::XPath::NodeSet<std::string>& transChain, int indent = 0); - Arabica::XPath::NodeSet<std::string> getTransientContent(const Arabica::DOM::Node<std::string>& state); - Arabica::DOM::Node<std::string> getUltimateTarget(const Arabica::DOM::Node<std::string>& transition); + Arabica::XPath::NodeSet<std::string> getTransientContent(const Arabica::DOM::Element<std::string>& state); + Arabica::DOM::Node<std::string> getUltimateTarget(const Arabica::DOM::Element<std::string>& transition); static PromelaInlines getInlinePromela(const std::string&); static PromelaInlines getInlinePromela(const Arabica::XPath::NodeSet<std::string>& elements, bool recurse = false); @@ -148,8 +148,8 @@ protected: Trie _eventTrie; Arabica::XPath::NodeSet<std::string> _globalStates; Arabica::DOM::Node<std::string> _startState; - std::map<std::string, Arabica::DOM::Node<std::string> > _states; - std::map<Arabica::DOM::Node<std::string>, int> _transitions; + std::map<std::string, Arabica::DOM::Element<std::string> > _states; + std::map<Arabica::DOM::Element<std::string>, int> _transitions; std::map<std::string, PromelaEventSource> _invokers; PromelaEventSource _globalEventSource; diff --git a/test/src/test-w3c.cpp b/test/src/test-w3c.cpp index 65b56dd..7eb54a7 100644 --- a/test/src/test-w3c.cpp +++ b/test/src/test-w3c.cpp @@ -135,7 +135,7 @@ class W3CStatusMonitor : public uscxml::InterpreterMonitor { void printNodeSet(const Arabica::XPath::NodeSet<std::string>& config) { std::string seperator; for (int i = 0; i < config.size(); i++) { - std::cout << seperator << ATTR(config[i], "id"); + std::cout << seperator << ATTR_CAST(config[i], "id"); seperator = ", "; } } @@ -144,13 +144,13 @@ class W3CStatusMonitor : public uscxml::InterpreterMonitor { Arabica::XPath::NodeSet<std::string> config = interpreter.getConfiguration(); if (config.size() == 1) { if (withFlattening) { - std::cout << ATTR(config[0], "id") << std::endl; - if (boost::starts_with(ATTR(config[0], "id"), "active-pass")) { + std::cout << ATTR_CAST(config[0], "id") << std::endl; + if (boost::starts_with(ATTR_CAST(config[0], "id"), "active-pass")) { std::cout << "TEST SUCCEEDED" << std::endl; exit(EXIT_SUCCESS); } } else { - if (boost::iequals(ATTR(config[0], "id"), "pass")) { + if (boost::iequals(ATTR_CAST(config[0], "id"), "pass")) { std::cout << "TEST SUCCEEDED" << std::endl; exit(EXIT_SUCCESS); } diff --git a/test/uscxml/test-performance-events.scxml b/test/uscxml/test-performance-events.scxml new file mode 100644 index 0000000..0af8272 --- /dev/null +++ b/test/uscxml/test-performance-events.scxml @@ -0,0 +1,28 @@ +<scxml datamodel="ecmascript"> + <datamodel> + <data id="iterations">100000</data> + <data id="test"> + { + string: 'bar', + integer: 12, + float: 234243.2342 + } + </data> + </datamodel> + <state id="start"> + <transition target="loop" /> + </state> + <state id="loop"> + <onentry> + <raise event="continue"> + <content> + this is space normalized! + </content> + </raise> + <script>iterations--;</script> + </onentry> + <transition event="continue" cond="iterations > 0" target="start" /> + <transition cond="iterations == 0" target="final" /> + </state> + <final id="final" /> +</scxml>
\ No newline at end of file |