diff options
author | Stefan Radomski <github@mintwerk.de> | 2016-06-13 08:52:55 (GMT) |
---|---|---|
committer | Stefan Radomski <github@mintwerk.de> | 2016-06-13 08:52:55 (GMT) |
commit | 053e9bc973fbe88fc41a34064ffadc0deabac58d (patch) | |
tree | 6aeee286577159ffcb612d41972a9d18ab685c6d /src/uscxml/interpreter/FastMicroStep.cpp | |
parent | 6e13c7b6e0888323223afd5d2e36e86243df57af (diff) | |
download | uscxml-053e9bc973fbe88fc41a34064ffadc0deabac58d.zip uscxml-053e9bc973fbe88fc41a34064ffadc0deabac58d.tar.gz uscxml-053e9bc973fbe88fc41a34064ffadc0deabac58d.tar.bz2 |
Fixed dozens of memory leaks
Diffstat (limited to 'src/uscxml/interpreter/FastMicroStep.cpp')
-rw-r--r-- | src/uscxml/interpreter/FastMicroStep.cpp | 60 |
1 files changed, 48 insertions, 12 deletions
diff --git a/src/uscxml/interpreter/FastMicroStep.cpp b/src/uscxml/interpreter/FastMicroStep.cpp index 3ad5515..927fbbc 100644 --- a/src/uscxml/interpreter/FastMicroStep.cpp +++ b/src/uscxml/interpreter/FastMicroStep.cpp @@ -155,8 +155,35 @@ void FastMicroStep::resortStates(DOMNode* node, const X& xmlPrefix) { } } -void FastMicroStep::init(XERCESC_NS::DOMElement* scxml) { +std::list<XERCESC_NS::DOMElement*> FastMicroStep::getExitSetCached(const XERCESC_NS::DOMElement* transition, + const XERCESC_NS::DOMElement* root) { + + if (_cache.exitSet.find(transition) == _cache.exitSet.end()) { + _cache.exitSet[transition] = getExitSet(transition, root); + } + + return _cache.exitSet[transition]; +} + +bool FastMicroStep::conflictsCached(const DOMElement* t1, const DOMElement* t2, const DOMElement* root) { + if (getSourceState(t1) == getSourceState(t2)) + return true; + + if (DOMUtils::isDescendant(getSourceState(t1), getSourceState(t2))) + return true; + if (DOMUtils::isDescendant(getSourceState(t2), getSourceState(t1))) + return true; + + if (DOMUtils::hasIntersection(getExitSetCached(t1, root), getExitSetCached(t2, root))) + return true; + + return false; +} + + +void FastMicroStep::init(XERCESC_NS::DOMElement* scxml) { + _scxml = scxml; _binding = (HAS_ATTR(_scxml, "binding") && iequals(ATTR(_scxml, "binding"), "late") ? LATE : EARLY); _xmlPrefix = _scxml->getPrefix(); @@ -331,7 +358,9 @@ void FastMicroStep::init(XERCESC_NS::DOMElement* scxml) { // establish the transitions' exit set assert(_transitions[i]->element != NULL); // std::cout << "i: " << i << std::endl << std::flush; - std::list<DOMElement*> exitList = getExitSet(_transitions[i]->element, _scxml); + std::list<DOMElement*> exitList = getExitSetCached(_transitions[i]->element, _scxml); + _cache.exitSet[_transitions[i]->element] = exitList; + for (j = 0; j < _states.size(); j++) { if (!exitList.empty() && _states[j]->element == exitList.front()) { _transitions[i]->exitSet[j] = true; @@ -343,14 +372,21 @@ void FastMicroStep::init(XERCESC_NS::DOMElement* scxml) { assert(exitList.size() == 0); // establish the transitions' conflict set - for (j = 0; j < _transitions.size(); j++) { - if (conflicts(_transitions[i]->element, _transitions[j]->element, _scxml)) { + for (j = i; j < _transitions.size(); j++) { + if (conflictsCached(_transitions[i]->element, _transitions[j]->element, _scxml)) { _transitions[i]->conflicts[j] = true; } else { _transitions[i]->conflicts[j] = false; } +// std::cout << "."; } + + // conflicts matrix is symmetric + for (j = 0; j < i; j++) { + _transitions[i]->conflicts[j] = _transitions[j]->conflicts[i]; + } + // establish the transitions' target set std::list<std::string> targets = tokenize(ATTR(_transitions[i]->element, "target")); for (auto tIter = targets.begin(); tIter != targets.end(); tIter++) { @@ -387,8 +423,10 @@ void FastMicroStep::init(XERCESC_NS::DOMElement* scxml) { // the transitions event and condition - _transitions[i]->event = (HAS_ATTR(_transitions[i]->element, "event") ? ATTR(_transitions[i]->element, "event") : ""); - _transitions[i]->cond = (HAS_ATTR(_transitions[i]->element, "cond") ? ATTR(_transitions[i]->element, "cond") : ""); + _transitions[i]->event = (HAS_ATTR(_transitions[i]->element, "event") ? + ATTR(_transitions[i]->element, "event") : ""); + _transitions[i]->cond = (HAS_ATTR(_transitions[i]->element, "cond") ? + ATTR(_transitions[i]->element, "cond") : ""); // is there executable content? if (_transitions[i]->element->getChildElementCount() > 0) { @@ -396,6 +434,7 @@ void FastMicroStep::init(XERCESC_NS::DOMElement* scxml) { } } + _cache.exitSet.clear(); _isInitialized = true; } @@ -1030,12 +1069,9 @@ std::list<DOMElement*> FastMicroStep::getCompletion(const DOMElement* state) { completion.push_back(initElems.front()); } else { // first child state - DOMNodeList* children = state->getChildNodes(); - for (size_t i = 0; i < children->getLength(); i++) { - if (children->item(i)->getNodeType() != DOMNode::ELEMENT_NODE) - continue; - if (isState(dynamic_cast<DOMElement*>(children->item(i)))) { - completion.push_back(dynamic_cast<DOMElement*>(children->item(i))); + for (auto childElem = state->getFirstElementChild(); childElem; childElem = childElem->getNextElementSibling()) { + if (isState(childElem)) { + completion.push_back(childElem); break; } } |