summaryrefslogtreecommitdiffstats
path: root/src/uscxml/interpreter/FastMicroStep.cpp
diff options
context:
space:
mode:
authorStefan Radomski <github@mintwerk.de>2016-06-13 08:52:55 (GMT)
committerStefan Radomski <github@mintwerk.de>2016-06-13 08:52:55 (GMT)
commit053e9bc973fbe88fc41a34064ffadc0deabac58d (patch)
tree6aeee286577159ffcb612d41972a9d18ab685c6d /src/uscxml/interpreter/FastMicroStep.cpp
parent6e13c7b6e0888323223afd5d2e36e86243df57af (diff)
downloaduscxml-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.cpp60
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;
}
}