diff --git a/src/uscxml/interpreter/FastMicroStep.cpp b/src/uscxml/interpreter/FastMicroStep.cpp index 78aada954..ed6238f5e 100644 --- a/src/uscxml/interpreter/FastMicroStep.cpp +++ b/src/uscxml/interpreter/FastMicroStep.cpp @@ -217,21 +217,27 @@ std::pair FastMicroStep::getExitSet(const Transition* transi statesToExit.first = domainState->documentOrder + 1; // do not include domain itself // end of exit set - XERCESC_NS::DOMElement* sibling = domainState->element->getNextElementSibling(); - while(sibling && !isState(sibling)) - sibling = sibling->getNextElementSibling(); - if (sibling) { - State* siblingState = (State*)sibling->getUserData(X("uscxmlState")); - statesToExit.second = siblingState->documentOrder - 1; - } else { - statesToExit.second = _states.size() - 1; + statesToExit.second = statesToExit.first; + + uint32_t second = statesToExit.first + 1; + + while (second < _states.size()) { + State *childState = _states[second]; + + if (childState->ancestors[domain]) { + statesToExit.second = second; + } else { + break; + } + + second++; } + _exitSetCache[transition->postFixOrder] = statesToExit; - return statesToExit; } + return _exitSetCache[transition->postFixOrder]; } - uint32_t FastMicroStep::getTransitionDomain(const Transition* transition) { size_t i, j; if (!transition->target.any()) diff --git a/src/uscxml/interpreter/LargeMicroStep.cpp b/src/uscxml/interpreter/LargeMicroStep.cpp index a6d90f4d1..ae3193c60 100644 --- a/src/uscxml/interpreter/LargeMicroStep.cpp +++ b/src/uscxml/interpreter/LargeMicroStep.cpp @@ -1319,21 +1319,27 @@ std::pair LargeMicroStep::getExitSet(const Transition* trans statesToExit.first = domainState->documentOrder + 1; // do not include domain itself // end of exit set - XERCESC_NS::DOMElement* sibling = domainState->element->getNextElementSibling(); - while(sibling && !isState(sibling)) - sibling = sibling->getNextElementSibling(); - if (sibling) { - State* siblingState = (State*)sibling->getUserData(X("uscxmlState")); - statesToExit.second = siblingState->documentOrder - 1; - } else { - statesToExit.second = _states.size() - 1; + statesToExit.second = statesToExit.first; + + uint32_t second = statesToExit.first + 1; + + while (second < _states.size()) { + State *childState = _states[second]; + + if (childState->ancestors.find(domainState) != childState->ancestors.end()) { + statesToExit.second = second; + } else { + break; + } + + second++; } + _exitSetCache[transition->postFixOrder] = statesToExit; - return statesToExit; } + return _exitSetCache[transition->postFixOrder]; } - uint32_t LargeMicroStep::getTransitionDomain(const Transition* transition) { if (transition->target.size() == 0) return std::numeric_limits::max();