summaryrefslogtreecommitdiffstats
path: root/src/uscxml/interpreter/InterpreterRC.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/uscxml/interpreter/InterpreterRC.cpp')
-rw-r--r--src/uscxml/interpreter/InterpreterRC.cpp396
1 files changed, 212 insertions, 184 deletions
diff --git a/src/uscxml/interpreter/InterpreterRC.cpp b/src/uscxml/interpreter/InterpreterRC.cpp
index 52b36e0..10c41d0 100644
--- a/src/uscxml/interpreter/InterpreterRC.cpp
+++ b/src/uscxml/interpreter/InterpreterRC.cpp
@@ -50,17 +50,17 @@ void InterpreterRC::interpret() {
tthread::lock_guard<tthread::recursive_mutex> lock(_mutex);
if (!_isInitialized)
init();
-
+
if (!_scxml) {
return;
}
// dump();
-
+
// just make sure we have a session id
assert(_sessionId.length() > 0);
-
+
setupIOProcessors();
-
+
std::string datamodelName;
if (datamodelName.length() == 0 && HAS_ATTR(_scxml, "datamodel"))
datamodelName = ATTR(_scxml, "datamodel");
@@ -79,79 +79,89 @@ void InterpreterRC::interpret() {
if(datamodelName.length() > 0 && !_dataModel) {
LOG(ERROR) << "No datamodel for " << datamodelName << " registered";
}
-
+
if (_dataModel) {
_dataModel.assign("_x.args", _cmdLineOptions);
}
-
+
_running = true;
_binding = (HAS_ATTR(_scxml, "binding") && iequals(ATTR(_scxml, "binding"), "late") ? LATE : EARLY);
-
+
// @TODO: Reread http://www.w3.org/TR/scxml/#DataBinding
-
+
if (_dataModel && _binding == EARLY) {
// initialize all data elements
- NodeSet<std::string> dataElems = _xpath.evaluate("//" + _xpathPrefix + "data", _scxml).asNodeSet();
+ NodeSet<std::string> dataElems = _xpath.evaluate("//" + _nsInfo.xpathPrefix + "data", _scxml).asNodeSet();
for (unsigned int i = 0; i < dataElems.size(); i++) {
// do not process data elements of nested documents from invokers
- if (!getAncestorElement(dataElems[i], _xmlNSPrefix + "invoke"))
+ if (!getAncestorElement(dataElems[i], _nsInfo.xmlNSPrefix + "invoke"))
if (dataElems[i].getNodeType() == Node_base::ELEMENT_NODE) {
initializeData(Element<std::string>(dataElems[i]));
}
}
} else if(_dataModel) {
// initialize current data elements
- NodeSet<std::string> topDataElems = filterChildElements(_xmlNSPrefix + "data", filterChildElements(_xmlNSPrefix + "datamodel", _scxml));
+ NodeSet<std::string> topDataElems = filterChildElements(_nsInfo.xmlNSPrefix + "data", filterChildElements(_nsInfo.xmlNSPrefix + "datamodel", _scxml));
for (unsigned int i = 0; i < topDataElems.size(); i++) {
if (topDataElems[i].getNodeType() == Node_base::ELEMENT_NODE)
initializeData(Element<std::string>(topDataElems[i]));
}
}
-
+
// executeGlobalScriptElements
- NodeSet<std::string> globalScriptElems = filterChildElements(_xmlNSPrefix + "script", _scxml);
+ NodeSet<std::string> globalScriptElems = filterChildElements(_nsInfo.xmlNSPrefix + "script", _scxml);
for (unsigned int i = 0; i < globalScriptElems.size(); i++) {
if (_dataModel) {
executeContent(globalScriptElems[i]);
}
}
-
+
NodeSet<std::string> initialTransitions;
-
+
if (_userDefinedStartConfiguration.size() > 0) {
// we emulate entering a given configuration by creating a pseudo deep history
- Element<std::string> initHistory = _document.createElementNS(_nsURL, "history");
+ Element<std::string> initHistory = _document.createElementNS(_nsInfo.nsURL, "history");
+ _nsInfo.setPrefix(initHistory);
+
initHistory.setAttribute("id", UUID::getUUID());
initHistory.setAttribute("type", "deep");
_scxml.insertBefore(initHistory, _scxml.getFirstChild());
-
+
std::string histId = ATTR(initHistory, "id");
NodeSet<std::string> histStates;
for (int i = 0; i < _userDefinedStartConfiguration.size(); i++) {
histStates.push_back(getState(_userDefinedStartConfiguration[i]));
}
_historyValue[histId] = histStates;
-
- Element<std::string> initialElem = _document.createElementNS(_nsURL, "initial");
+
+ Element<std::string> initialElem = _document.createElementNS(_nsInfo.nsURL, "initial");
+ _nsInfo.setPrefix(initialElem);
+
initialElem.setAttribute("generated", "true");
- Element<std::string> transitionElem = _document.createElementNS(_nsURL, "transition");
+ Element<std::string> transitionElem = _document.createElementNS(_nsInfo.nsURL, "transition");
+ _nsInfo.setPrefix(transitionElem);
+
transitionElem.setAttribute("target", histId);
initialElem.appendChild(transitionElem);
_scxml.appendChild(initialElem);
initialTransitions.push_back(transitionElem);
-
+
} else {
// try to get initial transition from initial element
- initialTransitions = _xpath.evaluate("/" + _xpathPrefix + "initial/" + _xpathPrefix + "transition", _scxml).asNodeSet();
+ initialTransitions = _xpath.evaluate("/" + _nsInfo.xpathPrefix + "initial/" + _nsInfo.xpathPrefix + "transition", _scxml).asNodeSet();
if (initialTransitions.size() == 0) {
Arabica::XPath::NodeSet<std::string> initialStates;
// fetch per draft
initialStates = getInitialStates();
assert(initialStates.size() > 0);
for (int i = 0; i < initialStates.size(); i++) {
- Element<std::string> initialElem = _document.createElementNS(_nsURL, "initial");
+ Element<std::string> initialElem = _document.createElementNS(_nsInfo.nsURL, "initial");
+ _nsInfo.setPrefix(initialElem);
+
initialElem.setAttribute("generated", "true");
- Element<std::string> transitionElem = _document.createElementNS(_nsURL, "transition");
+ Element<std::string> transitionElem = _document.createElementNS(_nsInfo.nsURL, "transition");
+ _nsInfo.setPrefix(transitionElem);
+
transitionElem.setAttribute("target", ATTR(initialStates[i], "id"));
initialElem.appendChild(transitionElem);
_scxml.appendChild(initialElem);
@@ -159,12 +169,12 @@ void InterpreterRC::interpret() {
}
}
}
-
+
assert(initialTransitions.size() > 0);
-
+
enterStates(initialTransitions);
// _mutex.unlock();
-
+
// assert(hasLegalConfiguration());
mainEventLoop();
} catch (boost::bad_weak_ptr e) {
@@ -173,7 +183,7 @@ void InterpreterRC::interpret() {
// set datamodel to null from this thread
if(_dataModel)
_dataModel = DataModel();
-
+
}
/**
@@ -181,12 +191,12 @@ procedure mainEventLoop():
while running:
enabledTransitions = null
macrostepDone = false
- # Here we handle eventless transitions and transitions
+ # Here we handle eventless transitions and transitions
# triggered by internal events until macrostep is complete
while running and not macrostepDone:
enabledTransitions = selectEventlessTransitions()
if enabledTransitions.isEmpty():
- if internalQueue.isEmpty():
+ if internalQueue.isEmpty():
macrostepDone = true
else:
internalEvent = internalQueue.dequeue()
@@ -194,7 +204,7 @@ procedure mainEventLoop():
enabledTransitions = selectTransitions(internalEvent)
if not enabledTransitions.isEmpty():
microstep(enabledTransitions.toList())
- # either we're in a final state, and we break out of the loop
+ # either we're in a final state, and we break out of the loop
if not running:
break;
# or we've completed a macrostep, so we start a new macrostep by waiting for an external event
@@ -203,7 +213,7 @@ procedure mainEventLoop():
for inv in state.invoke:
invoke(inv)
statesToInvoke.clear()
- # Invoking may have raised internal error events and we iterate to handle them
+ # Invoking may have raised internal error events and we iterate to handle them
if not internalQueue.isEmpty():
continue
# A blocking wait for an external event. Alternatively, if we have been invoked
@@ -219,24 +229,24 @@ procedure mainEventLoop():
if inv.invokeid == externalEvent.invokeid:
applyFinalize(inv, externalEvent)
if inv.autoforward:
- send(inv.id, externalEvent)
+ send(inv.id, externalEvent)
enabledTransitions = selectTransitions(externalEvent)
if not enabledTransitions.isEmpty():
- microstep(enabledTransitions.toList())
- # End of outer while running loop. If we get here, we have reached a top-level final state or have been cancelled
- exitInterpreter()
+ microstep(enabledTransitions.toList())
+ # End of outer while running loop. If we get here, we have reached a top-level final state or have been cancelled
+ exitInterpreter()
*/
void InterpreterRC::mainEventLoop() {
monIter_t monIter;
-
+
while(_running) {
NodeSet<std::string> enabledTransitions;
_stable = false;
-
+
// Here we handle eventless transitions and transitions
// triggered by internal events until machine is stable
while(_running && !_stable) {
-
+
enabledTransitions = selectEventlessTransitions();
if (enabledTransitions.size() == 0) {
if (_internalQueue.size() == 0) {
@@ -244,14 +254,15 @@ void InterpreterRC::mainEventLoop() {
} else {
_currEvent = _internalQueue.front();
_internalQueue.pop_front();
-
+
// --- MONITOR: beforeProcessingEvent ------------------------------
for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) {
try {
(*monIter)->beforeProcessingEvent(shared_from_this(), _currEvent);
- } USCXML_MONITOR_CATCH_BLOCK(beforeProcessingEvent)
+ }
+ USCXML_MONITOR_CATCH_BLOCK(beforeProcessingEvent)
}
-
+
if (_dataModel)
_dataModel.setEvent(_currEvent);
enabledTransitions = selectTransitions(_currEvent.name);
@@ -263,12 +274,12 @@ void InterpreterRC::mainEventLoop() {
microstep(enabledTransitions);
}
}
-
+
if (!_running)
goto EXIT_INTERPRETER;
for (unsigned int i = 0; i < _statesToInvoke.size(); i++) {
- NodeSet<std::string> invokes = filterChildElements(_xmlNSPrefix + "invoke", _statesToInvoke[i]);
+ NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _statesToInvoke[i]);
for (unsigned int j = 0; j < invokes.size(); j++) {
invoke(invokes[j]);
}
@@ -277,7 +288,7 @@ void InterpreterRC::mainEventLoop() {
if (!_internalQueue.empty())
continue;
-
+
// assume that we have a legal configuration as soon as the internal queue is empty
if (!hasLegalConfiguration()) {
std::cout << "Illegal configuration!" << std::endl;
@@ -287,26 +298,27 @@ void InterpreterRC::mainEventLoop() {
std::cout << std::endl;
}
assert(hasLegalConfiguration());
-
+
monIter = _monitors.begin();
// if (!_sendQueue || _sendQueue->isEmpty()) {
-
+
// --- MONITOR: onStableConfiguration ------------------------------
for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) {
try {
(*monIter)->onStableConfiguration(shared_from_this());
- } USCXML_MONITOR_CATCH_BLOCK(onStableConfiguration)
+ }
+ USCXML_MONITOR_CATCH_BLOCK(onStableConfiguration)
}
-
+
// }
-
+
_mutex.unlock();
// whenever we have a stable configuration, run the mainThread hooks with 200fps
while(_externalQueue.isEmpty() && _thread == NULL) {
runOnMainThread(200);
}
_mutex.lock();
-
+
// A blocking wait for an external event. Alternatively, if we have been invoked
// our parent session also might cancel us. The mechanism for this is platform specific,
// but here we assume it's a special event we receive
@@ -321,17 +333,18 @@ void InterpreterRC::mainEventLoop() {
_currEvent.eventType = Event::EXTERNAL; // make sure it is set to external
if (!_running)
goto EXIT_INTERPRETER;
-
+
// --- MONITOR: beforeProcessingEvent ------------------------------
for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) {
try {
(*monIter)->beforeProcessingEvent(shared_from_this(), _currEvent);
- } USCXML_MONITOR_CATCH_BLOCK(beforeProcessingEvent)
+ }
+ USCXML_MONITOR_CATCH_BLOCK(beforeProcessingEvent)
}
-
+
if (_dataModel && iequals(_currEvent.name, "cancel.invoke." + _sessionId))
break;
-
+
if (_dataModel) {
try {
_dataModel.setEvent(_currEvent);
@@ -340,7 +353,7 @@ void InterpreterRC::mainEventLoop() {
}
}
for (unsigned int i = 0; i < _configuration.size(); i++) {
- NodeSet<std::string> invokes = filterChildElements(_xmlNSPrefix + "invoke", _configuration[i]);
+ NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", _configuration[i]);
for (unsigned int j = 0; j < invokes.size(); j++) {
Element<std::string> invokeElem = (Element<std::string>)invokes[j];
std::string invokeId;
@@ -357,13 +370,13 @@ void InterpreterRC::mainEventLoop() {
}
std::string autoForward = invokeElem.getAttribute("autoforward");
if (iequals(invokeId, _currEvent.invokeid)) {
-
- Arabica::XPath::NodeSet<std::string> finalizes = filterChildElements(_xmlNSPrefix + "finalize", invokeElem);
+
+ Arabica::XPath::NodeSet<std::string> finalizes = filterChildElements(_nsInfo.xmlNSPrefix + "finalize", invokeElem);
for (int k = 0; k < finalizes.size(); k++) {
Element<std::string> finalizeElem = Element<std::string>(finalizes[k]);
executeContent(finalizeElem);
}
-
+
}
if (iequals(autoForward, "true")) {
try {
@@ -384,15 +397,16 @@ void InterpreterRC::mainEventLoop() {
microstep(enabledTransitions);
}
}
-
+
EXIT_INTERPRETER:
// --- MONITOR: beforeCompletion ------------------------------
for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) {
try {
(*monIter)->beforeCompletion(shared_from_this());
- } USCXML_MONITOR_CATCH_BLOCK(beforeCompletion)
+ }
+ USCXML_MONITOR_CATCH_BLOCK(beforeCompletion)
}
-
+
exitInterpreter();
if (_sendQueue) {
std::map<std::string, std::pair<InterpreterImpl*, SendRequest> >::iterator sendIter = _sendIds.begin();
@@ -401,14 +415,15 @@ EXIT_INTERPRETER:
sendIter++;
}
}
-
+
// --- MONITOR: afterCompletion ------------------------------
for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) {
try {
(*monIter)->afterCompletion(shared_from_this());
- } USCXML_MONITOR_CATCH_BLOCK(afterCompletion)
+ }
+ USCXML_MONITOR_CATCH_BLOCK(afterCompletion)
}
-
+
}
/**
@@ -420,7 +435,7 @@ procedure exitInterpreter():
for inv in s.invoke:
cancelInvoke(inv)
configuration.delete(s)
- if isFinalState(s) and isScxmlState(s.parent):
+ if isFinalState(s) and isScxmlState(s.parent):
returnDoneEvent(s.donedata)
*/
void InterpreterRC::exitInterpreter() {
@@ -429,11 +444,11 @@ void InterpreterRC::exitInterpreter() {
statesToExit.sort();
for (int i = 0; i < statesToExit.size(); i++) {
- Arabica::XPath::NodeSet<std::string> onExitElems = filterChildElements(_xmlNSPrefix + "onexit", statesToExit[i]);
+ Arabica::XPath::NodeSet<std::string> onExitElems = filterChildElements(_nsInfo.xmlNSPrefix + "onexit", statesToExit[i]);
for (int j = 0; j < onExitElems.size(); j++) {
executeContent(onExitElems[j]);
}
- Arabica::XPath::NodeSet<std::string> invokeElems = filterChildElements(_xmlNSPrefix + "invoke", statesToExit[i]);
+ Arabica::XPath::NodeSet<std::string> invokeElems = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", statesToExit[i]);
for (int j = 0; j < invokeElems.size(); j++) {
cancelInvoke(invokeElems[j]);
}
@@ -451,7 +466,7 @@ function selectEventlessTransitions():
for state in atomicStates:
loop: for s in [state].append(getProperAncestors(state, null)):
for t in s.transition:
- if not t.event and conditionMatch(t):
+ if not t.event and conditionMatch(t):
enabledTransitions.add(t)
break loop
enabledTransitions = removeConflictingTransitions(enabledTransitions)
@@ -459,7 +474,7 @@ function selectEventlessTransitions():
*/
Arabica::XPath::NodeSet<std::string> InterpreterRC::selectEventlessTransitions() {
Arabica::XPath::NodeSet<std::string> enabledTransitions;
-
+
NodeSet<std::string> atomicStates;
for (unsigned int i = 0; i < _configuration.size(); i++) {
if (isAtomic(_configuration[i]))
@@ -474,7 +489,7 @@ Arabica::XPath::NodeSet<std::string> InterpreterRC::selectEventlessTransitions()
withAncestors.push_back(getProperAncestors(state, Node<std::string>()));
for (unsigned int j = 0; j < withAncestors.size(); j++) {
const Node<std::string>& ancestor = withAncestors[i];
- NodeSet<std::string> transitions = filterChildElements(_xmlNSPrefix + "transition", ancestor);
+ NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", ancestor);
for (unsigned int k = 0; k < transitions.size(); k++) {
if (!HAS_ATTR(transitions[k], "event") && hasConditionMatch(transitions[k])) {
enabledTransitions.push_back(transitions[k]);
@@ -482,9 +497,10 @@ Arabica::XPath::NodeSet<std::string> InterpreterRC::selectEventlessTransitions()
}
}
}
- BREAK_LOOP:;
+BREAK_LOOP:
+ ;
}
-
+
enabledTransitions = removeConflictingTransitions(enabledTransitions);
return enabledTransitions;
}
@@ -504,14 +520,14 @@ function selectTransitions(event):
*/
Arabica::XPath::NodeSet<std::string> InterpreterRC::selectTransitions(const std::string& event) {
Arabica::XPath::NodeSet<std::string> enabledTransitions;
-
+
NodeSet<std::string> atomicStates;
for (unsigned int i = 0; i < _configuration.size(); i++) {
if (isAtomic(_configuration[i]))
atomicStates.push_back(_configuration[i]);
}
atomicStates.to_document_order();
-
+
#if 0
std::cout << "selectTransitions for " << event << "========" << std::endl;
#endif
@@ -520,13 +536,13 @@ Arabica::XPath::NodeSet<std::string> InterpreterRC::selectTransitions(const std:
#if 0
std::cout << " == from " << ATTR(state, "id") << std::endl;
#endif
-
+
NodeSet<std::string> withAncestors;
withAncestors.push_back(state);
withAncestors.push_back(getProperAncestors(state, Node<std::string>()));
for (unsigned int j = 0; j < withAncestors.size(); j++) {
const Node<std::string>& ancestor = withAncestors[j];
- NodeSet<std::string> transitions = filterChildElements(_xmlNSPrefix + "transition", ancestor);
+ NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", ancestor);
for (unsigned int k = 0; k < transitions.size(); k++) {
if (isEnabledTransition(transitions[k], event)) {
enabledTransitions.push_back(transitions[k]);
@@ -534,9 +550,10 @@ Arabica::XPath::NodeSet<std::string> InterpreterRC::selectTransitions(const std:
}
}
}
- BREAK_LOOP:;
+BREAK_LOOP:
+ ;
}
-
+
enabledTransitions = removeConflictingTransitions(enabledTransitions);
#if 0
@@ -564,7 +581,7 @@ bool InterpreterRC::isEnabledTransition(const Node<std::string>& transition, con
} else {
return false;
}
-
+
std::list<std::string> eventNames = tokenizeIdRefs(eventName);
std::list<std::string>::iterator eventIter = eventNames.begin();
while(eventIter != eventNames.end()) {
@@ -588,19 +605,19 @@ function removeConflictingTransitions(enabledTransitions):
if computeExitSet([t1]).hasIntersection(computeExitSet([t2])):
if isDescendant(t1.source, t2.source):
transitionsToRemove.add(t2)
- else:
+ else:
t1Preempted = true
break
if not t1Preempted:
for t3 in transitionsToRemove.toList():
filteredTransitions.delete(t3)
filteredTransitions.add(t1)
-
+
return filteredTransitions
*/
Arabica::XPath::NodeSet<std::string> InterpreterRC::removeConflictingTransitions(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) {
Arabica::XPath::NodeSet<std::string> filteredTransitions;
-
+
for (unsigned int i = 0; i < enabledTransitions.size(); i++) {
const Node<std::string>& t1 = enabledTransitions[i];
bool t1Preempted = false;
@@ -617,7 +634,7 @@ Arabica::XPath::NodeSet<std::string> InterpreterRC::removeConflictingTransitions
}
}
}
-
+
if (!t1Preempted) {
// remove transitionsToRemove from filteredTransitions
std::list<Node<std::string> > tmp;
@@ -652,58 +669,62 @@ procedure microstep(enabledTransitions):
enterStates(enabledTransitions)
*/
void InterpreterRC::microstep(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) {
-
+
// --- MONITOR: beforeMicroStep ------------------------------
for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) {
try {
(*monIter)->beforeMicroStep(shared_from_this());
- } USCXML_MONITOR_CATCH_BLOCK(beforeMicroStep)
+ }
+ USCXML_MONITOR_CATCH_BLOCK(beforeMicroStep)
}
-
+
exitStates(enabledTransitions);
-
+
monIter_t monIter;
for (int i = 0; i < enabledTransitions.size(); i++) {
Element<std::string> transition(enabledTransitions[i]);
-
+
// --- MONITOR: beforeTakingTransitions ------------------------------
for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) {
try {
(*monIter)->beforeTakingTransition(shared_from_this(), transition, (i + 1 < enabledTransitions.size()));
- } USCXML_MONITOR_CATCH_BLOCK(beforeTakingTransitions)
+ }
+ USCXML_MONITOR_CATCH_BLOCK(beforeTakingTransitions)
}
-
+
executeContent(transition);
-
+
// --- MONITOR: afterTakingTransitions ------------------------------
for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) {
try {
(*monIter)->afterTakingTransition(shared_from_this(), transition, (i + 1 < enabledTransitions.size()));
- } USCXML_MONITOR_CATCH_BLOCK(afterTakingTransitions)
+ }
+ USCXML_MONITOR_CATCH_BLOCK(afterTakingTransitions)
}
}
-
+
enterStates(enabledTransitions);
-
+
// --- MONITOR: afterMicroStep ------------------------------
for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) {
try {
(*monIter)->afterMicroStep(shared_from_this());
- } USCXML_MONITOR_CATCH_BLOCK(afterMicroStep)
+ }
+ USCXML_MONITOR_CATCH_BLOCK(afterMicroStep)
}
}
/**
procedure exitStates(enabledTransitions):
- statesToExit = computeExitSet(enabledTransitions)
+ statesToExit = computeExitSet(enabledTransitions)
for s in statesToExit:
statesToInvoke.delete(s)
statesToExit = statesToExit.toList().sort(exitOrder)
for s in statesToExit:
for h in s.history:
if h.type == "deep":
- f = lambda s0: isAtomicState(s0) and isDescendant(s0,s)
+ f = lambda s0: isAtomicState(s0) and isDescendant(s0,s)
else:
f = lambda s0: s0.parent == s
historyValue[h.id] = configuration.toList().filter(f)
@@ -730,9 +751,9 @@ void InterpreterRC::exitStates(const Arabica::XPath::NodeSet<std::string>& enabl
statesToExit.forward(false);
statesToExit.sort();
-
+
for (int i = 0; i < statesToExit.size(); i++) {
- NodeSet<std::string> histories = filterChildElements(_xmlNSPrefix + "history", statesToExit[i]);
+ NodeSet<std::string> histories = filterChildElements(_nsInfo.xmlNSPrefix + "history", statesToExit[i]);
for (int j = 0; j < histories.size(); j++) {
Element<std::string> historyElem = (Element<std::string>)histories[j];
std::string historyType = (historyElem.hasAttribute("type") ? historyElem.getAttribute("type") : "shallow");
@@ -749,34 +770,36 @@ void InterpreterRC::exitStates(const Arabica::XPath::NodeSet<std::string>& enabl
_historyValue[historyElem.getAttribute("id")] = historyNodes;
}
}
-
+
for (int i = 0; i < statesToExit.size(); i++) {
// --- MONITOR: beforeExitingState ------------------------------
for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) {
try {
(*monIter)->beforeExitingState(shared_from_this(), Element<std::string>(statesToExit[i]), (i + 1 < statesToExit.size()));
- } USCXML_MONITOR_CATCH_BLOCK(beforeExitingState)
+ }
+ USCXML_MONITOR_CATCH_BLOCK(beforeExitingState)
}
-
- NodeSet<std::string> onExits = filterChildElements(_xmlNSPrefix + "onExit", statesToExit[i]);
+
+ NodeSet<std::string> onExits = filterChildElements(_nsInfo.xmlNSPrefix + "onExit", statesToExit[i]);
for (int j = 0; j < onExits.size(); j++) {
Element<std::string> onExitElem = (Element<std::string>)onExits[j];
executeContent(onExitElem);
}
-
+
// --- MONITOR: afterExitingState ------------------------------
for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) {
try {
(*monIter)->afterExitingState(shared_from_this(), Element<std::string>(statesToExit[i]), (i + 1 < statesToExit.size()));
- } USCXML_MONITOR_CATCH_BLOCK(afterExitingState)
+ }
+ USCXML_MONITOR_CATCH_BLOCK(afterExitingState)
}
-
- NodeSet<std::string> invokes = filterChildElements(_xmlNSPrefix + "invoke", statesToExit[i]);
+
+ NodeSet<std::string> invokes = filterChildElements(_nsInfo.xmlNSPrefix + "invoke", statesToExit[i]);
for (int j = 0; j < invokes.size(); j++) {
Element<std::string> invokeElem = (Element<std::string>)invokes[j];
cancelInvoke(invokeElem);
}
-
+
// remove statesToExit[i] from _configuration - test409
tmp.clear();
for (int j = 0; j < _configuration.size(); j++) {
@@ -799,7 +822,7 @@ function computeExitSet(transitions)
for s in configuration:
if isDescendant(s,domain):
statesToExit.add(s)
- return statesToExit
+ return statesToExit
*/
Arabica::XPath::NodeSet<std::string> InterpreterRC::computeExitSet(const Arabica::XPath::NodeSet<std::string>& transitions) {
NodeSet<std::string> statesToExit;
@@ -832,13 +855,13 @@ Arabica::XPath::NodeSet<std::string> InterpreterRC::computeExitSet(const Arabica
transitions.push_back(transition);
return computeExitSet(transitions);
}
-
+
/**
procedure enterStates(enabledTransitions):
statesToEnter = new OrderedSet()
statesForDefaultEntry = new OrderedSet()
- computeEntrySet(enabledTransitions, statesToEnter, statesForDefaultEntry)
+ computeEntrySet(enabledTransitions, statesToEnter, statesForDefaultEntry)
for s in statesToEnter.toList().sort(entryOrder):
configuration.add(s)
statesToInvoke.add(s)
@@ -866,28 +889,29 @@ void InterpreterRC::enterStates(const Arabica::XPath::NodeSet<std::string>& enab
// initialize the temporary table for default content in history states
std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent;
monIter_t monIter;
-
+
computeEntrySet(enabledTransitions, statesToEnter, statesForDefaultEntry, defaultHistoryContent);
statesToEnter.to_document_order();
-
+
for (int i = 0; i < statesToEnter.size(); i++) {
Element<std::string> s = (Element<std::string>)statesToEnter[i];
-
+
// --- MONITOR: beforeEnteringState ------------------------------
for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) {
try {
(*monIter)->beforeEnteringState(shared_from_this(), s, (i + 1 < statesToEnter.size()));
- } USCXML_MONITOR_CATCH_BLOCK(beforeEnteringState)
+ }
+ USCXML_MONITOR_CATCH_BLOCK(beforeEnteringState)
}
-
+
_configuration.push_back(s);
_statesToInvoke.push_back(s);
-
+
// if (_binding == LATE && stateElem.getAttribute("isFirstEntry").size() > 0) {
if (_binding == LATE && !isMember(s, _alreadyEntered)) {
- NodeSet<std::string> dataModelElems = filterChildElements(_xmlNSPrefix + "datamodel", s);
+ NodeSet<std::string> dataModelElems = filterChildElements(_nsInfo.xmlNSPrefix + "datamodel", s);
if(dataModelElems.size() > 0 && _dataModel) {
- Arabica::XPath::NodeSet<std::string> dataElems = filterChildElements(_xmlNSPrefix + "data", dataModelElems[0]);
+ Arabica::XPath::NodeSet<std::string> dataElems = filterChildElements(_nsInfo.xmlNSPrefix + "data", dataModelElems[0]);
for (int j = 0; j < dataElems.size(); j++) {
if (dataElems[j].getNodeType() == Node_base::ELEMENT_NODE)
initializeData(Element<std::string>(dataElems[j]));
@@ -897,19 +921,20 @@ void InterpreterRC::enterStates(const Arabica::XPath::NodeSet<std::string>& enab
// stateElem.setAttribute("isFirstEntry", "");
}
// execute onentry executable content
- NodeSet<std::string> onEntryElems = filterChildElements(_xmlNSPrefix + "onEntry", s);
+ NodeSet<std::string> onEntryElems = filterChildElements(_nsInfo.xmlNSPrefix + "onEntry", s);
executeContent(onEntryElems, false);
-
+
// --- MONITOR: afterEnteringState ------------------------------
for(monIter_t monIter = _monitors.begin(); monIter != _monitors.end(); monIter++) {
try {
(*monIter)->afterEnteringState(shared_from_this(), s, (i + 1 < statesToEnter.size()));
- } USCXML_MONITOR_CATCH_BLOCK(afterEnteringState)
+ }
+ USCXML_MONITOR_CATCH_BLOCK(afterEnteringState)
}
-
+
if (isMember(s, statesForDefaultEntry)) {
// execute initial transition content for compound states
- Arabica::XPath::NodeSet<std::string> transitions = _xpath.evaluate("" + _xpathPrefix + "initial/" + _xpathPrefix + "transition", s).asNodeSet();
+ Arabica::XPath::NodeSet<std::string> transitions = _xpath.evaluate("" + _nsInfo.xpathPrefix + "initial/" + _nsInfo.xpathPrefix + "transition", s).asNodeSet();
for (int j = 0; j < transitions.size(); j++) {
executeContent(transitions[j]);
}
@@ -917,18 +942,18 @@ void InterpreterRC::enterStates(const Arabica::XPath::NodeSet<std::string>& enab
if (defaultHistoryContent.find(ATTR(s, "id")) != defaultHistoryContent.end()) {
executeContent(defaultHistoryContent[ATTR(s, "id")]);
}
-
+
/**
- if isFinalState(s):
- if isSCXMLElement(s.parent):
- running = false
- else:
- parent = s.parent
- grandparent = parent.parent
- internalQueue.enqueue(new Event("done.state." + parent.id, s.donedata))
- if isParallelState(grandparent):
- if getChildStates(grandparent).every(isInFinalState):
- internalQueue.enqueue(new Event("done.state." + grandparent.id))
+ if isFinalState(s):
+ if isSCXMLElement(s.parent):
+ running = false
+ else:
+ parent = s.parent
+ grandparent = parent.parent
+ internalQueue.enqueue(new Event("done.state." + parent.id, s.donedata))
+ if isParallelState(grandparent):
+ if getChildStates(grandparent).every(isInFinalState):
+ internalQueue.enqueue(new Event("done.state." + grandparent.id))
*/
//std::cout << _name << ": " << s << std::endl;
@@ -940,9 +965,9 @@ void InterpreterRC::enterStates(const Arabica::XPath::NodeSet<std::string>& enab
} else {
Element<std::string> parent = (Element<std::string>)s.getParentNode();
Element<std::string> grandParent = (Element<std::string>)parent.getParentNode();
-
+
internalDoneSend(parent);
-
+
if (isParallel(grandParent)) {
Arabica::XPath::NodeSet<std::string> childs = getChildStates(grandParent);
bool inFinalState = true;
@@ -965,18 +990,18 @@ void InterpreterRC::enterStates(const Arabica::XPath::NodeSet<std::string>& enab
/**
procedure computeEntrySet(transitions, statesToEnter, statesForDefaultEntry)
for t in transitions:
- statesToEnter.union(getTargetStates(t.target))
+ statesToEnter.union(getTargetStates(t.target))
for s in statesToEnter:
- addDescendantStatesToEnter(s,statesToEnter,statesForDefaultEntry)
- for t in transitions:
- ancestor = getTransitionDomain(t)
- for s in getTargetStates(t.target)):
+ addDescendantStatesToEnter(s,statesToEnter,statesForDefaultEntry)
+ for t in transitions:
+ ancestor = getTransitionDomain(t)
+ for s in getTargetStates(t.target)):
addAncestorStatesToEnter(s, ancestor, statesToEnter, statesForDefaultEntry)
*/
void InterpreterRC::computeEntrySet(const Arabica::XPath::NodeSet<std::string>& transitions,
- NodeSet<std::string>& statesToEnter,
- NodeSet<std::string>& statesForDefaultEntry,
- std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent) {
+ NodeSet<std::string>& statesToEnter,
+ NodeSet<std::string>& statesForDefaultEntry,
+ std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent) {
for (int i = 0; i < transitions.size(); i++) {
const Node<std::string>& t = transitions[i];
@@ -1001,7 +1026,7 @@ void InterpreterRC::computeEntrySet(const Arabica::XPath::NodeSet<std::string>&
assert(tmp[i]);
addDescendantStatesToEnter(tmp[i],statesToEnter,statesForDefaultEntry, defaultHistoryContent);
}
-
+
#if 1
std::cout << "after addDescendantStatesToEnter: ";
for (int i = 0; i < statesToEnter.size(); i++) {
@@ -1009,7 +1034,7 @@ void InterpreterRC::computeEntrySet(const Arabica::XPath::NodeSet<std::string>&
}
std::cout << std::endl;
#endif
-
+
for (int i = 0; i < transitions.size(); i++) {
Element<std::string> t = (Element<std::string>)transitions[i];
Node<std::string> ancestor = getTransitionDomain(t);
@@ -1030,9 +1055,9 @@ void InterpreterRC::computeEntrySet(const Arabica::XPath::NodeSet<std::string>&
}
void InterpreterRC::computeEntrySet(const Arabica::DOM::Node<std::string>& transition,
- NodeSet<std::string>& statesToEnter,
- NodeSet<std::string>& statesForDefaultEntry,
- std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent) {
+ NodeSet<std::string>& statesToEnter,
+ NodeSet<std::string>& statesForDefaultEntry,
+ std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent) {
Arabica::XPath::NodeSet<std::string> transitions;
transitions.push_back(transition);
computeEntrySet(transitions, statesToEnter, statesForDefaultEntry, defaultHistoryContent);
@@ -1062,12 +1087,12 @@ procedure addDescendantStatesToEnter(state,statesToEnter,statesForDefaultEntry):
if isParallelState(state):
for child in getChildStates(state):
if not statesToEnter.some(lambda s: isDescendant(s,child)):
- addDescendantStatesToEnter(child,statesToEnter,statesForDefaultEntry)
+ addDescendantStatesToEnter(child,statesToEnter,statesForDefaultEntry)
*/
void InterpreterRC::addDescendantStatesToEnter(const Arabica::DOM::Node<std::string>& state,
- Arabica::XPath::NodeSet<std::string>& statesToEnter,
- Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry,
- std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent) {
+ Arabica::XPath::NodeSet<std::string>& statesToEnter,
+ Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry,
+ std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent) {
if (isHistory(state)) {
std::string stateId = ATTR(state, "id");
if (_historyValue.find(stateId) != _historyValue.end()) {
@@ -1078,7 +1103,7 @@ void InterpreterRC::addDescendantStatesToEnter(const Arabica::DOM::Node<std::str
addAncestorStatesToEnter(s, getParentState(s), statesToEnter, statesForDefaultEntry, defaultHistoryContent);
}
} else {
- NodeSet<std::string> transitions = filterChildElements(_xmlNSPrefix + "transition", state);
+ NodeSet<std::string> transitions = filterChildElements(_nsInfo.xmlNSPrefix + "transition", state);
if (transitions.size() > 0) {
defaultHistoryContent[ATTR(state, "id")] = transitions[0];
}
@@ -1097,7 +1122,7 @@ void InterpreterRC::addDescendantStatesToEnter(const Arabica::DOM::Node<std::str
} else {
if (!isMember(state, statesToEnter)) // adding an existing element invalidates old reference
statesToEnter.push_back(state);
-
+
if (isCompound(state)) {
statesForDefaultEntry.push_back(state);
NodeSet<std::string> targets = getInitialStates(state);
@@ -1119,7 +1144,8 @@ void InterpreterRC::addDescendantStatesToEnter(const Arabica::DOM::Node<std::str
}
}
addDescendantStatesToEnter(child,statesToEnter,statesForDefaultEntry, defaultHistoryContent);
- BREAK_LOOP:;
+BREAK_LOOP:
+ ;
}
}
}
@@ -1133,13 +1159,13 @@ procedure addAncestorStatesToEnter(state, ancestor, statesToEnter, statesForDefa
if isParallelState(anc):
for child in getChildStates(anc):
if not statesToEnter.some(lambda s: isDescendant(s,child)):
- addDescendantStatesToEnter(child,statesToEnter,statesForDefaultEntry)
+ addDescendantStatesToEnter(child,statesToEnter,statesForDefaultEntry)
*/
void InterpreterRC::addAncestorStatesToEnter(const Arabica::DOM::Node<std::string>& state,
- const Arabica::DOM::Node<std::string>& ancestor,
- Arabica::XPath::NodeSet<std::string>& statesToEnter,
- Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry,
- std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent) {
+ const Arabica::DOM::Node<std::string>& ancestor,
+ Arabica::XPath::NodeSet<std::string>& statesToEnter,
+ Arabica::XPath::NodeSet<std::string>& statesForDefaultEntry,
+ std::map<std::string, Arabica::DOM::Node<std::string> > defaultHistoryContent) {
NodeSet<std::string> ancestors = getProperAncestors(state,ancestor);
for (int i = 0; i < ancestors.size(); i++) {
const Node<std::string>& anc = ancestors[i];
@@ -1155,7 +1181,8 @@ void InterpreterRC::addAncestorStatesToEnter(const Arabica::DOM::Node<std::strin
}
}
addDescendantStatesToEnter(child,statesToEnter,statesForDefaultEntry, defaultHistoryContent);
- BREAK_LOOP:;
+BREAK_LOOP:
+ ;
}
}
}
@@ -1202,16 +1229,16 @@ function getTransitionDomain(t)
Arabica::DOM::Node<std::string> InterpreterRC::getTransitionDomain(const Arabica::DOM::Node<std::string>& transition) {
NodeSet<std::string> tStates = getTargetStates(transition);
Node<std::string> source = getSourceState(transition);
-
+
#if 0
std::cout << "getTransitionDomain: " << std::endl << transition << std::endl;
#endif
-
+
if (tStates.size() == 0) {
return Arabica::DOM::Node<std::string>(); // null
}
std::string transitionType = (HAS_ATTR(transition, "type") ? ATTR(transition, "type") : "external");
-
+
if (iequals(transitionType, "internal") && isCompound(source)) {
for (int i = 0; i < tStates.size(); i++) {
const Node<std::string>& s = tStates[i];
@@ -1220,7 +1247,8 @@ Arabica::DOM::Node<std::string> InterpreterRC::getTransitionDomain(const Arabica
}
return source;
}
-BREAK_LOOP:;
+BREAK_LOOP:
+ ;
Arabica::XPath::NodeSet<std::string> states;
states.push_back(source);
states.push_back(tStates);
@@ -1247,10 +1275,10 @@ Arabica::DOM::Node<std::string> InterpreterRC::findLCCA(const Arabica::XPath::No
}
ancestor = ancestors[i];
break;
- NEXT_ANCESTOR:
+NEXT_ANCESTOR:
;
}
-
+
// take uppermost root as ancestor
if (!ancestor)
ancestor = _scxml;
@@ -1261,22 +1289,22 @@ Arabica::DOM::Node<std::string> InterpreterRC::findLCCA(const Arabica::XPath::No
/**
If state2 is null, returns the set of all ancestors of state1 in ancestry order
(state1's parent followed by the parent's parent, etc. up to an including the
- <scxml> element). If state2 is non-null, returns inancestry order the set of all
- ancestors of state1, up to but not including state2. (A "proper ancestor" of a
- state is its parent, or the parent's parent, or the parent's parent's parent,
- etc.)) If state2 is state1's parent, or equal to state1, or a descendant of
+ <scxml> element). If state2 is non-null, returns inancestry order the set of all
+ ancestors of state1, up to but not including state2. (A "proper ancestor" of a
+ state is its parent, or the parent's parent, or the parent's parent's parent,
+ etc.)) If state2 is state1's parent, or equal to state1, or a descendant of
state1, this returns the empty set.
*/
Arabica::XPath::NodeSet<std::string> InterpreterRC::getProperAncestors(const Arabica::DOM::Node<std::string>& state1, const Arabica::DOM::Node<std::string>& state2) {
NodeSet<std::string> ancestors;
-
+
if (!state1 || !isState(state1))
return ancestors;
if (!state2) {
/**
- If state2 is null, returns the set of all ancestors of state1 in ancestry
- order (state1's parent followed by the parent's parent, etc. up to an
+ If state2 is null, returns the set of all ancestors of state1 in ancestry
+ order (state1's parent followed by the parent's parent, etc. up to an
including the <scxml> element).
*/
Arabica::DOM::Node<std::string> parent = state1.getParentNode();
@@ -1287,16 +1315,16 @@ Arabica::XPath::NodeSet<std::string> InterpreterRC::getProperAncestors(const Ara
return ancestors;
}
- /**
+ /**
If state2 is state1's parent, or equal to state1, or a descendant of
- state1, this returns the empty set
+ state1, this returns the empty set
*/
if (state1.getParentNode() == state2 || state1 == state2 || isDescendant(state2, state1)) {
return ancestors;
}
-
+
/**
- If state2 is non-null, returns in ancestry order the set of all ancestors
+ If state2 is non-null, returns in ancestry order the set of all ancestors
of state1, up to but not including state2.
*/
Arabica::DOM::Node<std::string> parent = state1.getParentNode();
@@ -1309,7 +1337,7 @@ Arabica::XPath::NodeSet<std::string> InterpreterRC::getProperAncestors(const Ara
NodeSet<std::string> InterpreterRC::getTargetStates(const Arabica::DOM::Node<std::string>& transition) {
NodeSet<std::string> targetStates;
-
+
std::string targetId = ((Arabica::DOM::Element<std::string>)transition).getAttribute("target");
std::list<std::string> targetIds = InterpreterImpl::tokenizeIdRefs(ATTR(transition, "target"));
if (targetIds.size() > 0) {
@@ -1332,14 +1360,14 @@ NodeSet<std::string> InterpreterRC::getTargetStates(const Arabica::DOM::Node<std
Returns 'true' if state1 is a descendant of state2 (a child, or a child of a child, or a child of a child of a child, etc.) Otherwise returns 'false'.
*/
bool InterpreterRC::isDescendant(const Arabica::DOM::Node<std::string>& state1, const Arabica::DOM::Node<std::string>& state2) {
- return false;
+ return false;
}
/**
Returns a list containing all <state>, <final>, and <parallel> children of state1.
*/
Arabica::XPath::NodeSet<std::string> InterpreterRC::getChildStates(const Arabica::DOM::Node<std::string>& state) {
- return Arabica::XPath::NodeSet<std::string>();
+ return Arabica::XPath::NodeSet<std::string>();
}
#endif