summaryrefslogtreecommitdiffstats
path: root/src/uscxml/plugins/invoker/scxml
diff options
context:
space:
mode:
authorStefan Radomski <github@mintwerk.de>2016-05-12 13:12:33 (GMT)
committerStefan Radomski <github@mintwerk.de>2016-05-12 13:12:33 (GMT)
commitb62e7979600feee23dc7cdb61042a8fc7673122b (patch)
treef7351372f37979dd2d048e0b68a16a4cd3b2aadb /src/uscxml/plugins/invoker/scxml
parent1b11b310be61e51b3ac5ebb83f7c8a33aef3d6e8 (diff)
downloaduscxml-b62e7979600feee23dc7cdb61042a8fc7673122b.zip
uscxml-b62e7979600feee23dc7cdb61042a8fc7673122b.tar.gz
uscxml-b62e7979600feee23dc7cdb61042a8fc7673122b.tar.bz2
Major Refactoring v2.0
Diffstat (limited to 'src/uscxml/plugins/invoker/scxml')
-rw-r--r--src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp180
-rw-r--r--src/uscxml/plugins/invoker/scxml/USCXMLInvoker.h41
2 files changed, 142 insertions, 79 deletions
diff --git a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp
index 62f7a1e..4d3c579 100644
--- a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp
+++ b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.cpp
@@ -18,16 +18,22 @@
*/
#include "USCXMLInvoker.h"
-#include <glog/logging.h>
-#include "uscxml/dom/DOMUtils.h"
-#include <DOM/SAX2DOM/SAX2DOM.hpp>
+
+#include "uscxml/config.h"
#ifdef BUILD_AS_PLUGINS
#include <Pluma/Connector.hpp>
#endif
+#ifdef UNIX
+#include <pthread.h>
+#endif
+
namespace uscxml {
+// msxml.h should die in a fire for polluting the global namespace
+// using namespace xercesc;
+
#ifdef BUILD_AS_PLUGINS
PLUMA_CONNECTOR
bool pluginConnect(pluma::Host& host) {
@@ -36,26 +42,88 @@ bool pluginConnect(pluma::Host& host) {
}
#endif
-USCXMLInvoker::USCXMLInvoker() : _cancelled(false) {
- _parentQueue._invoker = this;
+USCXMLInvoker::USCXMLInvoker() {
+ _parentQueue = EventQueue(std::shared_ptr<ParentQueueImpl>(new ParentQueueImpl(this)));
+ _thread = NULL;
+ _isActive = false;
+ _isStarted = false;
}
USCXMLInvoker::~USCXMLInvoker() {
+ stop();
};
+void USCXMLInvoker::start() {
+ _isStarted = true;
+ _thread = new std::thread(USCXMLInvoker::run, this);
+}
+
+void USCXMLInvoker::stop() {
+ _isStarted = false;
+ _isActive = false;
+
+ if (_thread) {
+ /**
+ * We cannot join the invoked thread if it is blocking at an external
+ * receive. Cancel will finalize and unblock.
+ */
+ _invokedInterpreter.cancel();
+ _thread->join();
+ delete _thread;
+ _thread = NULL;
+ }
+}
+
void USCXMLInvoker::uninvoke() {
- _cancelled = true;
- Event event;
- event.name = "unblock.and.die";
- if (_invokedInterpreter)
+ _isActive = false;
+ stop();
+}
+
+void USCXMLInvoker::eventFromSCXML(const Event& event) {
+ if (_isActive) {
_invokedInterpreter.receive(event);
+ }
+}
+
+void USCXMLInvoker::run(void* instance) {
+ USCXMLInvoker* INSTANCE = (USCXMLInvoker*)instance;
+
+#ifdef APPLE
+ std::string threadName;
+ threadName += "uscxml::";
+ threadName += (INSTANCE->_invokedInterpreter.getImpl()->_name.size() > 0 ? INSTANCE->_invokedInterpreter.getImpl()->_name : "anon");
+ threadName += ".scxml";
+
+ pthread_setname_np(threadName.c_str());
+#endif
+ InterpreterState state = USCXML_UNDEF;
+ while(state != USCXML_FINISHED) {
+ state = INSTANCE->_invokedInterpreter.step(true);
+
+// if (!INSTANCE->_isStarted) {
+// // we have been cancelled
+// INSTANCE->_isActive = false;
+// return;
+// }
+ }
+
+ if (INSTANCE->_isActive) {
+ // we finished on our own and were not cancelled
+ Event e;
+ e.eventType = Event::PLATFORM;
+ e.invokeid = INSTANCE->_invokedInterpreter.getImpl()->getInvokeId();
+ e.name = "done.invoke." + e.invokeid;
+ INSTANCE->_interpreter->enqueueExternal(e);
+ }
+
+ INSTANCE->_isActive = false;
}
-boost::shared_ptr<InvokerImpl> USCXMLInvoker::create(InterpreterImpl* interpreter) {
- boost::shared_ptr<USCXMLInvoker> invoker = boost::shared_ptr<USCXMLInvoker>(new USCXMLInvoker());
- invoker->_parentInterpreter = interpreter;
+std::shared_ptr<InvokerImpl> USCXMLInvoker::create(InterpreterImpl* interpreter) {
+ std::shared_ptr<USCXMLInvoker> invoker(new USCXMLInvoker());
+ invoker->_interpreter = interpreter;
return invoker;
}
@@ -64,71 +132,65 @@ Data USCXMLInvoker::getDataModelVariables() {
return data;
}
-void USCXMLInvoker::send(const SendRequest& req) {
- if (_invokedInterpreter)
- _invokedInterpreter.receive(req);
-}
-
-void USCXMLInvoker::cancel(const std::string sendId) {
- assert(false);
-}
+void USCXMLInvoker::invoke(const std::string& source, const Event& invokeEvent) {
+ if (source.length() > 0) {
+ _invokedInterpreter = Interpreter::fromURL(source);
+ } else if (invokeEvent.data.node) {
+ xercesc::DOMImplementation* implementation = xercesc::DOMImplementationRegistry::getDOMImplementation(X("core"));
+ xercesc::DOMDocument* document = implementation->createDocument();
-void USCXMLInvoker::invoke(const InvokeRequest& req) {
- _cancelled = false;
- if (req.src.length() > 0) {
- _invokedInterpreter = Interpreter::fromURL(req.src);
- } else if (req.dom) {
- Arabica::DOM::DOMImplementation<std::string> domFactory = Arabica::SimpleDOM::DOMImplementation<std::string>::getDOMImplementation();
- Arabica::DOM::Document<std::string> dom = domFactory.createDocument(req.dom.getNamespaceURI(), "", 0);
// we need to import the parent - to support xpath test150
- Arabica::DOM::Node<std::string> newNode = dom.importNode(req.dom, true);
- dom.appendChild(newNode);
+ xercesc::DOMNode* newNode = document->importNode(invokeEvent.data.node, true);
+ document->appendChild(newNode);
+
+// std::cout << *document << std::endl;
+
// TODO: where do we get the namespace from?
- _invokedInterpreter = Interpreter::fromDOM(dom, _interpreter->getNameSpaceInfo(), _interpreter->getSourceURL());
- } else if (req.content.size() > 0) {
- _invokedInterpreter = Interpreter::fromXML(req.content, _interpreter->getSourceURL());
+ _invokedInterpreter = Interpreter::fromDocument(document, _interpreter->getBaseURL());
+
} else {
- LOG(ERROR) << "Cannot invoke nested SCXML interpreter, neither src attribute nor content nor DOM is given";
+ _isActive = false;
+ ERROR_PLATFORM_THROW("Cannot invoke nested SCXML interpreter, neither src attribute nor content nor DOM is given");
}
- if (_invokedInterpreter) {
- if (req.elem && HAS_ATTR(req.elem, "initial")) {
- _invokedInterpreter.setInitalConfiguration(tokenize(ATTR(req.elem, "initial")));
- }
- DataModel dataModel(_invokedInterpreter.getImpl()->getDataModel());
- _invokedInterpreter.getImpl()->setParentQueue(&_parentQueue);
+ if (_invokedInterpreter) {
+ _invokedInterpreter.getImpl()->_parentQueue = _parentQueue;
+ _invokedInterpreter.getImpl()->_invokeId = invokeEvent.invokeid;
+ _invokedInterpreter.getImpl()->_invokeReq = invokeEvent;
// copy monitors
- std::set<InterpreterMonitor*>::const_iterator monIter = _interpreter->_monitors.begin();
- while(monIter != _interpreter->_monitors.end()) {
- if ((*monIter)->copyToInvokers()) {
- _invokedInterpreter.getImpl()->_monitors.insert(*monIter);
- }
- monIter++;
- }
-
- // transfer namespace prefixes
- _invokedInterpreter.setNameSpaceInfo(_parentInterpreter->getNameSpaceInfo());
- _invokedInterpreter.getImpl()->_sessionId = req.invokeid;
+// std::set<InterpreterMonitor*>::const_iterator monIter = _interpreter->_monitors.begin();
+// while(monIter != _interpreter->_monitors.end()) {
+// if ((*monIter)->copyToInvokers()) {
+// _invokedInterpreter.getImpl()->_monitors.insert(*monIter);
+// }
+// monIter++;
+// }
+
/// test240 assumes that invoke request params will carry over to the datamodel
- _invokedInterpreter.getImpl()->setInvokeRequest(req);
+// _invokedInterpreter.getImpl()->setInvokeRequest(req);
+ _isActive = true;
+
+ // we need to make sure it is at least setup to receive data!
+ _invokedInterpreter.getImpl()->init();
+
+ start();
- _invokedInterpreter.start();
} else {
/// test 530
- _parentInterpreter->receive(Event("done.invoke." + _invokeId, Event::PLATFORM));
+ Event e("done.invoke." + invokeEvent.invokeid, Event::PLATFORM);
+ eventToSCXML(e, USCXML_INVOKER_SCXML_TYPE, _invokeId);
+ _isActive = false;
}
}
-void USCXMLInvoker::ParentQueue::push(const SendRequest& event) {
+void USCXMLInvoker::ParentQueueImpl::enqueue(const Event& event) {
// test 252
- if (_invoker->_cancelled)
+ if (!_invoker->_isActive)
return;
- SendRequest copyEvent(event);
- // this is somewhat hidden here!
- copyEvent.invokeid = _invoker->_invokeId;
- _invoker->_parentInterpreter->receive(copyEvent);
+ Event copy(event); // TODO: can we get around a copy?
+ _invoker->eventToSCXML(copy, USCXML_INVOKER_SCXML_TYPE, _invoker->_invokeId);
}
} \ No newline at end of file
diff --git a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.h b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.h
index f5f8fbd..dac8d8b 100644
--- a/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.h
+++ b/src/uscxml/plugins/invoker/scxml/USCXMLInvoker.h
@@ -21,56 +21,57 @@
#define USCXMLINVOKER_H_OQFA21IO
#include <uscxml/Interpreter.h>
-#include <boost/enable_shared_from_this.hpp>
-#include "uscxml/concurrency/BlockingQueue.h"
+#include "uscxml/interpreter/EventQueueImpl.h"
#ifdef BUILD_AS_PLUGINS
#include "uscxml/plugins/Plugins.h"
#endif
-namespace uscxml {
+#define USCXML_INVOKER_SCXML_TYPE "http://www.w3.org/TR/scxml"
-class Interpreter;
-class USCXMLInvoker;
+namespace uscxml {
class USCXMLInvoker :
public InvokerImpl,
- public boost::enable_shared_from_this<USCXMLInvoker> {
+ public std::enable_shared_from_this<USCXMLInvoker> {
public:
- class ParentQueue : public concurrency::BlockingQueue<SendRequest> {
+ class ParentQueueImpl : public EventQueueImpl {
public:
- ParentQueue() {}
- virtual void push(const SendRequest& event);
+ ParentQueueImpl(USCXMLInvoker* invoker) : _invoker(invoker) {}
+ virtual void enqueue(const Event& event);
USCXMLInvoker* _invoker;
};
USCXMLInvoker();
virtual ~USCXMLInvoker();
- virtual boost::shared_ptr<InvokerImpl> create(InterpreterImpl* interpreter);
+ virtual std::shared_ptr<InvokerImpl> create(InterpreterImpl* interpreter);
+
virtual std::list<std::string> getNames() {
std::list<std::string> names;
names.push_back("scxml");
names.push_back("uscxml");
- names.push_back("http://www.w3.org/TR/scxml");
+ names.push_back(USCXML_INVOKER_SCXML_TYPE);
names.push_back("http://www.w3.org/TR/scxml/");
return names;
}
- virtual bool deleteOnUninvoke() {
- return false;
- }
+ virtual void eventFromSCXML(const Event& event);
virtual Data getDataModelVariables();
- virtual void send(const SendRequest& req);
- virtual void cancel(const std::string sendId);
- virtual void invoke(const InvokeRequest& req);
+ virtual void invoke(const std::string& source, const Event& invokeEvent);
virtual void uninvoke();
protected:
- bool _cancelled;
- ParentQueue _parentQueue;
+
+ void start();
+ void stop();
+ static void run(void* instance);
+
+ bool _isActive;
+ bool _isStarted;
+ std::thread* _thread;
+ EventQueue _parentQueue;
Interpreter _invokedInterpreter;
- InterpreterImpl* _parentInterpreter;
};
#ifdef BUILD_AS_PLUGINS