summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-02-08 12:26:42 (GMT)
committerStefan Radomski <radomski@tk.informatik.tu-darmstadt.de>2013-02-08 12:26:42 (GMT)
commit71a3ca4fd78d7a9cca844e81f29f48b9c36bd4c7 (patch)
tree57a294052ce41ed131f458d4fb083fce3b743ef4 /src
parent275bf3fd017ca27c021d4c10cc9d3d82fff13922 (diff)
downloaduscxml-71a3ca4fd78d7a9cca844e81f29f48b9c36bd4c7.zip
uscxml-71a3ca4fd78d7a9cca844e81f29f48b9c36bd4c7.tar.gz
uscxml-71a3ca4fd78d7a9cca844e81f29f48b9c36bd4c7.tar.bz2
Fixed history
Diffstat (limited to 'src')
-rw-r--r--src/uscxml/Factory.cpp7
-rw-r--r--src/uscxml/Interpreter.cpp244
-rw-r--r--src/uscxml/Interpreter.h11
-rw-r--r--src/uscxml/Message.cpp121
-rw-r--r--src/uscxml/Message.h14
-rw-r--r--src/uscxml/URL.cpp2
-rw-r--r--src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp8
-rw-r--r--src/uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.cpp48
-rw-r--r--src/uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.h42
-rw-r--r--src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.cpp1
-rw-r--r--src/uscxml/plugins/invoker/sqlite3/Sqlite3Invoker.cpp44
-rw-r--r--src/uscxml/plugins/invoker/sqlite3/Sqlite3Invoker.h40
-rw-r--r--src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.cpp34
-rw-r--r--src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.h12
14 files changed, 533 insertions, 95 deletions
diff --git a/src/uscxml/Factory.cpp b/src/uscxml/Factory.cpp
index 623dbaf..4481257 100644
--- a/src/uscxml/Factory.cpp
+++ b/src/uscxml/Factory.cpp
@@ -20,6 +20,7 @@
# ifdef OPENSCENEGRAPH_FOUND
# include "uscxml/plugins/invoker/graphics/openscenegraph/OSGInvoker.h"
+# include "uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.h"
# endif
# ifdef MILES_FOUND
@@ -95,6 +96,10 @@ Factory::Factory() {
OSGInvoker* invoker = new OSGInvoker();
registerInvoker(invoker);
}
+ {
+ OSGConverter* invoker = new OSGConverter();
+ registerInvoker(invoker);
+ }
#endif
#ifdef V8_FOUND
@@ -252,7 +257,7 @@ void IOProcessorImpl::returnEvent(Event& event) {
_interpreter->receive(event);
}
-
+
Factory* Factory::_instance = NULL;
std::string Factory::pluginPath;
} \ No newline at end of file
diff --git a/src/uscxml/Interpreter.cpp b/src/uscxml/Interpreter.cpp
index 04604fd..5b947a7 100644
--- a/src/uscxml/Interpreter.cpp
+++ b/src/uscxml/Interpreter.cpp
@@ -117,7 +117,9 @@ bool Interpreter::toAbsoluteURI(URL& uri) {
}
void Interpreter::startPrefixMapping(const std::string& prefix, const std::string& uri) {
+#if 0
std::cout << "starting prefix mapping " << prefix << ": " << uri << std::endl;
+#endif
if (boost::iequals(uri, "http://www.w3.org/2005/07/scxml")) {
_nsURL = uri;
if (prefix.size() == 0) {
@@ -253,6 +255,9 @@ void Interpreter::interpret() {
LOG(ERROR) << "No datamodel for " << datamodelName << " registered";
}
+ if (_dataModel)
+ _dataModel.assign("_x.args", _cmdLineOptions);
+
setupIOProcessors();
_running = true;
@@ -269,7 +274,6 @@ void Interpreter::interpret() {
} else if(_dataModel) {
// initialize current data elements
NodeSet<std::string> topDataElems = filterChildElements(_xmlNSPrefix + "data", filterChildElements(_xmlNSPrefix + "datamodel", _scxml));
- // NodeSet<std::string> topDataElems = _xpath.evaluate("/" + _xpathPrefix + "scxml/" + _xpathPrefix + "datamodel/" + _xpathPrefix + "data", _document).asNodeSet();
for (unsigned int i = 0; i < topDataElems.size(); i++) {
initializeData(topDataElems[i]);
}
@@ -278,7 +282,6 @@ void Interpreter::interpret() {
// executeGlobalScriptElements
NodeSet<std::string> globalScriptElems = _xpath.evaluate("/" + _xpathPrefix + "scxml/" + _xpathPrefix + "script", _document).asNodeSet();
for (unsigned int i = 0; i < globalScriptElems.size(); i++) {
- // std::cout << globalScriptElems[i].getFirstChild().getNodeValue() << std::endl;
if (_dataModel)
executeContent(globalScriptElems[i]);
}
@@ -344,7 +347,6 @@ void Interpreter::initializeData(const Arabica::DOM::Node<std::string>& data) {
break;
}
}
-// std::cout << value << std::endl;
}
} catch (Event e) {
@@ -429,7 +431,7 @@ void Interpreter::mainEventLoop() {
}
std::cout << std::endl;
#endif
- std::set<InterpreterMonitor*>::iterator monIter = _monitors.begin();
+ monIter = _monitors.begin();
while(monIter != _monitors.end()) {
(*monIter)->beforeMicroStep(this);
monIter++;
@@ -450,12 +452,18 @@ void Interpreter::mainEventLoop() {
enabledTransitions = selectTransitions(internalEvent.name);
}
}
- if (!enabledTransitions.empty())
+ if (!enabledTransitions.empty()) {
+ monIter = _monitors.begin();
+ while(monIter != _monitors.end()) {
+ (*monIter)->beforeTakingTransitions(this, enabledTransitions);
+ monIter++;
+ }
microstep(enabledTransitions);
+ }
}
for (unsigned int i = 0; i < _statesToInvoke.size(); i++) {
- NodeSet<std::string> invokes = _xpath.evaluate("" + _xpathPrefix + "invoke", _statesToInvoke[i]).asNodeSet();
+ NodeSet<std::string> invokes = filterChildElements(_xmlNSPrefix + "invoke", _statesToInvoke[i]);
for (unsigned int j = 0; j < invokes.size(); j++) {
invoke(invokes[j]);
}
@@ -491,24 +499,27 @@ void Interpreter::mainEventLoop() {
LOG(ERROR) << "Syntax error while setting external event:" << std::endl << e << std::endl;
}
for (unsigned int i = 0; i < _configuration.size(); i++) {
- NodeSet<std::string> invokes = _xpath.evaluate("" + _xpathPrefix + "invoke", _configuration[i]).asNodeSet();
+ NodeSet<std::string> invokes = filterChildElements(_xmlNSPrefix + "invoke", _configuration[i]);
for (unsigned int j = 0; j < invokes.size(); j++) {
Arabica::DOM::Element<std::string> invokeElem = (Arabica::DOM::Element<std::string>)invokes[j];
- std::string invokeId = invokeElem.getAttribute("id");
+ std::string invokeId;
+ if (HAS_ATTR(invokeElem, "id"))
+ invokeId = ATTR(invokeElem, "id");
+ if (HAS_ATTR(invokeElem, "idlocation") && _dataModel)
+ invokeId = _dataModel.evalAsString(ATTR(invokeElem, "idlocation"));
+
std::string autoForward = invokeElem.getAttribute("autoforward");
if (boost::iequals(invokeId, externalEvent.invokeid)) {
- Arabica::XPath::NodeSet<std::string> finalizes = _xpath.evaluate("" + _xpathPrefix + "finalize", invokeElem).asNodeSet();
+ Arabica::XPath::NodeSet<std::string> finalizes = filterChildElements(_xmlNSPrefix + "finalize", invokeElem);
for (int k = 0; k < finalizes.size(); k++) {
Arabica::DOM::Element<std::string> finalizeElem = Arabica::DOM::Element<std::string>(finalizes[k]);
executeContent(finalizeElem);
}
-
}
- if (autoForward.length() > 0) {
- // @TODO
-// send(invokeId, externalEvent);
+ if (boost::iequals(autoForward, "true")) {
+ _invokers[invokeId].send(externalEvent);
}
}
}
@@ -540,7 +551,7 @@ void Interpreter::internalDoneSend(const Arabica::DOM::Node<std::string>& state)
Arabica::DOM::Element<std::string> parent = (Arabica::DOM::Element<std::string>)stateElem.getParentNode();
Event event;
- Arabica::XPath::NodeSet<std::string> doneDatas = _xpath.evaluate("" + _xpathPrefix + "donedata", stateElem).asNodeSet();
+ Arabica::XPath::NodeSet<std::string> doneDatas = filterChildElements(_xmlNSPrefix + "donedata", stateElem);
if (doneDatas.size() > 0) {
// only process first donedata element
Arabica::DOM::Node<std::string> doneData = doneDatas[0];
@@ -668,10 +679,10 @@ void Interpreter::send(const Arabica::DOM::Node<std::string>& element) {
}
// params
- NodeSet<std::string> params = _xpath.evaluate("" + _xpathPrefix + "param", element).asNodeSet();
+ NodeSet<std::string> params = filterChildElements(_xmlNSPrefix + "param", element);
for (int i = 0; i < params.size(); i++) {
if (!HAS_ATTR(params[i], "name")) {
- LOG(ERROR) << "param element is missing name attribut";
+ LOG(ERROR) << "param element is missing name attribute";
continue;
}
std::string paramValue;
@@ -683,11 +694,13 @@ void Interpreter::send(const Arabica::DOM::Node<std::string>& element) {
LOG(ERROR) << "param element is missing expr or location or no datamodel is specified";
continue;
}
- sendReq.params.insert(std::make_pair(ATTR(params[i], "name"), paramValue));
+ std::string paramKey = ATTR(params[i], "name");
+ boost::algorithm::to_lower(paramKey);
+ sendReq.params.insert(std::make_pair(paramKey, paramValue));
}
// content
- NodeSet<std::string> contents = _xpath.evaluate("" + _xpathPrefix + "content", element).asNodeSet();
+ NodeSet<std::string> contents = filterChildElements(_xmlNSPrefix + "content", element);
if (contents.size() > 1)
LOG(ERROR) << "Only a single content element is allowed for send elements - using first one";
if (contents.size() > 0) {
@@ -792,7 +805,10 @@ void Interpreter::invoke(const Arabica::DOM::Node<std::string>& element) {
// namelist
if (HAS_ATTR(element, "namelist")) {
- invokeReq.namelist = ATTR(element, "namelist");
+ std::vector<std::string> names = tokenizeIdRefs(ATTR(element, "namelist"));
+ for (int i = 0; i < names.size(); i++) {
+ invokeReq.namelist[names[i]] = _dataModel.evalAsString(names[i]);
+ }
}
// autoforward
@@ -805,7 +821,7 @@ void Interpreter::invoke(const Arabica::DOM::Node<std::string>& element) {
}
// params
- NodeSet<std::string> params = _xpath.evaluate("" + _xpathPrefix + "param", element).asNodeSet();
+ NodeSet<std::string> params = filterChildElements(_xmlNSPrefix + "param", element);
for (int i = 0; i < params.size(); i++) {
if (!HAS_ATTR(params[i], "name")) {
LOG(ERROR) << "param element is missing name attribut";
@@ -824,16 +840,17 @@ void Interpreter::invoke(const Arabica::DOM::Node<std::string>& element) {
LOG(ERROR) << "param element is missing expr or location or no datamodel is specified";
continue;
}
- invokeReq.params.insert(std::make_pair(ATTR(params[i], "name"), paramValue));
+ std::string paramKey = ATTR(params[i], "name");
+ boost::algorithm::to_lower(paramKey);
+ invokeReq.params.insert(std::make_pair(paramKey, paramValue));
}
// content
- NodeSet<std::string> contents = _xpath.evaluate("" + _xpathPrefix + "content", element).asNodeSet();
+ NodeSet<std::string> contents = filterChildElements(_xmlNSPrefix + "content", element);
if (contents.size() > 1)
LOG(ERROR) << "Only a single content element is allowed for send elements - using first one";
if (contents.size() > 0) {
- //std::cout << contents[0] << std::endl;
invokeReq.content = contents[0].getNodeValue();
}
@@ -846,6 +863,9 @@ void Interpreter::invoke(const Arabica::DOM::Node<std::string>& element) {
_invokers[invokeReq.invokeid] = invoker;
LOG(INFO) << "Added invoker " << invokeReq.type << " at " << invokeReq.invokeid;
invoker.invoke(invokeReq);
+ if (_dataModel) {
+ _dataModel.assign("_invokers['" + invokeReq.invokeid + "']", invoker.getDataModelVariables());
+ }
} else {
LOG(ERROR) << "No invoker known for type " << invokeReq.type;
}
@@ -866,6 +886,14 @@ void Interpreter::cancelInvoke(const Arabica::DOM::Node<std::string>& element) {
}
if (_invokers.find(invokeId) != _invokers.end()) {
LOG(INFO) << "Removed invoker at " << invokeId;
+ if (_dataModel) {
+ try {
+ _dataModel.assign("_invokers['" + invokeId + "']", "''");
+ } catch (Event e) {
+ LOG(ERROR) << "Syntax when removing invoker:" << std::endl << e << std::endl;
+ }
+
+ }
_invokers.erase(invokeId);
} else {
LOG(ERROR) << "Cannot cancel invoke for id " << invokeId << ": no soch invokation";
@@ -886,7 +914,7 @@ Arabica::XPath::NodeSet<std::string> Interpreter::selectTransitions(const std::s
NodeSet<std::string> ancestors = getProperAncestors(atomicStates[i], Arabica::DOM::Node<std::string>());
ancestors.push_back(atomicStates[i]);
for (unsigned int j = 0; j < ancestors.size(); j++) {
- NodeSet<std::string> transitions = _xpath.evaluate("" + _xpathPrefix + "transition", ancestors[j]).asNodeSet();
+ NodeSet<std::string> transitions = filterChildElements(_xmlNSPrefix + "transition", ancestors[j]);
for (unsigned int k = 0; k < transitions.size(); k++) {
if (((Arabica::DOM::Element<std::string>)transitions[k]).hasAttribute("event") &&
nameMatch(((Arabica::DOM::Element<std::string>)transitions[k]).getAttribute("event"), event) &&
@@ -958,7 +986,7 @@ Arabica::XPath::NodeSet<std::string> Interpreter::selectEventlessTransitions() {
NodeSet<std::string> ancestors = getProperAncestors(atomicStates[i], Arabica::DOM::Node<std::string>());
ancestors.push_back(atomicStates[i]);
for (unsigned int j = 0; j < ancestors.size(); j++) {
- NodeSet<std::string> transitions = filterChildElements("transition", ancestors[j]);
+ NodeSet<std::string> transitions = filterChildElements(_xmlNSPrefix + "transition", ancestors[j]);
for (unsigned int k = 0; k < transitions.size(); k++) {
if (!((Arabica::DOM::Element<std::string>)transitions[k]).hasAttribute("event") && hasConditionMatch(transitions[k])) {
enabledTransitions.push_back(transitions[k]);
@@ -967,7 +995,7 @@ Arabica::XPath::NodeSet<std::string> Interpreter::selectEventlessTransitions() {
}
#if 0
- NodeSet<std::string> transitions = _xpath.evaluate("" + _xpathPrefix + "transition", ancestors[j]).asNodeSet();
+ NodeSet<std::string> transitions = filterChildElements(_xmlNSPrefix + "transition", ancestors[j]);
for (unsigned int k = 0; k < transitions.size(); k++) {
if (!((Arabica::DOM::Element<std::string>)transitions[k]).hasAttribute("event") && hasConditionMatch(transitions[k])) {
enabledTransitions.push_back(transitions[k]);
@@ -1047,11 +1075,11 @@ void Interpreter::exitInterpreter() {
statesToExit.reverse();
for (int i = 0; i < statesToExit.size(); i++) {
- Arabica::XPath::NodeSet<std::string> onExitElems = _xpath.evaluate("" + _xpathPrefix + "onexit", statesToExit[i]).asNodeSet();
+ Arabica::XPath::NodeSet<std::string> onExitElems = filterChildElements(_xmlNSPrefix + "onexit", statesToExit[i]);
for (int j = 0; j < onExitElems.size(); j++) {
executeContent(onExitElems[j]);
}
- Arabica::XPath::NodeSet<std::string> invokeElems = _xpath.evaluate("" + _xpathPrefix + "invoke", statesToExit[i]).asNodeSet();
+ Arabica::XPath::NodeSet<std::string> invokeElems = filterChildElements(_xmlNSPrefix + "invoke", statesToExit[i]);
for (int j = 0; j < invokeElems.size(); j++) {
cancelInvoke(invokeElems[j]);
}
@@ -1252,6 +1280,8 @@ void Interpreter::returnDoneEvent(const Arabica::DOM::Node<std::string>& state)
void Interpreter::exitStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) {
NodeSet<std::string> statesToExit;
+ std::set<InterpreterMonitor*>::iterator monIter;
+
for (int i = 0; i < enabledTransitions.size(); i++) {
Arabica::DOM::Element<std::string> transition = ((Arabica::DOM::Element<std::string>)enabledTransitions[i]);
if (!isTargetless(transition)) {
@@ -1298,8 +1328,14 @@ void Interpreter::exitStates(const Arabica::XPath::NodeSet<std::string>& enabled
statesToExit.to_document_order();
statesToExit.reverse();
+ monIter = _monitors.begin();
+ while(monIter != _monitors.end()) {
+ (*monIter)->beforeExitingStates(this, statesToExit);
+ monIter++;
+ }
+
for (int i = 0; i < statesToExit.size(); i++) {
- NodeSet<std::string> histories = filterChildElements("history", statesToExit[i]);
+ NodeSet<std::string> histories = filterChildElements(_xmlNSPrefix + "history", statesToExit[i]);
for (int j = 0; j < histories.size(); j++) {
Arabica::DOM::Element<std::string> historyElem = (Arabica::DOM::Element<std::string>)histories[j];
std::string historyType = (historyElem.hasAttribute("type") ? historyElem.getAttribute("type") : "shallow");
@@ -1318,24 +1354,18 @@ void Interpreter::exitStates(const Arabica::XPath::NodeSet<std::string>& enabled
}
for (int i = 0; i < statesToExit.size(); i++) {
- NodeSet<std::string> onExits = filterChildElements("onExit", statesToExit[i]);
+ NodeSet<std::string> onExits = filterChildElements(_xmlNSPrefix + "onExit", statesToExit[i]);
for (int j = 0; j < onExits.size(); j++) {
Arabica::DOM::Element<std::string> onExitElem = (Arabica::DOM::Element<std::string>)onExits[j];
executeContent(onExitElem);
}
- NodeSet<std::string> invokes = filterChildElements("invoke", statesToExit[i]);
+ NodeSet<std::string> invokes = filterChildElements(_xmlNSPrefix + "invoke", statesToExit[i]);
for (int j = 0; j < invokes.size(); j++) {
Arabica::DOM::Element<std::string> invokeElem = (Arabica::DOM::Element<std::string>)invokes[j];
cancelInvoke(invokeElem);
}
}
-// std::cout << "States to Exit: ";
-// for (int i = 0; i < statesToExit.size(); i++) {
-// std::cout << ((Arabica::DOM::Element<std::string>)statesToExit[i]).getAttribute("id") << ", ";
-// }
-// std::cout << std::endl;
-
// remove statesToExit from _configuration
tmp.clear();
for (int i = 0; i < _configuration.size(); i++) {
@@ -1346,20 +1376,38 @@ void Interpreter::exitStates(const Arabica::XPath::NodeSet<std::string>& enabled
_configuration = NodeSet<std::string>();
_configuration.insert(_configuration.end(), tmp.begin(), tmp.end());
+ monIter = _monitors.begin();
+ while(monIter != _monitors.end()) {
+ (*monIter)->afterExitingStates(this);
+ monIter++;
+ }
}
void Interpreter::enterStates(const Arabica::XPath::NodeSet<std::string>& enabledTransitions) {
NodeSet<std::string> statesToEnter;
NodeSet<std::string> statesForDefaultEntry;
+ std::set<InterpreterMonitor*>::iterator monIter;
for (int i = 0; i < enabledTransitions.size(); i++) {
Arabica::DOM::Element<std::string> transition = ((Arabica::DOM::Element<std::string>)enabledTransitions[i]);
if (!isTargetless(transition)) {
std::string transitionType = (boost::iequals(transition.getAttribute("type"), "internal") ? "internal" : "external");
NodeSet<std::string> tStates = getTargetStates(transition);
+
+#if 0
+ std::cout << "Target States: ";
+ for (int i = 0; i < tStates.size(); i++) {
+ std::cout << ATTR(tStates[i], "id") << ", ";
+ }
+ std::cout << std::endl;
+#endif
+
Arabica::DOM::Node<std::string> ancestor;
Arabica::DOM::Node<std::string> source = getSourceState(transition);
+#if 0
+ std::cout << "Source States: " << ATTR(source, "id") << std::endl;
+#endif
assert(source);
bool allDescendants = true;
@@ -1381,13 +1429,26 @@ void Interpreter::enterStates(const Arabica::XPath::NodeSet<std::string>& enable
ancestor = findLCCA(tmpStates);
}
+#if 0
+ std::cout << "Ancestor: " << ATTR(ancestor, "id") << std::endl;
+#endif
+
for (int j = 0; j < tStates.size(); j++) {
addStatesToEnter(tStates[j], statesToEnter, statesForDefaultEntry);
}
for (int j = 0; j < tStates.size(); j++) {
NodeSet<std::string> ancestors = getProperAncestors(tStates[j], ancestor);
- for (int k = 0; k < ancestors.size(); k++) {
+
+#if 0
+ std::cout << "Proper Ancestors of " << ATTR(tStates[j], "id") << " and " << ATTR(ancestor, "id") << ": ";
+ for (int i = 0; i < ancestors.size(); i++) {
+ std::cout << ATTR(ancestors[i], "id") << ", ";
+ }
+ std::cout << std::endl;
+#endif
+
+ for (int k = 0; k < ancestors.size(); k++) {
statesToEnter.push_back(ancestors[k]);
if(isParallel(ancestors[k])) {
NodeSet<std::string> childs = getChildStates(ancestors[k]);
@@ -1409,22 +1470,21 @@ void Interpreter::enterStates(const Arabica::XPath::NodeSet<std::string>& enable
}
}
statesToEnter.to_document_order();
-#if 0
- std::cout << "Entering states: ";
- for (int i = 0; i < statesToEnter.size(); i++) {
- std::cout << ATTR(statesToEnter[i], "id") << ", ";
- }
- std::cout << std::endl;
-#endif
+
+ monIter = _monitors.begin();
+ while(monIter != _monitors.end()) {
+ (*monIter)->beforeEnteringStates(this, statesToEnter);
+ monIter++;
+ }
for (int i = 0; i < statesToEnter.size(); i++) {
Arabica::DOM::Element<std::string> stateElem = (Arabica::DOM::Element<std::string>)statesToEnter[i];
_configuration.push_back(stateElem);
_statesToInvoke.push_back(stateElem);
if (_binding == LATE && stateElem.getAttribute("isFirstEntry").size() > 0) {
- NodeSet<std::string> dataModelElems = filterChildElements("datamodel", stateElem);
+ NodeSet<std::string> dataModelElems = filterChildElements(_xmlNSPrefix + "datamodel", stateElem);
if(dataModelElems.size() > 0 && _dataModel) {
- Arabica::XPath::NodeSet<std::string> dataElems = filterChildElements("data", dataModelElems[0]);
+ Arabica::XPath::NodeSet<std::string> dataElems = filterChildElements(_xmlNSPrefix + "data", dataModelElems[0]);
for (int j = 0; j < dataElems.size(); j++) {
initializeData(dataElems[j]);
}
@@ -1432,7 +1492,7 @@ void Interpreter::enterStates(const Arabica::XPath::NodeSet<std::string>& enable
stateElem.setAttribute("isFirstEntry", "");
}
// execute onentry executable content
- NodeSet<std::string> onEntryElems = filterChildElements("onEntry", stateElem);
+ NodeSet<std::string> onEntryElems = filterChildElements(_xmlNSPrefix + "onEntry", stateElem);
for (int j = 0; j < onEntryElems.size(); j++) {
executeContent(onEntryElems[j]);
}
@@ -1472,6 +1532,13 @@ void Interpreter::enterStates(const Arabica::XPath::NodeSet<std::string>& enable
_done = true;
}
}
+
+ monIter = _monitors.begin();
+ while(monIter != _monitors.end()) {
+ (*monIter)->afterEnteringStates(this);
+ monIter++;
+ }
+
}
bool Interpreter::parentIsScxmlState(Arabica::DOM::Node<std::string> state) {
@@ -1483,7 +1550,6 @@ bool Interpreter::parentIsScxmlState(Arabica::DOM::Node<std::string> state) {
}
bool Interpreter::isInFinalState(const Arabica::DOM::Node<std::string>& state) {
-// std::cout << ATTR(state, "id") << std::endl;
if (isCompound(state)) {
Arabica::XPath::NodeSet<std::string> childs = getChildStates(state);
for (int i = 0; i < childs.size(); i++) {
@@ -1516,15 +1582,35 @@ void Interpreter::addStatesToEnter(const Arabica::DOM::Node<std::string>& state,
if (isHistory(state)) {
if (_historyValue.find(stateId) != _historyValue.end()) {
Arabica::XPath::NodeSet<std::string> historyValue = _historyValue[stateId];
+
+#if 0
+ std::cout << "History States: ";
+ for (int i = 0; i < historyValue.size(); i++) {
+ std::cout << ATTR(historyValue[i], "id") << ", ";
+ }
+ std::cout << std::endl;
+#endif
+
for (int i = 0; i < historyValue.size(); i++) {
addStatesToEnter(historyValue[i], statesToEnter, statesForDefaultEntry);
NodeSet<std::string> ancestors = getProperAncestors(historyValue[i], state);
+
+#if 0
+ std::cout << "Proper Ancestors: ";
+ for (int i = 0; i < ancestors.size(); i++) {
+ std::cout << ATTR(ancestors[i], "id") << ", ";
+ }
+ std::cout << std::endl;
+#endif
+
for (int j = 0; j < ancestors.size(); j++) {
+ if (boost::iequals(TAGNAME(ancestors[j]), _xmlNSPrefix + "scxml")) // do not add the scxml element itself
+ continue;
statesToEnter.push_back(ancestors[j]);
}
}
} else {
- NodeSet<std::string> transitions = _xpath.evaluate("" + _xpathPrefix + "transition", state).asNodeSet();
+ NodeSet<std::string> transitions = filterChildElements(_xmlNSPrefix + "transition", state);
for (int i = 0; i < transitions.size(); i++) {
NodeSet<std::string> targets = getTargetStates(transitions[i]);
for (int j = 0; j < targets.size(); j++) {
@@ -1567,18 +1653,22 @@ Arabica::XPath::NodeSet<std::string> Interpreter::getChildStates(const Arabica::
}
Arabica::DOM::Node<std::string> Interpreter::findLCCA(const Arabica::XPath::NodeSet<std::string>& states) {
-// std::cout << "findLCCA: ";
-// for (int i = 0; i < states.size(); i++) {
-// std::cout << ATTR(states[i], "id") << " - " << TAGNAME(states[i]) << ", ";
-// }
-// std::cout << std::endl << std::flush;
-
+#if 0
+ std::cout << "findLCCA: ";
+ for (int i = 0; i < states.size(); i++) {
+ std::cout << ATTR(states[i], "id") << " - " << TAGNAME(states[i]) << ", ";
+ }
+ std::cout << std::endl << std::flush;
+#endif
+
Arabica::XPath::NodeSet<std::string> ancestors = getProperAncestors(states[0], Arabica::DOM::Node<std::string>());
ancestors.push_back(states[0]); // state[0] may already be the ancestor - bug in W3C spec?
Arabica::DOM::Node<std::string> ancestor;
for (int i = 0; i < ancestors.size(); i++) {
for (int j = 0; j < states.size(); j++) {
-// std::cout << "Checking " << TAGNAME(states[j]) << " and " << TAGNAME(ancestors[i]) << std::endl;
+#if 0
+ std::cout << "Checking " << TAGNAME(states[j]) << " and " << TAGNAME(ancestors[i]) << std::endl;
+#endif
if (!isDescendant(states[j], ancestors[i]) && (states[j] != ancestors[i]))
goto NEXT_ANCESTOR;
}
@@ -1588,7 +1678,9 @@ NEXT_ANCESTOR:
;
}
assert(ancestor);
-// std::cout << " -> " << ATTR(ancestor, "id") << " " << ancestor.getLocalName() << std::endl;
+#if 0
+ std::cout << " -> " << ATTR(ancestor, "id") << " " << ancestor.getLocalName() << std::endl;
+#endif
return ancestor;
}
@@ -1613,6 +1705,13 @@ Arabica::DOM::Node<std::string> Interpreter::getState(const std::string& stateId
if (target.size() > 0)
goto FOUND;
+ // now history states
+ target = _xpath.evaluate("//" + _xpathPrefix + "history[@id='" + stateId + "']", _document).asNodeSet();
+ if (target.size() > 0)
+ goto FOUND;
+
+ LOG(ERROR) << "No state with id " << stateId << " found!";
+
FOUND:
if (target.size() > 0) {
assert(target.size() == 1);
@@ -1652,7 +1751,7 @@ Arabica::DOM::Node<std::string> Interpreter::getInitialState(Arabica::DOM::Node<
}
// initial element as child - but not the implicit generated one
- NodeSet<std::string> initialStates = _xpath.evaluate("" + _xpathPrefix + "initial", state).asNodeSet();
+ NodeSet<std::string> initialStates = filterChildElements(_xmlNSPrefix + "initial", state);
if(initialStates.size() == 1 && !boost::iequals(ATTR(initialStates[0], "generated"), "true"))
return initialStates[0];
@@ -1786,6 +1885,8 @@ bool Interpreter::isState(const Arabica::DOM::Node<std::string>& state) {
return true;
if (boost::iequals("parallel", tagName))
return true;
+ if (boost::iequals("history", tagName))
+ return true;
if (boost::iequals("final", tagName))
return true;
return false;
@@ -1824,7 +1925,7 @@ bool Interpreter::isPseudoState(const Arabica::DOM::Node<std::string>& state) {
}
bool Interpreter::isTransitionTarget(const Arabica::DOM::Node<std::string>& elem) {
- return (isState(elem) || boost::iequals(LOCALNAME(elem), "history"));
+ return (isState(elem) || boost::iequals(LOCALNAME(elem), "history")); // TODO: history is a state
}
bool Interpreter::isAtomic(const Arabica::DOM::Node<std::string>& state) {
@@ -1903,6 +2004,29 @@ IOProcessor Interpreter::getIOProcessor(const std::string& type) {
return _ioProcessors[type];
}
+void Interpreter::setCmdLineOptions(int argc, char** argv) {
+ char* key = NULL;
+ char* value = NULL;
+ for (int i = 0; i < argc; i++) {
+ if (false) {
+ } else if (strlen(argv[i]) > 2 && strncmp(&argv[i][0], "-", 1) == 0 && strncmp(&argv[i][1], "-", 1) == 0) {
+ // longopt
+ key = &argv[i][2];
+ } else if (strlen(argv[i]) > 1 && strncmp(&argv[i][0], "-", 1) == 0 && strncmp(&argv[i][1], "-", 1) != 0) {
+ // shortopt
+ key = &argv[i][1];
+ }
+ if (key != NULL) {
+ if (i + 1 < argc && strncmp(&argv[i + 1][0], "-", 1) != 0) {
+ value = argv[++i];
+ _cmdLineOptions.compound[key] = Data(value, Data::VERBATIM);
+ } else {
+ _cmdLineOptions.compound[key] = Data("true");
+ }
+ }
+ }
+}
+
void Interpreter::dump() {
if (!_document)
return;
diff --git a/src/uscxml/Interpreter.h b/src/uscxml/Interpreter.h
index 334b2ad..ab58ec3 100644
--- a/src/uscxml/Interpreter.h
+++ b/src/uscxml/Interpreter.h
@@ -33,6 +33,11 @@ public:
virtual void beforeCompletion(Interpreter* interpreter) {}
virtual void afterCompletion(Interpreter* interpreter) {}
virtual void beforeMicroStep(Interpreter* interpreter) {}
+ virtual void beforeTakingTransitions(Interpreter* interpreter, const Arabica::XPath::NodeSet<std::string>& transitions) {}
+ virtual void beforeEnteringStates(Interpreter* interpreter, const Arabica::XPath::NodeSet<std::string>& statesToEnter) {}
+ virtual void afterEnteringStates(Interpreter* interpreter) {}
+ virtual void beforeExitingStates(Interpreter* interpreter, const Arabica::XPath::NodeSet<std::string>& statesToExit) {}
+ virtual void afterExitingStates(Interpreter* interpreter) {}
};
class NumAttr {
@@ -100,6 +105,9 @@ public:
}
bool toAbsoluteURI(URL& uri);
+ void setCmdLineOptions(int argc, char** argv);
+ Data getCmdLineOptions() { return _cmdLineOptions; }
+
DataModel getDataModel() {
return _dataModel;
}
@@ -247,12 +255,15 @@ protected:
std::string _name;
std::string _sessionId;
+ Data _cmdLineOptions;
+
IOProcessor getIOProcessor(const std::string& type);
// IOProcessor* getIOProcessorForId(const std::string& sendId);
std::map<std::string, IOProcessor> _ioProcessors;
std::map<std::string, std::pair<Interpreter*, SendRequest> > _sendIds;
std::map<std::string, Invoker> _invokers;
+ std::map<std::string, Invoker> _autoForwardees;
/// We need to remember to adapt them when the DOM is operated upon
std::map<std::string, Arabica::DOM::Node<std::string> > _cachedStates;
diff --git a/src/uscxml/Message.cpp b/src/uscxml/Message.cpp
index a78937f..9453508 100644
--- a/src/uscxml/Message.cpp
+++ b/src/uscxml/Message.cpp
@@ -157,7 +157,6 @@ Arabica::DOM::Document<std::string> SendRequest::toDocument() {
}
-
scxmlMsg.setAttribute("sendid", sendid);
return document;
@@ -217,10 +216,7 @@ Data Data::fromJSON(const std::string& jsonString) {
// there are no more tokens
if (t[currTok].end == 0 || tokenStack.empty())
break;
-
-// std::cout << "Token Stack: [" << tokenStack.back().start << ", " << tokenStack.back().end << "]" << std::endl;
-// std::cout << "Token Curr: [" << t[currTok].start << ", " << t[currTok].end << "]" << std::endl;
-
+
// next token starts after current one => pop
if (t[currTok].end > tokenStack.back().end)
tokenStack.pop_back();
@@ -240,7 +236,7 @@ Data Data::fromJSON(const std::string& jsonString) {
return data;
}
- Event Event::fromXML(const std::string& xmlString) {
+Event Event::fromXML(const std::string& xmlString) {
Arabica::SAX2DOM::Parser<std::string> eventParser;
Arabica::SAX::CatchErrorHandler<std::string> errorHandler;
eventParser.setErrorHandler(errorHandler);
@@ -296,17 +292,116 @@ InvokeRequest InvokeRequest::fromXML(const std::string& xmlString) {
}
#ifndef SWIGJAVA
+std::ostream& operator<< (std::ostream& os, const InvokeRequest& invokeReq) {
+
+ std::string indent;
+ for (int i = 0; i < _dataIndentation; i++) {
+ indent += " ";
+ }
+
+ os << indent << "InvokeReq" << (invokeReq.autoForward ? " with autoforward" : "") << std::endl;
+
+ if (invokeReq.type.size() > 0)
+ os << indent << " type: " << invokeReq.type << std::endl;
+
+ if (invokeReq.src.size() > 0)
+ os<< indent << " src: " << invokeReq.src << std::endl;
+
+ if (invokeReq.namelist.size() > 0) {
+ os << indent << " namelist: " << std::endl;
+ InvokeRequest::namelist_t::const_iterator namelistIter = invokeReq.namelist.begin();
+ while(namelistIter != invokeReq.namelist.end()) {
+ os << indent << " " << namelistIter->first << ": " << namelistIter->second << std::endl;
+ namelistIter++;
+ }
+ }
+
+ if (invokeReq.params.size() > 0) {
+ os << indent << " params: " << std::endl;
+ SendRequest::params_t::const_iterator paramIter = invokeReq.params.begin();
+ while(paramIter != invokeReq.params.end()) {
+ os << indent << " " << paramIter->first << ": " << paramIter->second << std::endl;
+ paramIter++;
+ }
+ }
+
+ if (invokeReq.content.size() > 0)
+ os << indent << " content: " << invokeReq.content << std::endl;
+
+ _dataIndentation++;
+ os << (Event)invokeReq;
+ _dataIndentation--;
+ return os;
+
+}
+#endif
+
+
+#ifndef SWIGJAVA
+std::ostream& operator<< (std::ostream& os, const SendRequest& sendReq) {
+
+ std::string indent;
+ for (int i = 0; i < _dataIndentation; i++) {
+ indent += " ";
+ }
+
+ os << indent<< "SendReq" << std::endl;
+
+ if (sendReq.target.size() > 0)
+ os << indent << " target: " << sendReq.target << std::endl;
+
+ if (sendReq.type.size() > 0)
+ os << indent << " type: " << sendReq.type << std::endl;
+
+ if (sendReq.delayMs > 0)
+ os<< indent << " delay: " << sendReq.delayMs << std::endl;
+
+ if (sendReq.namelist.size() > 0) {
+ os << indent << " namelist: " << std::endl;
+ SendRequest::namelist_t::const_iterator namelistIter = sendReq.namelist.begin();
+ while(namelistIter != sendReq.namelist.end()) {
+ os << indent << " " << namelistIter->first << ": " << namelistIter->second << std::endl;
+ namelistIter++;
+ }
+ }
+
+ if (sendReq.params.size() > 0) {
+ os << indent << " params: " << std::endl;
+ SendRequest::params_t::const_iterator paramIter = sendReq.params.begin();
+ while(paramIter != sendReq.params.end()) {
+ os << indent << " " << paramIter->first << ": " << paramIter->second << std::endl;
+ paramIter++;
+ }
+ }
+
+ if (sendReq.content.size() > 0)
+ os << indent << " content: " << sendReq.content << std::endl;
+
+ _dataIndentation++;
+ os << (Event)sendReq;
+ _dataIndentation--;
+ return os;
+
+}
+#endif
+
+#ifndef SWIGJAVA
std::ostream& operator<< (std::ostream& os, const Event& event) {
- os << (event.type == Event::EXTERNAL ? "External" : "Internal") << " Event " /* << (event.dom ? "with DOM attached" : "")*/ << std::endl;
+ std::string indent;
+ for (int i = 0; i < _dataIndentation; i++) {
+ indent += " ";
+ }
+
+ os << indent << (event.type == Event::EXTERNAL ? "External" : "Internal") << " Event " << (event.dom ? "with DOM attached" : "") << std::endl;
if (event.name.size() > 0)
- os << " name: " << event.name << std::endl;
+ os << indent << " name: " << event.name << std::endl;
if (event.origin.size() > 0)
- os << " origin: " << event.origin << std::endl;
+ os << indent << " origin: " << event.origin << std::endl;
if (event.origintype.size() > 0)
- os << " origintype: " << event.origintype << std::endl;
+ os << indent << " origintype: " << event.origintype << std::endl;
_dataIndentation++;
- os << " data: " << (Data)event << std::endl;
+ os << indent << " data: " << (Data)event << std::endl;
_dataIndentation--;
return os;
}
@@ -362,7 +457,9 @@ std::ostream& operator<< (std::ostream& os, const Data& data) {
} else {
os << data.atom;
}
- }
+ } else {
+ os << "undefined";
+ }
return os;
}
#endif
diff --git a/src/uscxml/Message.h b/src/uscxml/Message.h
index 68e8151..43eecdf 100644
--- a/src/uscxml/Message.h
+++ b/src/uscxml/Message.h
@@ -86,9 +86,11 @@ public:
class InvokeRequest : public Event {
public:
+ InvokeRequest(Event event) : Event(event) {}
+ InvokeRequest() {}
std::string type;
std::string src;
- std::string namelist;
+ std::map<std::string, std::string> namelist;
typedef std::map<std::string, std::string> namelist_t;
bool autoForward;
std::multimap<std::string, std::string> params;
@@ -104,10 +106,16 @@ public:
return ss.str();
}
+#ifndef SWIGJAVA
+ friend std::ostream& operator<< (std::ostream& os, const InvokeRequest& sendReq);
+#endif
+
};
class SendRequest : public Event {
public:
+ SendRequest() {}
+ SendRequest(Event event) : Event(event) {}
std::string target;
std::string type;
uint32_t delayMs;
@@ -125,6 +133,10 @@ public:
// std::cout << ss.str() << std::endl;
return ss.str();
}
+
+#ifndef SWIGJAVA
+ friend std::ostream& operator<< (std::ostream& os, const SendRequest& sendReq);
+#endif
};
diff --git a/src/uscxml/URL.cpp b/src/uscxml/URL.cpp
index 4a8ead7..015ed6c 100644
--- a/src/uscxml/URL.cpp
+++ b/src/uscxml/URL.cpp
@@ -162,7 +162,7 @@ std::ostream & operator<<(std::ostream & stream, const URL& url) {
// std::replace( urlString.begin(), urlString.end(), '/', '\\');
#endif
}
- LOG(ERROR) << "Trying to open " << urlString;
+// LOG(ERROR) << "Trying to open " << urlString;
URL_FILE *handle = url_fopen(urlString.c_str(), "r");
if(!handle) {
diff --git a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
index 9f04670..d8a3c8d 100644
--- a/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
+++ b/src/uscxml/plugins/datamodel/ecmascript/v8/V8DataModel.cpp
@@ -63,6 +63,8 @@ boost::shared_ptr<DataModelImpl> V8DataModel::create(Interpreter* interpreter) {
dm->setName(interpreter->getName());
dm->setSessionId(interpreter->getSessionId());
dm->eval("_ioprocessors = {};");
+ dm->eval("_invokers = {};");
+ dm->eval("_x = {};");
return dm;
}
@@ -183,7 +185,7 @@ Data V8DataModel::getValueAsData(const v8::Handle<v8::Value>& value) {
} else if(value->IsUint32()) {
LOG(ERROR) << "IsUint32 is unimplemented" << std::endl;
} else if(value->IsUndefined()) {
- LOG(ERROR) << "IsUndefined is unimplemented" << std::endl;
+ data.atom = "undefined";
}
return data;
}
@@ -269,6 +271,10 @@ std::string V8DataModel::evalAsString(const std::string& expr) {
v8::HandleScope handleScope;
v8::Context::Scope contextScope(_contexts.back());
v8::Handle<v8::Value> result = evalAsValue(expr);
+ if (result->IsObject()) {
+ Data data = getValueAsData(result);
+ return toStr(data);
+ }
v8::String::AsciiValue data(result->ToString());
return std::string(*data);
}
diff --git a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.cpp b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.cpp
new file mode 100644
index 0000000..eb3d810
--- /dev/null
+++ b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.cpp
@@ -0,0 +1,48 @@
+#include "OSGConverter.h"
+#include <glog/logging.h>
+
+#ifdef BUILD_AS_PLUGINS
+#include <Pluma/Connector.hpp>
+#endif
+
+namespace uscxml {
+
+#ifdef BUILD_AS_PLUGINS
+PLUMA_CONNECTOR
+bool connect(pluma::Host& host) {
+ host.add( new OSGConverterProvider() );
+ return true;
+}
+#endif
+
+OSGConverter::OSGConverter() {
+}
+
+OSGConverter::~OSGConverter() {
+};
+
+boost::shared_ptr<IOProcessorImpl> OSGConverter::create(Interpreter* interpreter) {
+ boost::shared_ptr<OSGConverter> invoker = boost::shared_ptr<OSGConverter>(new OSGConverter());
+ invoker->_interpreter = interpreter;
+ return invoker;
+}
+
+Data OSGConverter::getDataModelVariables() {
+ Data data;
+ return data;
+}
+
+void OSGConverter::send(const SendRequest& req) {
+ std::cout << req << std::endl;
+ Event event;
+ event.name = "error";
+ returnEvent(event);
+}
+
+void OSGConverter::cancel(const std::string sendId) {
+}
+
+void OSGConverter::invoke(const InvokeRequest& req) {
+}
+
+} \ No newline at end of file
diff --git a/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.h b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.h
new file mode 100644
index 0000000..c52b1ee
--- /dev/null
+++ b/src/uscxml/plugins/invoker/graphics/openscenegraph/OSGConverter.h
@@ -0,0 +1,42 @@
+#ifndef OSGCONVERTER_H_W09J90F0
+#define OSGCONVERTER_H_W09J90F0
+
+#include <uscxml/Interpreter.h>
+
+#ifdef BUILD_AS_PLUGINS
+#include "uscxml/plugins/Plugins.h"
+#endif
+
+namespace uscxml {
+
+class OSGConverter : public InvokerImpl {
+public:
+ OSGConverter();
+ virtual ~OSGConverter();
+ virtual boost::shared_ptr<IOProcessorImpl> create(Interpreter* interpreter);
+
+ virtual std::set<std::string> getNames() {
+ std::set<std::string> names;
+ names.insert("osgconverter");
+ names.insert("osgconvert");
+ names.insert("http://uscxml.tk.informatik.tu-darmstadt.de/#osgconverter");
+ names.insert("http://uscxml.tk.informatik.tu-darmstadt.de/#osgconvert");
+ return names;
+ }
+
+ virtual Data getDataModelVariables();
+ virtual void send(const SendRequest& req);
+ virtual void cancel(const std::string sendId);
+ virtual void invoke(const InvokeRequest& req);
+
+protected:
+};
+
+#ifdef BUILD_AS_PLUGINS
+PLUMA_INHERIT_PROVIDER(OSGConverter, Invoker);
+#endif
+
+}
+
+
+#endif /* end of include guard: OSGCONVERTER_H_W09J90F0 */
diff --git a/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.cpp b/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.cpp
index 1f08378..0272ca8 100644
--- a/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.cpp
+++ b/src/uscxml/plugins/invoker/heartbeat/HeartbeatInvoker.cpp
@@ -19,6 +19,7 @@ HeartbeatInvoker::HeartbeatInvoker() {
}
HeartbeatInvoker::~HeartbeatInvoker() {
+ cancel("");
};
boost::shared_ptr<IOProcessorImpl> HeartbeatInvoker::create(Interpreter* interpreter) {
diff --git a/src/uscxml/plugins/invoker/sqlite3/Sqlite3Invoker.cpp b/src/uscxml/plugins/invoker/sqlite3/Sqlite3Invoker.cpp
new file mode 100644
index 0000000..e217eaa
--- /dev/null
+++ b/src/uscxml/plugins/invoker/sqlite3/Sqlite3Invoker.cpp
@@ -0,0 +1,44 @@
+#include "Sqlite3Invoker.h"
+#include <glog/logging.h>
+
+#ifdef BUILD_AS_PLUGINS
+#include <Pluma/Connector.hpp>
+#endif
+
+namespace uscxml {
+
+#ifdef BUILD_AS_PLUGINS
+PLUMA_CONNECTOR
+bool connect(pluma::Host& host) {
+ host.add( new Sqlite3InvokerProvider() );
+ return true;
+}
+#endif
+
+Sqlite3Invoker::Sqlite3Invoker() {
+}
+
+Sqlite3Invoker::~Sqlite3Invoker() {
+};
+
+boost::shared_ptr<IOProcessorImpl> Sqlite3Invoker::create(Interpreter* interpreter) {
+ boost::shared_ptr<Sqlite3Invoker> invoker = boost::shared_ptr<Sqlite3Invoker>(new Sqlite3Invoker());
+ invoker->_interpreter = interpreter;
+ return invoker;
+}
+
+Data Sqlite3Invoker::getDataModelVariables() {
+ Data data;
+ return data;
+}
+
+void Sqlite3Invoker::send(const SendRequest& req) {
+}
+
+void Sqlite3Invoker::cancel(const std::string sendId) {
+}
+
+void Sqlite3Invoker::invoke(const InvokeRequest& req) {
+}
+
+} \ No newline at end of file
diff --git a/src/uscxml/plugins/invoker/sqlite3/Sqlite3Invoker.h b/src/uscxml/plugins/invoker/sqlite3/Sqlite3Invoker.h
new file mode 100644
index 0000000..f2ae915
--- /dev/null
+++ b/src/uscxml/plugins/invoker/sqlite3/Sqlite3Invoker.h
@@ -0,0 +1,40 @@
+#ifndef SQLITE3INVOKER_H_W09J90F0
+#define SQLITE3INVOKER_H_W09J90F0
+
+#include <uscxml/Interpreter.h>
+
+#ifdef BUILD_AS_PLUGINS
+#include "uscxml/plugins/Plugins.h"
+#endif
+
+namespace uscxml {
+
+class Sqlite3Invoker : public InvokerImpl {
+public:
+ Sqlite3Invoker();
+ virtual ~Sqlite3Invoker();
+ virtual boost::shared_ptr<IOProcessorImpl> create(Interpreter* interpreter);
+
+ virtual std::set<std::string> getNames() {
+ std::set<std::string> names;
+ names.insert("sqlite3");
+ names.insert("http://uscxml.tk.informatik.tu-darmstadt.de/#sqlite3");
+ return names;
+ }
+
+ virtual Data getDataModelVariables();
+ virtual void send(const SendRequest& req);
+ virtual void cancel(const std::string sendId);
+ virtual void invoke(const InvokeRequest& req);
+
+protected:
+};
+
+#ifdef BUILD_AS_PLUGINS
+PLUMA_INHERIT_PROVIDER(Sqlite3Invoker, Invoker);
+#endif
+
+}
+
+
+#endif /* end of include guard: SQLITE3INVOKER_H_W09J90F0 */
diff --git a/src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.cpp b/src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.cpp
index 3ed39d6..98d08b3 100644
--- a/src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.cpp
+++ b/src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.cpp
@@ -75,14 +75,15 @@ Data EventIOProcessor::getDataModelVariables() {
void EventIOProcessor::send(const SendRequest& req) {
- // I cant figure out how to copy the reference into the struct :(
- _sendData[req.sendid].req = req;
- _sendData[req.sendid].ioProcessor = this;
+
+ _sendData[req.sendid] = new SendData();
+ _sendData[req.sendid]->scxmlReq = req;
+ _sendData[req.sendid]->ioProcessor = this;
int err = 0;
char uriBuf[1024];
- struct evhttp_uri* targetURI = evhttp_uri_parse(_sendData[req.sendid].req.target.c_str());
+ struct evhttp_uri* targetURI = evhttp_uri_parse(_sendData[req.sendid]->scxmlReq.target.c_str());
if (evhttp_uri_get_port(targetURI) < 0)
evhttp_uri_set_port(targetURI, 80);
const char* hostName = evhttp_uri_get_host(targetURI);
@@ -108,11 +109,14 @@ void EventIOProcessor::send(const SendRequest& req) {
ssLocalURI << evhttp_uri_get_path(targetURI) << evhttp_uri_get_fragment(targetURI);
std::string localURI = ssLocalURI.str();
- if (_httpConnections.find(endPoint) == _httpConnections.end())
- _httpConnections[endPoint] = evhttp_connection_base_new(_asyncQueue._eventLoop, _dns, evhttp_uri_get_host(targetURI), evhttp_uri_get_port(targetURI));
+ if (_httpConnections.find(endPoint) == _httpConnections.end()) {
+ struct evhttp_connection* conn = evhttp_connection_base_new(_asyncQueue._eventLoop, _dns, evhttp_uri_get_host(targetURI), evhttp_uri_get_port(targetURI));
+ evhttp_connection_set_retries(conn, 3);
+ _httpConnections[endPoint] = conn;
+ }
struct evhttp_connection* httpConn = _httpConnections[endPoint];
- struct evhttp_request* httpReq = evhttp_request_new(EventIOServer::httpSendReqDoneCallback, this);
+ struct evhttp_request* httpReq = evhttp_request_new(EventIOServer::httpSendReqDoneCallback, _sendData[req.sendid]);
// event name
if (req.name.size() > 0) {
@@ -163,6 +167,15 @@ void EventIOProcessor::send(const SendRequest& req) {
}
}
+void EventIOProcessor::httpSendReqDone(struct SendData* sendData) {
+ if (sendData->httpReq == NULL || evhttp_request_get_response_code(sendData->httpReq) != 200) {
+ Event failureEvent;
+ failureEvent.name = "error.communication";
+ sendData->ioProcessor->returnEvent(failureEvent);
+ }
+ delete _sendData[sendData->scxmlReq.sendid];
+}
+
void EventIOProcessor::httpRecvReq(struct evhttp_request *req) {
const char *cmdtype;
@@ -246,12 +259,6 @@ void EventIOProcessor::httpRecvReq(struct evhttp_request *req) {
evhttp_send_reply(req, 200, "OK", NULL);
}
-void EventIOProcessor::httpSendReqDone(struct evhttp_request *req) {
- if (req) {
- LOG(INFO) << "got return code " << evhttp_request_get_response_code(req) << std::endl;
- }
-}
-
EventIOServer::EventIOServer(unsigned short port) {
_port = port;
_base = event_base_new();
@@ -333,7 +340,6 @@ void EventIOServer::start() {
void EventIOServer::run(void* instance) {
EventIOServer* INSTANCE = (EventIOServer*)instance;
- LOG(INFO) << "HTTP Server started" << std::endl;
while(INSTANCE->_isRunning) {
event_base_dispatch(INSTANCE->_base);
}
diff --git a/src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.h b/src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.h
index 783332e..7dd1c41 100644
--- a/src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.h
+++ b/src/uscxml/plugins/ioprocessor/basichttp/libevent/EventIOProcessor.h
@@ -23,7 +23,8 @@ class EventIOProcessor : public IOProcessorImpl {
public:
struct SendData {
EventIOProcessor* ioProcessor;
- uscxml::SendRequest req;
+ uscxml::SendRequest scxmlReq;
+ evhttp_request* httpReq;
};
EventIOProcessor();
@@ -48,11 +49,11 @@ public:
static void run(void* instance);
virtual std::string getPath() { return _interpreter->getName(); }
- virtual void httpSendReqDone(struct evhttp_request *req);
+ virtual void httpSendReqDone(struct SendData* sendData);
virtual void httpRecvReq(struct evhttp_request *req);
protected:
- std::map<std::string, SendData> _sendData;
+ std::map<std::string, SendData*> _sendData;
std::string _url;
@@ -82,9 +83,10 @@ private:
void determineAddress();
static std::string syncResolve(const std::string& hostname);
-
static void httpSendReqDoneCallback(struct evhttp_request *req, void *cb_arg) {
- ((EventIOProcessor*)cb_arg)->httpSendReqDone(req);
+ EventIOProcessor::SendData* sendData = (EventIOProcessor::SendData*)cb_arg;
+ sendData->httpReq = req;
+ sendData->ioProcessor->httpSendReqDone(sendData);
}
static void httpRecvReqCallback(struct evhttp_request *req, void *cb_arg) {
((EventIOProcessor*)cb_arg)->httpRecvReq(req);