diff options
author | Stefan Radomski <github@mintwerk.de> | 2016-05-19 08:03:50 (GMT) |
---|---|---|
committer | Stefan Radomski <github@mintwerk.de> | 2016-05-19 08:03:50 (GMT) |
commit | 5de792adc6796b0f03d62124765b4af0676dde46 (patch) | |
tree | e700d6b008b21c037aebcc1882fd9286920b2987 /src/uscxml/interpreter | |
parent | f8e0c96fddfdd5f086e1bd973d6b0a19c39c93da (diff) | |
download | uscxml-5de792adc6796b0f03d62124765b4af0676dde46.zip uscxml-5de792adc6796b0f03d62124765b4af0676dde46.tar.gz uscxml-5de792adc6796b0f03d62124765b4af0676dde46.tar.bz2 |
Refactored for public headers and started documentation
Diffstat (limited to 'src/uscxml/interpreter')
19 files changed, 775 insertions, 342 deletions
diff --git a/src/uscxml/interpreter/ContentExecutorImpl.cpp b/src/uscxml/interpreter/BasicContentExecutor.cpp index 6a06bec..2010ae2 100644 --- a/src/uscxml/interpreter/ContentExecutorImpl.cpp +++ b/src/uscxml/interpreter/BasicContentExecutor.cpp @@ -17,13 +17,13 @@ * @endcond */ -#include "ContentExecutorImpl.h" +#include "BasicContentExecutor.h" #include "uscxml/util/String.h" #include "uscxml/util/Predicates.h" #include "uscxml/util/UUID.h" #include "uscxml/util/URL.h" -#include "uscxml/messages/Data.h" +#include <xercesc/dom/DOM.hpp> #include <xercesc/parsers/XercesDOMParser.hpp> #include <xercesc/sax/HandlerBase.hpp> #include <xercesc/framework/MemBufInputSource.hpp> @@ -32,14 +32,14 @@ namespace uscxml { -using namespace xercesc; +using namespace XERCESC_NS; -void BasicContentExecutorImpl::processRaise(xercesc::DOMElement* content) { +void BasicContentExecutor::processRaise(XERCESC_NS::DOMElement* content) { Event raised(ATTR(content, "event")); _callbacks->enqueueInternal(raised); } -void BasicContentExecutorImpl::processSend(xercesc::DOMElement* element) { +void BasicContentExecutor::processSend(XERCESC_NS::DOMElement* element) { Event sendEvent; std::string target; std::string type = "http://www.w3.org/TR/scxml/#SCXMLEventProcessor"; // default @@ -193,7 +193,7 @@ void BasicContentExecutorImpl::processSend(xercesc::DOMElement* element) { } -void BasicContentExecutorImpl::processCancel(xercesc::DOMElement* content) { +void BasicContentExecutor::processCancel(XERCESC_NS::DOMElement* content) { std::string sendid; if (HAS_ATTR(content, "sendid")) { sendid = ATTR(content, "sendid"); @@ -206,7 +206,7 @@ void BasicContentExecutorImpl::processCancel(xercesc::DOMElement* content) { _callbacks->cancelDelayed(sendid); } -void BasicContentExecutorImpl::processIf(xercesc::DOMElement* content) { +void BasicContentExecutor::processIf(XERCESC_NS::DOMElement* content) { bool blockIsTrue = _callbacks->isTrue(ATTR(content, "cond")); DOMNodeList* children = content->getChildNodes(); @@ -241,12 +241,12 @@ void BasicContentExecutorImpl::processIf(xercesc::DOMElement* content) { } } -void BasicContentExecutorImpl::processAssign(xercesc::DOMElement* content) { +void BasicContentExecutor::processAssign(XERCESC_NS::DOMElement* content) { std::string location = ATTR(content, "location"); _callbacks->assign(location, elementAsData(content)); } -void BasicContentExecutorImpl::processForeach(xercesc::DOMElement* content) { +void BasicContentExecutor::processForeach(XERCESC_NS::DOMElement* content) { std::string array = ATTR(content, "array"); std::string item = ATTR(content, "item"); std::string index = (HAS_ATTR(content, "index") ? ATTR(content, "index") : ""); @@ -266,7 +266,7 @@ void BasicContentExecutorImpl::processForeach(xercesc::DOMElement* content) { } } -void BasicContentExecutorImpl::processLog(xercesc::DOMElement* content) { +void BasicContentExecutor::processLog(XERCESC_NS::DOMElement* content) { std::string label = ATTR(content, "label"); std::string expr = ATTR(content, "expr"); @@ -277,14 +277,14 @@ void BasicContentExecutorImpl::processLog(xercesc::DOMElement* content) { std::cout << d << std::endl; } -void BasicContentExecutorImpl::processScript(xercesc::DOMElement* content) { +void BasicContentExecutor::processScript(XERCESC_NS::DOMElement* content) { // download as necessary std::string scriptContent(X(content->getTextContent())); _callbacks->evalAsData(scriptContent); } -void BasicContentExecutorImpl::process(xercesc::DOMElement* block, const X& xmlPrefix) { +void BasicContentExecutor::process(XERCESC_NS::DOMElement* block, const X& xmlPrefix) { std::string tagName = TAGNAME(block); @@ -379,7 +379,7 @@ void BasicContentExecutorImpl::process(xercesc::DOMElement* block, const X& xmlP } -void BasicContentExecutorImpl::invoke(xercesc::DOMElement* element) { +void BasicContentExecutor::invoke(XERCESC_NS::DOMElement* element) { std::string type; std::string source; bool autoForward = false; @@ -475,7 +475,7 @@ void BasicContentExecutorImpl::invoke(xercesc::DOMElement* element) { USCXML_MONITOR_CALLBACK2(_callbacks->getMonitor(), afterUninvoking, element, invokeEvent.invokeid); } -void BasicContentExecutorImpl::uninvoke(xercesc::DOMElement* invoke) { +void BasicContentExecutor::uninvoke(XERCESC_NS::DOMElement* invoke) { // TODO: DANGER This is the real danger here char* invokeId = (char*)invoke->getUserData(X("invokeid")); assert(invokeId != NULL); @@ -487,7 +487,7 @@ void BasicContentExecutorImpl::uninvoke(xercesc::DOMElement* invoke) { free(invokeId); } -void BasicContentExecutorImpl::raiseDoneEvent(xercesc::DOMElement* state, xercesc::DOMElement* doneData) { +void BasicContentExecutor::raiseDoneEvent(XERCESC_NS::DOMElement* state, XERCESC_NS::DOMElement* doneData) { Event doneEvent; doneEvent.name = "done.state."; @@ -535,7 +535,7 @@ void BasicContentExecutorImpl::raiseDoneEvent(xercesc::DOMElement* state, xerces } -void BasicContentExecutorImpl::processNameLists(std::map<std::string, Data>& nameMap, DOMElement* element) { +void BasicContentExecutor::processNameLists(std::map<std::string, Data>& nameMap, DOMElement* element) { if (HAS_ATTR(element, "namelist")) { std::list<std::string> names = tokenize(ATTR(element, "namelist")); for (std::list<std::string>::const_iterator nameIter = names.begin(); nameIter != names.end(); nameIter++) { @@ -544,7 +544,7 @@ void BasicContentExecutorImpl::processNameLists(std::map<std::string, Data>& nam } } -void BasicContentExecutorImpl::processParams(std::multimap<std::string, Data>& paramMap, DOMElement* element) { +void BasicContentExecutor::processParams(std::multimap<std::string, Data>& paramMap, DOMElement* element) { std::list<DOMElement*> params = DOMUtils::filterChildElements(XML_PREFIX(element).str() + "param", element); for (auto paramIter = params.begin(); paramIter != params.end(); paramIter++) { std::string name = ATTR(*paramIter, "name"); @@ -560,7 +560,7 @@ void BasicContentExecutorImpl::processParams(std::multimap<std::string, Data>& p } } -Data BasicContentExecutorImpl::elementAsData(xercesc::DOMElement* element) { +Data BasicContentExecutor::elementAsData(XERCESC_NS::DOMElement* element) { if (HAS_ATTR(element, "expr")) { // return _callbacks->evalAsData(ATTR(element, "expr")); if (LOCALNAME(element) == "content") { @@ -586,22 +586,22 @@ Data BasicContentExecutorImpl::elementAsData(xercesc::DOMElement* element) { // make an attempt to parse as XML try { - xercesc::XercesDOMParser* parser = new xercesc::XercesDOMParser(); - parser->setValidationScheme(xercesc::XercesDOMParser::Val_Always); + XERCESC_NS::XercesDOMParser* parser = new XERCESC_NS::XercesDOMParser(); + parser->setValidationScheme(XERCESC_NS::XercesDOMParser::Val_Always); parser->setDoNamespaces(true); - parser->useScanner(xercesc::XMLUni::fgWFXMLScanner); + parser->useScanner(XERCESC_NS::XMLUni::fgWFXMLScanner); - xercesc::ErrorHandler* errHandler = new xercesc::HandlerBase(); + XERCESC_NS::ErrorHandler* errHandler = new XERCESC_NS::HandlerBase(); parser->setErrorHandler(errHandler); std::string tmp = url; - xercesc::MemBufInputSource is((XMLByte*)content.c_str(), content.size(), X("fake")); + XERCESC_NS::MemBufInputSource is((XMLByte*)content.c_str(), content.size(), X("fake")); parser->parse(is); Data d; - xercesc::DOMDocument* doc = parser->adoptDocument(); - d.adoptedDoc = std::make_shared<xercesc::DOMDocument*>(doc); + XERCESC_NS::DOMDocument* doc = parser->adoptDocument(); + d.adoptedDoc = std::make_shared<XERCESC_NS::DOMDocument*>(doc); d.node = doc->getDocumentElement(); return d; diff --git a/src/uscxml/interpreter/BasicContentExecutor.h b/src/uscxml/interpreter/BasicContentExecutor.h new file mode 100644 index 0000000..c3549f6 --- /dev/null +++ b/src/uscxml/interpreter/BasicContentExecutor.h @@ -0,0 +1,63 @@ +/** + * @file + * @author 2016 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#ifndef BASICCONTENTEXECUTOR_H_B873199D +#define BASICCONTENTEXECUTOR_H_B873199D + +#include "ContentExecutorImpl.h" + +namespace uscxml { + +using namespace XERCESC_NS; + +/** + * @ingroup execcontent + * @ingroup impl + */ +class USCXML_API BasicContentExecutor : public ContentExecutorImpl { +public: + BasicContentExecutor(ContentExecutorCallbacks* callbacks) : ContentExecutorImpl(callbacks) {} + virtual ~BasicContentExecutor() {} + + void processRaise(XERCESC_NS::DOMElement* content); + void processSend(XERCESC_NS::DOMElement* element); + void processCancel(XERCESC_NS::DOMElement* content); + void processIf(XERCESC_NS::DOMElement* content); + void processAssign(XERCESC_NS::DOMElement* content); + void processForeach(XERCESC_NS::DOMElement* content); + void processLog(XERCESC_NS::DOMElement* content); + void processScript(XERCESC_NS::DOMElement* content); + + virtual void process(XERCESC_NS::DOMElement* block, const X& xmlPrefix); + + virtual void invoke(XERCESC_NS::DOMElement* invoke); + virtual void uninvoke(XERCESC_NS::DOMElement* invoke); + virtual void raiseDoneEvent(XERCESC_NS::DOMElement* state, XERCESC_NS::DOMElement* doneData); + + virtual Data elementAsData(XERCESC_NS::DOMElement* element); + +protected: + void processNameLists(std::map<std::string, Data>& nameMap, XERCESC_NS::DOMElement* element); + void processParams(std::multimap<std::string, Data>& paramMap, XERCESC_NS::DOMElement* element); + +}; + +} + +#endif /* end of include guard: BASICCONTENTEXECUTOR_H_B873199D */ diff --git a/src/uscxml/interpreter/EventQueueImpl.cpp b/src/uscxml/interpreter/BasicEventQueue.cpp index 345da69..5d3fa2d 100644 --- a/src/uscxml/interpreter/EventQueueImpl.cpp +++ b/src/uscxml/interpreter/BasicEventQueue.cpp @@ -17,7 +17,7 @@ * @endcond */ -#include "EventQueueImpl.h" +#include "BasicEventQueue.h" #include <event2/util.h> // for evutil_socket_t #include <event2/thread.h> #include <assert.h> @@ -26,12 +26,12 @@ namespace uscxml { -EventQueueImpl::EventQueueImpl() { +BasicEventQueue::BasicEventQueue() { } -EventQueueImpl::~EventQueueImpl() { +BasicEventQueue::~BasicEventQueue() { } -Event EventQueueImpl::dequeue(bool blocking) { +Event BasicEventQueue::dequeue(bool blocking) { std::lock_guard<std::recursive_mutex> lock(_mutex); if (blocking) { while (_queue.empty()) { @@ -48,7 +48,7 @@ Event EventQueueImpl::dequeue(bool blocking) { } -void EventQueueImpl::enqueue(const Event& event) { +void BasicEventQueue::enqueue(const Event& event) { std::lock_guard<std::recursive_mutex> lock(_mutex); _queue.push_back(event); _cond.notify_all(); @@ -62,7 +62,7 @@ static void dummyCallback(evutil_socket_t fd, short what, void *arg) { evtimer_add(ev, &tv); } -DelayedEventQueueImpl::DelayedEventQueueImpl(DelayedEventQueueCallbacks* callbacks) { +BasicDelayedEventQueue::BasicDelayedEventQueue(DelayedEventQueueCallbacks* callbacks) { _callbacks = callbacks; #ifndef _WIN32 evthread_use_pthreads(); @@ -84,14 +84,14 @@ DelayedEventQueueImpl::DelayedEventQueueImpl(DelayedEventQueueCallbacks* callbac start(); } -DelayedEventQueueImpl::~DelayedEventQueueImpl() { +BasicDelayedEventQueue::~BasicDelayedEventQueue() { stop(); evtimer_del(_dummyEvent); event_free(_dummyEvent); event_base_free(_eventLoop); } -void DelayedEventQueueImpl::timerCallback(evutil_socket_t fd, short what, void *arg) { +void BasicDelayedEventQueue::timerCallback(evutil_socket_t fd, short what, void *arg) { struct callbackData *data = (struct callbackData*)arg; std::lock_guard<std::recursive_mutex> lock(data->eventQueue->_mutex); @@ -103,7 +103,7 @@ void DelayedEventQueueImpl::timerCallback(evutil_socket_t fd, short what, void * data->eventQueue->_callbackData.erase(data->eventUUID); } -void DelayedEventQueueImpl::enqueueDelayed(const Event& event, size_t delayMs, const std::string& eventUUID) { +void BasicDelayedEventQueue::enqueueDelayed(const Event& event, size_t delayMs, const std::string& eventUUID) { std::lock_guard<std::recursive_mutex> lock(_mutex); if(_callbackData.find(eventUUID) != _callbackData.end()) { cancelDelayed(eventUUID); @@ -121,7 +121,7 @@ void DelayedEventQueueImpl::enqueueDelayed(const Event& event, size_t delayMs, c event_add(e, &delay); } -void DelayedEventQueueImpl::cancelAllDelayed() { +void BasicDelayedEventQueue::cancelAllDelayed() { std::lock_guard<std::recursive_mutex> lock(_mutex); while(_callbackData.size() > 0) { @@ -134,7 +134,7 @@ void DelayedEventQueueImpl::cancelAllDelayed() { } -void DelayedEventQueueImpl::cancelDelayed(const std::string& eventId) { +void BasicDelayedEventQueue::cancelDelayed(const std::string& eventId) { std::lock_guard<std::recursive_mutex> lock(_mutex); if(_callbackData.find(eventId) != _callbackData.end()) { @@ -144,8 +144,8 @@ void DelayedEventQueueImpl::cancelDelayed(const std::string& eventId) { } } -void DelayedEventQueueImpl::run(void* instance) { - DelayedEventQueueImpl* INSTANCE = (DelayedEventQueueImpl*)instance; +void BasicDelayedEventQueue::run(void* instance) { + BasicDelayedEventQueue* INSTANCE = (BasicDelayedEventQueue*)instance; int result; while(INSTANCE->_isStarted) { /** @@ -165,15 +165,15 @@ void DelayedEventQueueImpl::run(void* instance) { } } -void DelayedEventQueueImpl::start() { +void BasicDelayedEventQueue::start() { if (_isStarted) { return; } _isStarted = true; - _thread = new std::thread(DelayedEventQueueImpl::run, this); + _thread = new std::thread(BasicDelayedEventQueue::run, this); } -void DelayedEventQueueImpl::stop() { +void BasicDelayedEventQueue::stop() { if (_isStarted) { _isStarted = false; event_base_loopbreak(_eventLoop); diff --git a/src/uscxml/interpreter/BasicEventQueue.h b/src/uscxml/interpreter/BasicEventQueue.h new file mode 100644 index 0000000..cfb2b5d --- /dev/null +++ b/src/uscxml/interpreter/BasicEventQueue.h @@ -0,0 +1,98 @@ +/** + * @file + * @author 2016 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#ifndef BASICEVENTQUEUE_H_39DCC18B +#define BASICEVENTQUEUE_H_39DCC18B + + +#include "EventQueueImpl.h" +#include <string> +#include <map> +#include <list> +#include <thread> +#include <mutex> +#include <condition_variable> + +#include <event2/event.h> + + +namespace uscxml { + +/** + * @ingroup eventqueue + * @ingroup impl + */ +class USCXML_API BasicEventQueue : public EventQueueImpl { +public: + BasicEventQueue(); + virtual ~BasicEventQueue(); + virtual Event dequeue(bool blocking); + virtual void enqueue(const Event& event); + +protected: + std::list<Event> _queue; + std::recursive_mutex _mutex; + std::condition_variable_any _cond; +}; + +/** + * @ingroup eventqueue + * @ingroup impl + */ +class USCXML_API BasicDelayedEventQueue : public BasicEventQueue, public DelayedEventQueueImpl { +public: + BasicDelayedEventQueue(DelayedEventQueueCallbacks* callbacks); + virtual ~BasicDelayedEventQueue(); + virtual void enqueueDelayed(const Event& event, size_t delayMs, const std::string& eventUUID); + virtual void cancelDelayed(const std::string& eventId); + virtual void cancelAllDelayed(); + virtual Event dequeue(bool blocking) { + return BasicEventQueue::dequeue(blocking); + } + virtual void enqueue(const Event& event) { + return BasicEventQueue::enqueue(event); + } + +protected: + struct callbackData { + Event userData; + std::string eventUUID; + bool persist; + struct event *event; + BasicDelayedEventQueue* eventQueue; + }; + + bool _isStarted; + std::thread* _thread; + + std::map<std::string, callbackData> _callbackData; + struct event_base* _eventLoop; + struct event* _dummyEvent; + + static void run(void* instance); + void start(); + void stop(); + + static void timerCallback(evutil_socket_t fd, short what, void *arg); + DelayedEventQueueCallbacks* _callbacks; +}; + +} + +#endif /* end of include guard: BASICEVENTQUEUE_H_39DCC18B */ diff --git a/src/uscxml/interpreter/ContentExecutor.cpp b/src/uscxml/interpreter/ContentExecutor.cpp new file mode 100644 index 0000000..e26d66a --- /dev/null +++ b/src/uscxml/interpreter/ContentExecutor.cpp @@ -0,0 +1,46 @@ +/** + * @file + * @author 2016 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + + +#include "ContentExecutor.h" +#include "ContentExecutorImpl.h" + +namespace uscxml { + +void ContentExecutor::process(XERCESC_NS::DOMElement* block, const X& xmlPrefix) { + _impl->process(block, xmlPrefix); +} + +void ContentExecutor::invoke(XERCESC_NS::DOMElement* invoke) { + _impl->invoke(invoke); +} + +void ContentExecutor::uninvoke(XERCESC_NS::DOMElement* invoke) { + _impl->uninvoke(invoke); +} + +Data ContentExecutor::elementAsData(XERCESC_NS::DOMElement* element) { + return _impl->elementAsData(element); +} + +void ContentExecutor::raiseDoneEvent(XERCESC_NS::DOMElement* state, XERCESC_NS::DOMElement* doneData) { + return _impl->raiseDoneEvent(state, doneData); +} + +} diff --git a/src/uscxml/interpreter/ContentExecutor.h b/src/uscxml/interpreter/ContentExecutor.h new file mode 100644 index 0000000..64f5a95 --- /dev/null +++ b/src/uscxml/interpreter/ContentExecutor.h @@ -0,0 +1,59 @@ +/** + * @file + * @author 2016 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#ifndef CONTENTEXECUTOR_H_A2D592FA +#define CONTENTEXECUTOR_H_A2D592FA + + +#include "uscxml/config.h" +#include "uscxml/Common.h" +#include "uscxml/messages/Data.h" +#include <string> + +// forward declare +namespace XERCESC_NS { + class DOMElement; +} + +namespace uscxml { + +class ContentExecutorImpl; +class X; + +/** + * @ingroup execcontent + * @ingroup facade + */ +class USCXML_API ContentExecutor { +public: + PIMPL_OPERATORS(ContentExecutor); + + virtual void process(XERCESC_NS::DOMElement* block, const X& xmlPrefix); + virtual void invoke(XERCESC_NS::DOMElement* invoke); + virtual void uninvoke(XERCESC_NS::DOMElement* invoke); + virtual Data elementAsData(XERCESC_NS::DOMElement* element); + virtual void raiseDoneEvent(XERCESC_NS::DOMElement* state, XERCESC_NS::DOMElement* doneData); + +protected: + std::shared_ptr<ContentExecutorImpl> _impl; +}; + +} + +#endif /* end of include guard: CONTENTEXECUTOR_H_A2D592FA */ diff --git a/src/uscxml/interpreter/ContentExecutorImpl.h b/src/uscxml/interpreter/ContentExecutorImpl.h index c0d28a2..e1a7e8c 100644 --- a/src/uscxml/interpreter/ContentExecutorImpl.h +++ b/src/uscxml/interpreter/ContentExecutorImpl.h @@ -17,20 +17,24 @@ * @endcond */ +#ifndef CONTENTEXECUTORIMPL_H_3ABA8969 +#define CONTENTEXECUTORIMPL_H_3ABA8969 -#ifndef CONTENTEXECUTORIMPL_H_13F2884F -#define CONTENTEXECUTORIMPL_H_13F2884F #include "uscxml/Common.h" #include "uscxml/util/DOM.h" -#include "uscxml/messages/Data.h" #include "uscxml/messages/Event.h" #include "uscxml/interpreter/InterpreterMonitor.h" + #include <xercesc/dom/DOM.hpp> #include <string> namespace uscxml { +/** + * @ingroup execcontent + * @ingroup callback + */ class USCXML_API ContentExecutorCallbacks { public: virtual void enqueueInternal(const Event& event) = 0; @@ -55,7 +59,7 @@ public: virtual std::string getBaseURL() = 0; virtual bool checkValidSendType(const std::string& type, const std::string& target) = 0; virtual void enqueue(const std::string& type, const std::string& target, size_t delayMs, const Event& sendEvent) = 0; - virtual void invoke(const std::string& type, const std::string& src, bool autoForward, xercesc::DOMElement* finalize, const Event& invokeEvent) = 0; + virtual void invoke(const std::string& type, const std::string& src, bool autoForward, XERCESC_NS::DOMElement* finalize, const Event& invokeEvent) = 0; virtual void uninvoke(const std::string& invokeId) = 0; virtual const Event& getCurrentEvent() = 0; @@ -65,79 +69,27 @@ public: }; +/** + * @ingroup execcontent + * @ingroup impl + */ class USCXML_API ContentExecutorImpl { public: ContentExecutorImpl(ContentExecutorCallbacks* callbacks) : _callbacks(callbacks) {} - virtual void process(xercesc::DOMElement* block, const X& xmlPrefix) = 0; + virtual void process(XERCESC_NS::DOMElement* block, const X& xmlPrefix) = 0; - virtual void invoke(xercesc::DOMElement* invoke) = 0; - virtual void uninvoke(xercesc::DOMElement* invoke) = 0; + virtual void invoke(XERCESC_NS::DOMElement* invoke) = 0; + virtual void uninvoke(XERCESC_NS::DOMElement* invoke) = 0; - virtual void raiseDoneEvent(xercesc::DOMElement* state, xercesc::DOMElement* doneData) = 0; - virtual Data elementAsData(xercesc::DOMElement* element) = 0; + virtual void raiseDoneEvent(XERCESC_NS::DOMElement* state, XERCESC_NS::DOMElement* doneData) = 0; + virtual Data elementAsData(XERCESC_NS::DOMElement* element) = 0; protected: ContentExecutorCallbacks* _callbacks; }; -class USCXML_API BasicContentExecutorImpl : public ContentExecutorImpl { -public: - BasicContentExecutorImpl(ContentExecutorCallbacks* callbacks) : ContentExecutorImpl(callbacks) {} - virtual ~BasicContentExecutorImpl() {} - - void processRaise(xercesc::DOMElement* content); - void processSend(xercesc::DOMElement* element); - void processCancel(xercesc::DOMElement* content); - void processIf(xercesc::DOMElement* content); - void processAssign(xercesc::DOMElement* content); - void processForeach(xercesc::DOMElement* content); - void processLog(xercesc::DOMElement* content); - void processScript(xercesc::DOMElement* content); - - virtual void process(xercesc::DOMElement* block, const X& xmlPrefix); - - virtual void invoke(xercesc::DOMElement* invoke); - virtual void uninvoke(xercesc::DOMElement* invoke); - virtual void raiseDoneEvent(xercesc::DOMElement* state, xercesc::DOMElement* doneData); - - virtual Data elementAsData(xercesc::DOMElement* element); - -protected: - void processNameLists(std::map<std::string, Data>& nameMap, xercesc::DOMElement* element); - void processParams(std::multimap<std::string, Data>& paramMap, xercesc::DOMElement* element); - -}; - -class USCXML_API ContentExecutor { -public: - PIMPL_OPERATORS(ContentExecutor) - - virtual void process(xercesc::DOMElement* block, const X& xmlPrefix) { - _impl->process(block, xmlPrefix); - } - - virtual void invoke(xercesc::DOMElement* invoke) { - _impl->invoke(invoke); - } - - virtual void uninvoke(xercesc::DOMElement* invoke) { - _impl->uninvoke(invoke); - } - - virtual Data elementAsData(xercesc::DOMElement* element) { - return _impl->elementAsData(element); - } - - virtual void raiseDoneEvent(xercesc::DOMElement* state, xercesc::DOMElement* doneData) { - return _impl->raiseDoneEvent(state, doneData); - } - -protected: - std::shared_ptr<ContentExecutorImpl> _impl; -}; - } -#endif /* end of include guard: CONTENTEXECUTORIMPL_H_13F2884F */ +#endif /* end of include guard: CONTENTEXECUTORIMPL_H_3ABA8969 */ diff --git a/src/uscxml/interpreter/EventQueue.cpp b/src/uscxml/interpreter/EventQueue.cpp new file mode 100644 index 0000000..9b9fa88 --- /dev/null +++ b/src/uscxml/interpreter/EventQueue.cpp @@ -0,0 +1,56 @@ +/** + * @file + * @author 2016 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#include "uscxml/Common.h" +#include "EventQueue.h" +#include "EventQueueImpl.h" +#include <string> +#include <map> +#include <list> +#include <thread> +#include <mutex> +#include <condition_variable> + +#include <event2/event.h> + + +namespace uscxml { + +Event EventQueue::dequeue(bool blocking) { + return _impl->dequeue(blocking); +} +void EventQueue::enqueue(const Event& event) { + return _impl->enqueue(event); +} + +PIMPL_OPERATORS_INHERIT_IMPL(DelayedEventQueue, EventQueue) + +void DelayedEventQueue::enqueueDelayed(const Event& event, size_t delayMs, const std::string& eventUUID) { + _impl->enqueueDelayed(event, delayMs, eventUUID); +} +void DelayedEventQueue::cancelDelayed(const std::string& eventUUID) { + return _impl->cancelDelayed(eventUUID); +} + +void DelayedEventQueue::cancelAllDelayed() { + return _impl->cancelAllDelayed(); +} + +} + diff --git a/src/uscxml/interpreter/EventQueue.h b/src/uscxml/interpreter/EventQueue.h new file mode 100644 index 0000000..4409b72 --- /dev/null +++ b/src/uscxml/interpreter/EventQueue.h @@ -0,0 +1,65 @@ +/** + * @file + * @author 2016 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#ifndef EVENTQUEUE_H_C5C41BEE +#define EVENTQUEUE_H_C5C41BEE + +#include "uscxml/Common.h" +#include "uscxml/messages/Event.h" + +namespace uscxml { + +class EventQueueImpl; +class DelayedEventQueueImpl; + +/** + * @ingroup eventqueue + * @ingroup facade + */ +class USCXML_API EventQueue { +public: + PIMPL_OPERATORS(EventQueue); + + virtual Event dequeue(bool blocking); + virtual void enqueue(const Event& event); + +protected: + std::shared_ptr<EventQueueImpl> _impl; + +}; + +/** + * @ingroup eventqueue + * @ingroup facade + */ +class USCXML_API DelayedEventQueue : public EventQueue { +public: + PIMPL_OPERATORS_INHERIT(DelayedEventQueue, EventQueue); + + void enqueueDelayed(const Event& event, size_t delayMs, const std::string& eventUUID); + void cancelDelayed(const std::string& eventUUID); + void cancelAllDelayed(); + +protected: + std::shared_ptr<DelayedEventQueueImpl> _impl; +}; + +} + +#endif /* end of include guard: EVENTQUEUE_H_C5C41BEE */ diff --git a/src/uscxml/interpreter/EventQueueImpl.h b/src/uscxml/interpreter/EventQueueImpl.h index 10543c9..1cafd4d 100644 --- a/src/uscxml/interpreter/EventQueueImpl.h +++ b/src/uscxml/interpreter/EventQueueImpl.h @@ -17,8 +17,8 @@ * @endcond */ -#ifndef EVENTSOURCE_H_775AB206 -#define EVENTSOURCE_H_775AB206 +#ifndef EVENTQUEUEIMPL_H_48027643 +#define EVENTQUEUEIMPL_H_48027643 #include "uscxml/Common.h" #include "uscxml/messages/Event.h" @@ -34,92 +34,36 @@ namespace uscxml { +/** + * @ingroup eventqueue + * @ingroup impl + */ class USCXML_API EventQueueImpl { public: - EventQueueImpl(); - virtual ~EventQueueImpl(); - virtual Event dequeue(bool blocking); - virtual void enqueue(const Event& event); - -protected: - std::list<Event> _queue; - std::recursive_mutex _mutex; - std::condition_variable_any _cond; - + virtual Event dequeue(bool blocking) = 0; + virtual void enqueue(const Event& event) = 0; }; +/** + * @ingroup eventqueue + * @ingroup callback + */ class USCXML_API DelayedEventQueueCallbacks { public: virtual void eventReady(Event& event, const std::string& eventId) = 0; }; +/** + * @ingroup eventqueue + * @ingroup impl + */ class USCXML_API DelayedEventQueueImpl : public EventQueueImpl { public: - DelayedEventQueueImpl(DelayedEventQueueCallbacks* callbacks); - virtual ~DelayedEventQueueImpl(); - virtual void enqueueDelayed(const Event& event, size_t delayMs, const std::string& eventUUID); - virtual void cancelDelayed(const std::string& eventId); - virtual void cancelAllDelayed(); - -protected: - struct callbackData { - Event userData; - std::string eventUUID; - bool persist; - struct event *event; - DelayedEventQueueImpl* eventQueue; - }; - - bool _isStarted; - std::thread* _thread; - - std::map<std::string, callbackData> _callbackData; - struct event_base* _eventLoop; - struct event* _dummyEvent; - - static void run(void* instance); - void start(); - void stop(); - - static void timerCallback(evutil_socket_t fd, short what, void *arg); - DelayedEventQueueCallbacks* _callbacks; -}; - -class USCXML_API EventQueue { -public: - PIMPL_OPERATORS(EventQueue) - - virtual Event dequeue(bool blocking) { - return _impl->dequeue(blocking); - } - virtual void enqueue(const Event& event) { - return _impl->enqueue(event); - } - -protected: - std::shared_ptr<EventQueueImpl> _impl; - -}; - -class USCXML_API DelayedEventQueue : public EventQueue { -public: - PIMPL_OPERATORS2(DelayedEventQueue, EventQueue) - - void enqueueDelayed(const Event& event, size_t delayMs, const std::string& eventUUID) { - _impl->enqueueDelayed(event, delayMs, eventUUID); - } - void cancelDelayed(const std::string& eventUUID) { - return _impl->cancelDelayed(eventUUID); - } - - void cancelAllDelayed() { - return _impl->cancelAllDelayed(); - } - -protected: - std::shared_ptr<DelayedEventQueueImpl> _impl; + virtual void enqueueDelayed(const Event& event, size_t delayMs, const std::string& eventUUID) = 0; + virtual void cancelDelayed(const std::string& eventId) = 0; + virtual void cancelAllDelayed() = 0; }; } -#endif /* end of include guard: EVENTSOURCE_H_775AB206 */ +#endif /* end of include guard: EVENTQUEUEIMPL_H_48027643 */ diff --git a/src/uscxml/interpreter/MicroStepFast.cpp b/src/uscxml/interpreter/FastMicroStep.cpp index 158c3ee..99c2d74 100644 --- a/src/uscxml/interpreter/MicroStepFast.cpp +++ b/src/uscxml/interpreter/FastMicroStep.cpp @@ -19,7 +19,7 @@ #undef USCXML_VERBOSE -#include "MicroStepFast.h" +#include "FastMicroStep.h" #include "uscxml/util/DOM.h" #include "uscxml/util/String.h" #include "uscxml/util/Predicates.h" @@ -74,13 +74,13 @@ namespace uscxml { -using namespace xercesc; +using namespace XERCESC_NS; -MicroStepFast::MicroStepFast(MicroStepCallbacks* callbacks) +FastMicroStep::FastMicroStep(MicroStepCallbacks* callbacks) : MicroStepImpl(callbacks), _flags(USCXML_CTX_PRISTINE), _isInitialized(false), _isCancelled(false) { } -MicroStepFast::~MicroStepFast() { +FastMicroStep::~FastMicroStep() { for (size_t i = 0; i < _states.size(); i++) { delete(_states[i]); } @@ -89,7 +89,7 @@ MicroStepFast::~MicroStepFast() { } } -void MicroStepFast::resortStates(DOMNode* node, const X& xmlPrefix) { +void FastMicroStep::resortStates(DOMNode* node, const X& xmlPrefix) { if (node->getNodeType() != DOMNode::ELEMENT_NODE) return; @@ -155,7 +155,7 @@ void MicroStepFast::resortStates(DOMNode* node, const X& xmlPrefix) { } } -void MicroStepFast::init(xercesc::DOMElement* scxml) { +void FastMicroStep::init(XERCESC_NS::DOMElement* scxml) { _scxml = scxml; _binding = (HAS_ATTR(_scxml, "binding") && iequals(ATTR(_scxml, "binding"), "late") ? LATE : EARLY); @@ -172,17 +172,18 @@ void MicroStepFast::init(xercesc::DOMElement* scxml) { /** -- All things states -- */ - std::list<xercesc::DOMElement*> tmp; + std::list<XERCESC_NS::DOMElement*> tmp; size_t i, j; - tmp = DOMUtils::inDocumentOrder({ - _xmlPrefix.str() + "state", - _xmlPrefix.str() + "parallel", - _xmlPrefix.str() + "scxml", - _xmlPrefix.str() + "initial", - _xmlPrefix.str() + "final", - _xmlPrefix.str() + "history"}, _scxml); - + tmp = DOMUtils::inDocumentOrder({ + _xmlPrefix.str() + "state", + _xmlPrefix.str() + "parallel", + _xmlPrefix.str() + "scxml", + _xmlPrefix.str() + "initial", + _xmlPrefix.str() + "final", + _xmlPrefix.str() + "history" + }, _scxml); + _states.resize(tmp.size()); _configuration.resize(tmp.size()); _history.resize(tmp.size()); @@ -307,7 +308,7 @@ void MicroStepFast::init(xercesc::DOMElement* scxml) { /** -- All things transitions -- */ - tmp = DOMUtils::inPostFixOrder({_xmlPrefix.str() + "transition"}, _scxml); + tmp = DOMUtils::inPostFixOrder({_xmlPrefix.str() + "transition"}, _scxml); _transitions.resize(tmp.size()); for (i = 0; i < _transitions.size(); i++) { @@ -318,13 +319,13 @@ void MicroStepFast::init(xercesc::DOMElement* scxml) { _transitions[i]->target.resize(_states.size()); tmp.pop_front(); } - assert(tmp.size() == 0); - + assert(tmp.size() == 0); + for (i = 0; i < _transitions.size(); i++) { // establish the transitions' exit set - assert(_transitions[i]->element != NULL); - std::cout << "i: " << i << std::endl << std::flush; + assert(_transitions[i]->element != NULL); + std::cout << "i: " << i << std::endl << std::flush; std::list<DOMElement*> exitList = getExitSet(_transitions[i]->element, _scxml); for (j = 0; j < _states.size(); j++) { if (!exitList.empty() && _states[j]->element == exitList.front()) { @@ -393,11 +394,11 @@ void MicroStepFast::init(xercesc::DOMElement* scxml) { _isInitialized = true; } -void MicroStepFast::markAsCancelled() { +void FastMicroStep::markAsCancelled() { _isCancelled = true; } -InterpreterState MicroStepFast::step(bool blocking) { +InterpreterState FastMicroStep::step(bool blocking) { if (!_isInitialized) { init(_scxml); return USCXML_INITIALIZED; @@ -911,7 +912,7 @@ ESTABLISH_ENTRYSET: return USCXML_MICROSTEPPED; } -void MicroStepFast::reset() { +void FastMicroStep::reset() { _isCancelled = false; _flags = USCXML_CTX_PRISTINE; _configuration.reset(); @@ -921,7 +922,7 @@ void MicroStepFast::reset() { } -bool MicroStepFast::isInState(const std::string& stateId) { +bool FastMicroStep::isInState(const std::string& stateId) { #ifdef USCXML_VERBOSE printStateNames(_configuration); #endif @@ -930,8 +931,8 @@ bool MicroStepFast::isInState(const std::string& stateId) { return _configuration[_stateIds[stateId]]; } -std::list<xercesc::DOMElement*> MicroStepFast::getConfiguration() { - std::list<xercesc::DOMElement*> config; +std::list<XERCESC_NS::DOMElement*> FastMicroStep::getConfiguration() { + std::list<XERCESC_NS::DOMElement*> config; size_t i = _configuration.find_first(); while(i != boost::dynamic_bitset<>::npos) { config.push_back(_states[i]->element); @@ -941,7 +942,7 @@ std::list<xercesc::DOMElement*> MicroStepFast::getConfiguration() { } -std::list<DOMElement*> MicroStepFast::getHistoryCompletion(const DOMElement* history) { +std::list<DOMElement*> FastMicroStep::getHistoryCompletion(const DOMElement* history) { std::set<std::string> elements; elements.insert(_xmlPrefix.str() + "history"); std::list<DOMElement*> histories = DOMUtils::inPostFixOrder(elements, _scxml); @@ -990,7 +991,7 @@ std::list<DOMElement*> MicroStepFast::getHistoryCompletion(const DOMElement* his /** * Print name of states contained in a (debugging). */ -void MicroStepFast::printStateNames(const boost::dynamic_bitset<>& a) { +void FastMicroStep::printStateNames(const boost::dynamic_bitset<>& a) { size_t i; const char* seperator = ""; for (i = 0; i < a.size(); i++) { @@ -1003,7 +1004,7 @@ void MicroStepFast::printStateNames(const boost::dynamic_bitset<>& a) { } #endif -std::list<DOMElement*> MicroStepFast::getCompletion(const DOMElement* state) { +std::list<DOMElement*> FastMicroStep::getCompletion(const DOMElement* state) { if (isHistory(state)) { // we already did in setHistoryCompletion @@ -1044,7 +1045,7 @@ std::list<DOMElement*> MicroStepFast::getCompletion(const DOMElement* state) { /** * See: http://www.w3.org/TR/scxml/#LegalStateConfigurations */ -bool MicroStepFast::hasLegalConfiguration() { +bool FastMicroStep::hasLegalConfiguration() { // The configuration contains exactly one child of the <scxml> element. std::list<DOMElement*> scxmlChilds = getChildStates(_scxml, true); diff --git a/src/uscxml/interpreter/MicroStepFast.h b/src/uscxml/interpreter/FastMicroStep.h index c41be80..3789af9 100644 --- a/src/uscxml/interpreter/MicroStepFast.h +++ b/src/uscxml/interpreter/FastMicroStep.h @@ -17,11 +17,14 @@ * @endcond */ -#ifndef INTERPRETERFAST_H_DA55E52B -#define INTERPRETERFAST_H_DA55E52B +#ifndef FASTMICROSTEP_H_065FE1F7 +#define FASTMICROSTEP_H_065FE1F7 //#define USCXML_VERBOSE 1 +#include "uscxml/config.h" +#include "uscxml/util/DOM.h" // X + #include <vector> #include <set> #include "MicroStepImpl.h" @@ -30,15 +33,19 @@ namespace uscxml { -class MicroStepFast : public MicroStepImpl { +/** + * @ingroup microstep + * @ingroup impl + */ +class FastMicroStep : public MicroStepImpl { public: - MicroStepFast(MicroStepCallbacks* callbacks); - virtual ~MicroStepFast(); + FastMicroStep(MicroStepCallbacks* callbacks); + virtual ~FastMicroStep(); virtual InterpreterState step(bool blocking); virtual void reset(); virtual bool isInState(const std::string& stateId); - virtual std::list<xercesc::DOMElement*> getConfiguration(); + virtual std::list<XERCESC_NS::DOMElement*> getConfiguration(); void markAsCancelled(); protected: @@ -46,14 +53,14 @@ protected: public: Transition() : element(NULL), source(0), onTrans(NULL), type(0) {} - xercesc::DOMElement* element; + XERCESC_NS::DOMElement* element; boost::dynamic_bitset<> conflicts; boost::dynamic_bitset<> exitSet; uint32_t source; boost::dynamic_bitset<> target; - xercesc::DOMElement* onTrans; + XERCESC_NS::DOMElement* onTrans; std::string event; std::string cond; @@ -66,32 +73,32 @@ protected: public: State() : element(NULL), parent(0), documentOrder(0), doneData(NULL), type(0) {} - xercesc::DOMElement* element; + XERCESC_NS::DOMElement* element; boost::dynamic_bitset<> completion; boost::dynamic_bitset<> children; boost::dynamic_bitset<> ancestors; uint32_t parent; uint32_t documentOrder; - std::list<xercesc::DOMElement*> data; - std::list<xercesc::DOMElement*> invoke; - std::list<xercesc::DOMElement*> onEntry; - std::list<xercesc::DOMElement*> onExit; - xercesc::DOMElement* doneData; + std::list<XERCESC_NS::DOMElement*> data; + std::list<XERCESC_NS::DOMElement*> invoke; + std::list<XERCESC_NS::DOMElement*> onEntry; + std::list<XERCESC_NS::DOMElement*> onExit; + XERCESC_NS::DOMElement* doneData; unsigned char type; }; - virtual void init(xercesc::DOMElement* scxml); + virtual void init(XERCESC_NS::DOMElement* scxml); - std::list<xercesc::DOMElement*> getCompletion(const xercesc::DOMElement* state); + std::list<XERCESC_NS::DOMElement*> getCompletion(const XERCESC_NS::DOMElement* state); unsigned char _flags; std::map<std::string, int> _stateIds; std::vector<State*> _states; std::vector<Transition*> _transitions; - std::list<xercesc::DOMElement*> _globalScripts; + std::list<XERCESC_NS::DOMElement*> _globalScripts; boost::dynamic_bitset<> _configuration; boost::dynamic_bitset<> _invocations; @@ -101,7 +108,7 @@ protected: std::set<boost::dynamic_bitset<> > _microstepConfigurations; Binding _binding; - xercesc::DOMElement* _scxml; + XERCESC_NS::DOMElement* _scxml; X _xmlPrefix; X _xmlNS; @@ -110,8 +117,8 @@ protected: Event _event; // we do not care about the event's representation private: - std::list<xercesc::DOMElement*> getHistoryCompletion(const xercesc::DOMElement* state); - void resortStates(xercesc::DOMNode* node, const X& xmlPrefix); + std::list<XERCESC_NS::DOMElement*> getHistoryCompletion(const XERCESC_NS::DOMElement* state); + void resortStates(XERCESC_NS::DOMNode* node, const X& xmlPrefix); // bool hasLegalConfiguration(); @@ -123,5 +130,5 @@ private: } -#endif /* end of include guard: INTERPRETERFAST_H_DA55E52B */ +#endif /* end of include guard: FASTMICROSTEP_H_065FE1F7 */ diff --git a/src/uscxml/interpreter/InterpreterImpl.cpp b/src/uscxml/interpreter/InterpreterImpl.cpp index e61c4ab..880afbc 100644 --- a/src/uscxml/interpreter/InterpreterImpl.cpp +++ b/src/uscxml/interpreter/InterpreterImpl.cpp @@ -17,12 +17,16 @@ * @endcond */ +#include "uscxml/config.h" #include "uscxml/Common.h" #include "uscxml/util/UUID.h" #include "uscxml/Interpreter.h" +#include "uscxml/interpreter/InterpreterImpl.h" // beware cyclic reference! +#include "uscxml/interpreter/BasicEventQueue.h" #include "uscxml/messages/Event.h" #include "uscxml/util/String.h" #include "uscxml/util/Predicates.h" +#include "uscxml/plugins/InvokerImpl.h" #include "easylogging++.h" @@ -33,14 +37,16 @@ #include <memory> #include <mutex> -#include "uscxml/interpreter/MicroStepFast.h" +#include "uscxml/interpreter/FastMicroStep.h" +#include "uscxml/interpreter/BasicContentExecutor.h" + +#include <xercesc/dom/DOM.hpp> +#include <xercesc/util/PlatformUtils.hpp> #define VERBOSE 0 namespace uscxml { -using namespace xercesc; - std::map<std::string, std::weak_ptr<InterpreterImpl> > InterpreterImpl::_instances; std::recursive_mutex InterpreterImpl::_instanceMutex; @@ -65,8 +71,8 @@ void InterpreterImpl::addInstance(std::shared_ptr<InterpreterImpl> interpreterIm InterpreterImpl::InterpreterImpl() : _isInitialized(false), _document(NULL), _scxml(NULL), _state(USCXML_INSTANTIATED), _monitor(NULL) { try { - xercesc::XMLPlatformUtils::Initialize(); - } catch (const xercesc::XMLException& toCatch) { + ::xercesc_3_1::XMLPlatformUtils::Initialize(); + } catch (const XERCESC_NS::XMLException& toCatch) { ERROR_PLATFORM_THROW("Cannot initialize XercesC: " + X(toCatch.getMessage()).str()); } @@ -80,7 +86,7 @@ InterpreterImpl::~InterpreterImpl() { _delayQueue.cancelAllDelayed(); if (_document) delete _document; - + { std::lock_guard<std::recursive_mutex> lock(_instanceMutex); _instances.erase(getSessionId()); @@ -102,7 +108,7 @@ void InterpreterImpl::setupDOM() { if (!_scxml) { // find scxml element - DOMNodeList* scxmls = NULL; + XERCESC_NS::DOMNodeList* scxmls = NULL; // proper namespace scxmls = _document->getElementsByTagNameNS(X("http://www.w3.org/2005/07/scxml"), X("scxml")); @@ -120,7 +126,7 @@ SCXML_STOP_SEARCH: return; } - _scxml = dynamic_cast<DOMElement*>(scxmls->item(0)); + _scxml = dynamic_cast<XERCESC_NS::DOMElement*>(scxmls->item(0)); _xmlPrefix = _scxml->getPrefix(); _xmlNS = _scxml->getNamespaceURI(); @@ -171,7 +177,7 @@ void InterpreterImpl::init() { } if (!_microStepper) { - _microStepper = MicroStep(std::shared_ptr<MicroStepImpl>(new MicroStepFast(this))); + _microStepper = MicroStep(std::shared_ptr<MicroStepImpl>(new FastMicroStep(this))); } _microStepper.init(_scxml); @@ -179,23 +185,23 @@ void InterpreterImpl::init() { _dataModel = _factory->createDataModel(HAS_ATTR(_scxml, "datamodel") ? ATTR(_scxml, "datamodel") : "null", this); } if (!_execContent) { - _execContent = ContentExecutor(std::shared_ptr<ContentExecutorImpl>(new BasicContentExecutorImpl(this))); + _execContent = ContentExecutor(std::shared_ptr<ContentExecutorImpl>(new BasicContentExecutor(this))); } if (!_externalQueue) { - _externalQueue = EventQueue(std::shared_ptr<EventQueueImpl>(new EventQueueImpl())); + _externalQueue = EventQueue(std::shared_ptr<EventQueueImpl>(new BasicEventQueue())); } if (!_internalQueue) { - _internalQueue = EventQueue(std::shared_ptr<EventQueueImpl>(new EventQueueImpl())); + _internalQueue = EventQueue(std::shared_ptr<EventQueueImpl>(new BasicEventQueue())); } if (!_delayQueue) { - _delayQueue = DelayedEventQueue(std::shared_ptr<DelayedEventQueueImpl>(new DelayedEventQueueImpl(this))); + _delayQueue = DelayedEventQueue(std::shared_ptr<DelayedEventQueueImpl>(new BasicDelayedEventQueue(this))); } _isInitialized = true; } -void InterpreterImpl::initData(xercesc::DOMElement* root) { +void InterpreterImpl::initData(XERCESC_NS::DOMElement* root) { std::string id = ATTR(root, "id"); Data d; try { @@ -330,7 +336,7 @@ void InterpreterImpl::eventReady(Event& sendEvent, const std::string& eventUUID) } } -void InterpreterImpl::invoke(const std::string& type, const std::string& src, bool autoForward, xercesc::DOMElement* finalize, const Event& invokeEvent) { +void InterpreterImpl::invoke(const std::string& type, const std::string& src, bool autoForward, XERCESC_NS::DOMElement* finalize, const Event& invokeEvent) { std::string tmp; if (src.size() > 0) { diff --git a/src/uscxml/interpreter/InterpreterImpl.h b/src/uscxml/interpreter/InterpreterImpl.h index 7c64779..e1abf9b 100644 --- a/src/uscxml/interpreter/InterpreterImpl.h +++ b/src/uscxml/interpreter/InterpreterImpl.h @@ -17,8 +17,8 @@ * @endcond */ -#ifndef INTERPRETERIMPL_H_29D5BEBA -#define INTERPRETERIMPL_H_29D5BEBA +#ifndef INTERPRETERIMPL_H_2A79C83D +#define INTERPRETERIMPL_H_2A79C83D #include <memory> #include <mutex> @@ -29,9 +29,10 @@ #include "uscxml/Common.h" #include "uscxml/util/URL.h" #include "uscxml/plugins/Factory.h" -#include "uscxml/plugins/DataModel.h" +#include "uscxml/plugins/DataModelImpl.h" #include "uscxml/interpreter/MicroStepImpl.h" #include "uscxml/interpreter/ContentExecutorImpl.h" +#include "uscxml/interpreter/EventQueue.h" #include "uscxml/interpreter/EventQueueImpl.h" #include "uscxml/util/DOM.h" #include <xercesc/dom/DOM.hpp> @@ -41,13 +42,10 @@ namespace uscxml { class InterpreterMonitor; class InterpreterIssue; -class USCXML_API ActionLanguage { -public: - MicroStep microStepper; - DataModel dataModel; - ContentExecutor execContent; -}; - +/** + * @ingroup interpreter + * @ingroup impl + */ class USCXML_API InterpreterImpl : public MicroStepCallbacks, public DataModelCallbacks, @@ -92,7 +90,7 @@ public: return _state; } - std::list<xercesc::DOMElement*> getConfiguration() { + std::list<XERCESC_NS::DOMElement*> getConfiguration() { return _microStepper.getConfiguration(); } @@ -112,22 +110,22 @@ public: virtual Event dequeueExternal(bool blocking); virtual bool isTrue(const std::string& expr); - virtual void raiseDoneEvent(xercesc::DOMElement* state, xercesc::DOMElement* doneData) { + virtual void raiseDoneEvent(XERCESC_NS::DOMElement* state, XERCESC_NS::DOMElement* doneData) { _execContent.raiseDoneEvent(state, doneData); } - virtual void process(xercesc::DOMElement* block) { + virtual void process(XERCESC_NS::DOMElement* block) { _execContent.process(block, _xmlPrefix); } virtual bool isMatched(const Event& event, const std::string& eventDesc); - virtual void initData(xercesc::DOMElement* element); + virtual void initData(XERCESC_NS::DOMElement* element); - virtual void invoke(xercesc::DOMElement* invoke) { + virtual void invoke(XERCESC_NS::DOMElement* invoke) { _execContent.invoke(invoke); } - virtual void uninvoke(xercesc::DOMElement* invoke) { + virtual void uninvoke(XERCESC_NS::DOMElement* invoke) { _execContent.uninvoke(invoke); } @@ -154,7 +152,7 @@ public: virtual bool isInState(const std::string& stateId) { return _microStepper.isInState(stateId); } - virtual xercesc::DOMDocument* getDocument() const { + virtual XERCESC_NS::DOMDocument* getDocument() const { return _document; } @@ -201,7 +199,7 @@ public: } virtual bool checkValidSendType(const std::string& type, const std::string& target); - virtual void invoke(const std::string& type, const std::string& src, bool autoForward, xercesc::DOMElement* finalize, const Event& invokeEvent); + virtual void invoke(const std::string& type, const std::string& src, bool autoForward, XERCESC_NS::DOMElement* finalize, const Event& invokeEvent); virtual void uninvoke(const std::string& invokeId); virtual void enqueue(const std::string& type, const std::string& target, size_t delayMs, const Event& sendEvent); @@ -225,7 +223,7 @@ public: static std::map<std::string, std::weak_ptr<InterpreterImpl> > getInstances(); - virtual xercesc::DOMDocument* getDocument() { + virtual XERCESC_NS::DOMDocument* getDocument() { return _document; } @@ -239,8 +237,8 @@ protected: std::string _invokeId; // TODO: Never set! bool _isInitialized; - xercesc::DOMDocument* _document; - xercesc::DOMElement* _scxml; + XERCESC_NS::DOMDocument* _document; + XERCESC_NS::DOMElement* _scxml; std::map<std::string, std::tuple<std::string, std::string, std::string> > _delayedEventTargets; @@ -287,4 +285,4 @@ private: } -#endif /* end of include guard: INTERPRETERIMPL_H_29D5BEBA */ +#endif /* end of include guard: INTERPRETERIMPL_H_2A79C83D */ diff --git a/src/uscxml/interpreter/InterpreterMonitor.h b/src/uscxml/interpreter/InterpreterMonitor.h index 6ebdb35..901e1eb 100644 --- a/src/uscxml/interpreter/InterpreterMonitor.h +++ b/src/uscxml/interpreter/InterpreterMonitor.h @@ -17,8 +17,8 @@ * @endcond */ -#ifndef INTERPRETERMONITOR_H_4BA77097 -#define INTERPRETERMONITOR_H_4BA77097 +#ifndef INTERPRETERMONITOR_H_D3F21429 +#define INTERPRETERMONITOR_H_D3F21429 #include "uscxml/Common.h" #include "uscxml/messages/Event.h" @@ -51,23 +51,23 @@ public: virtual void beforeProcessingEvent(const Event& event) {} virtual void beforeMicroStep() {} - virtual void beforeExitingState(const xercesc::DOMElement* state) {} - virtual void afterExitingState(const xercesc::DOMElement* state) {} + virtual void beforeExitingState(const XERCESC_NS::DOMElement* state) {} + virtual void afterExitingState(const XERCESC_NS::DOMElement* state) {} - virtual void beforeExecutingContent(const xercesc::DOMElement* execContent) {} - virtual void afterExecutingContent(const xercesc::DOMElement* execContent) {} + virtual void beforeExecutingContent(const XERCESC_NS::DOMElement* execContent) {} + virtual void afterExecutingContent(const XERCESC_NS::DOMElement* execContent) {} - virtual void beforeUninvoking(const xercesc::DOMElement* invokeElem, const std::string& invokeid) {} - virtual void afterUninvoking(const xercesc::DOMElement* invokeElem, const std::string& invokeid) {} + virtual void beforeUninvoking(const XERCESC_NS::DOMElement* invokeElem, const std::string& invokeid) {} + virtual void afterUninvoking(const XERCESC_NS::DOMElement* invokeElem, const std::string& invokeid) {} - virtual void beforeTakingTransition(const xercesc::DOMElement* transition) {} - virtual void afterTakingTransition(const xercesc::DOMElement* transition) {} + virtual void beforeTakingTransition(const XERCESC_NS::DOMElement* transition) {} + virtual void afterTakingTransition(const XERCESC_NS::DOMElement* transition) {} - virtual void beforeEnteringState(const xercesc::DOMElement* state) {} - virtual void afterEnteringState(const xercesc::DOMElement* state) {} + virtual void beforeEnteringState(const XERCESC_NS::DOMElement* state) {} + virtual void afterEnteringState(const XERCESC_NS::DOMElement* state) {} - virtual void beforeInvoking(const xercesc::DOMElement* invokeElem, const std::string& invokeid) {} - virtual void afterInvoking(const xercesc::DOMElement* invokeElem, const std::string& invokeid) {} + virtual void beforeInvoking(const XERCESC_NS::DOMElement* invokeElem, const std::string& invokeid) {} + virtual void afterInvoking(const XERCESC_NS::DOMElement* invokeElem, const std::string& invokeid) {} virtual void afterMicroStep() {} virtual void onStableConfiguration() {} @@ -90,6 +90,23 @@ protected: }; +class USCXML_API StateTransitionMonitor : public uscxml::InterpreterMonitor { +public: + StateTransitionMonitor() {} + virtual ~StateTransitionMonitor() {} + + virtual void beforeTakingTransition(const XERCESC_NS::DOMElement* transition); + virtual void beforeExecutingContent(const XERCESC_NS::DOMElement* element); + virtual void onStableConfiguration(); + virtual void beforeProcessingEvent(const uscxml::Event& event); + virtual void beforeExitingState(const XERCESC_NS::DOMElement* state); + virtual void beforeEnteringState(const XERCESC_NS::DOMElement* state); + virtual void beforeMicroStep(); + +protected: + static std::recursive_mutex _mutex; +}; + } -#endif /* end of include guard: INTERPRETERMONITOR_H_4BA77097 */ +#endif /* end of include guard: INTERPRETERMONITOR_H_D3F21429 */ diff --git a/src/uscxml/interpreter/InterpreterState.h b/src/uscxml/interpreter/InterpreterState.h new file mode 100644 index 0000000..a4741ed --- /dev/null +++ b/src/uscxml/interpreter/InterpreterState.h @@ -0,0 +1,44 @@ +/** + * @file + * @author 2016 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + + +#ifndef INTERPRETERSTATE_H_E6CCAEA5 +#define INTERPRETERSTATE_H_E6CCAEA5 + + +#include "uscxml/Common.h" + +namespace uscxml { + +enum InterpreterState { + USCXML_FINISHED = -2, ///< machine reached a final configuration and is done + USCXML_INTERRUPTED = -1, ///< machine received the empty event on the external queue + USCXML_UNDEF = 0, ///< not an actual state + USCXML_IDLE = 1, ///< stable configuration and queues empty + USCXML_INITIALIZED = 2, ///< DOM is setup and all external components instantiated + USCXML_INSTANTIATED = 3, ///< nothing really, just instantiated + USCXML_MICROSTEPPED = 4, ///< processed one transition set + USCXML_MACROSTEPPED = 5, ///< processed all transition sets and reached a stable configuration + USCXML_CANCELLED = 6, ///< machine was cancelled, step once more to finalize +}; + + +} + +#endif /* end of include guard: INTERPRETERSTATE_H_E6CCAEA5 */ diff --git a/src/uscxml/interpreter/MicroStep.cpp b/src/uscxml/interpreter/MicroStep.cpp new file mode 100644 index 0000000..aa75c91 --- /dev/null +++ b/src/uscxml/interpreter/MicroStep.cpp @@ -0,0 +1,47 @@ +/** + * @file + * @author 2012-2016 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#include "MicroStep.h" +#include "MicroStepImpl.h" + +namespace uscxml { + +InterpreterState MicroStep::step(bool blocking) { + return _impl->step(blocking); +} +void MicroStep::reset() { + return _impl->reset(); +} +bool MicroStep::isInState(const std::string& stateId) { + return _impl->isInState(stateId); +} + +std::list<XERCESC_NS::DOMElement*> MicroStep::getConfiguration() { + return _impl->getConfiguration(); +} + +void MicroStep::init(XERCESC_NS::DOMElement* scxml) { + _impl->init(scxml); +} + +void MicroStep::markAsCancelled() { + _impl->markAsCancelled(); +} + +}
\ No newline at end of file diff --git a/src/uscxml/interpreter/MicroStep.h b/src/uscxml/interpreter/MicroStep.h new file mode 100644 index 0000000..c20e994 --- /dev/null +++ b/src/uscxml/interpreter/MicroStep.h @@ -0,0 +1,66 @@ +/** + * @file + * @author 2016 Stefan Radomski (stefan.radomski@cs.tu-darmstadt.de) + * @copyright Simplified BSD + * + * @cond + * This program is free software: you can redistribute it and/or modify + * it under the terms of the FreeBSD license as published by the FreeBSD + * project. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the FreeBSD license along with this + * program. If not, see <http://www.opensource.org/licenses/bsd-license>. + * @endcond + */ + +#ifndef MICROSTEP_H_07DA8BFA +#define MICROSTEP_H_07DA8BFA + + +#include <memory> +#include <list> +#include <string> + +#include "uscxml/config.h" +#include "uscxml/Common.h" +#include "uscxml/interpreter/InterpreterState.h" + +// #include <xercesc/dom/DOM.hpp> + +// forward declare +namespace XERCESC_NS { + class DOMElement; +} + +namespace uscxml { + +class MicroStepImpl; + +/** + * @ingroup microstep + * @ingroup facade + */ +class USCXML_API MicroStep { +public: + PIMPL_OPERATORS(MicroStep); + + virtual InterpreterState step(bool blocking); + virtual void reset(); + virtual bool isInState(const std::string& stateId); + + std::list<XERCESC_NS::DOMElement*> getConfiguration(); + + virtual void init(XERCESC_NS::DOMElement* scxml); + virtual void markAsCancelled(); + +protected: + std::shared_ptr<MicroStepImpl> _impl; +}; + +} + +#endif /* end of include guard: MICROSTEP_H_07DA8BFA */ diff --git a/src/uscxml/interpreter/MicroStepImpl.h b/src/uscxml/interpreter/MicroStepImpl.h index 71c03b5..e4cde5d 100644 --- a/src/uscxml/interpreter/MicroStepImpl.h +++ b/src/uscxml/interpreter/MicroStepImpl.h @@ -20,57 +20,50 @@ #ifndef MICROSTEPIMPL_H_98233709 #define MICROSTEPIMPL_H_98233709 -#include <memory> -#include <mutex> +#include "uscxml/config.h" + #include <list> -#include <map> #include <string> +#include <xercesc/dom/DOM.hpp> #include "uscxml/Common.h" +#include "uscxml/Interpreter.h" #include "uscxml/messages/Event.h" -#include "uscxml/interpreter/InterpreterMonitor.h" -#include "uscxml/util/DOM.h" -#include <xercesc/dom/DOM.hpp> - -namespace uscxml { - -enum InterpreterState { - USCXML_FINISHED = -2, ///< machine reached a final configuration and is done - USCXML_INTERRUPTED = -1, ///< machine received the empty event on the external queue - USCXML_UNDEF = 0, ///< not an actual state - USCXML_IDLE = 1, ///< stable configuration and queues empty - USCXML_INITIALIZED = 2, ///< DOM is setup and all external components instantiated - USCXML_INSTANTIATED = 3, ///< nothing really, just instantiated - USCXML_MICROSTEPPED = 4, ///< processed one transition set - USCXML_MACROSTEPPED = 5, ///< processed all transition sets and reached a stable configuration - USCXML_CANCELLED = 6, ///< machine was cancelled, step once more to finalize -}; +namespace uscxml { +/** + * @ingroup microstep + * @ingroup callback + */ class USCXML_API MicroStepCallbacks { public: /** Event Queues / Matching */ virtual Event dequeueInternal() = 0; virtual Event dequeueExternal(bool blocking) = 0; virtual bool isMatched(const Event& event, const std::string& eventDesc) = 0; - virtual void raiseDoneEvent(xercesc::DOMElement* state, xercesc::DOMElement* doneData) = 0; + virtual void raiseDoneEvent(XERCESC_NS::DOMElement* state, XERCESC_NS::DOMElement* doneData) = 0; /** Datamodel */ virtual bool isTrue(const std::string& expr) = 0; - virtual void initData(xercesc::DOMElement* element) = 0; + virtual void initData(XERCESC_NS::DOMElement* element) = 0; /** Executable Content */ - virtual void process(xercesc::DOMElement* block) = 0; + virtual void process(XERCESC_NS::DOMElement* block) = 0; /** Invocations */ - virtual void invoke(xercesc::DOMElement* invoke) = 0; - virtual void uninvoke(xercesc::DOMElement* invoke) = 0; + virtual void invoke(XERCESC_NS::DOMElement* invoke) = 0; + virtual void uninvoke(XERCESC_NS::DOMElement* invoke) = 0; /** Monitoring */ virtual InterpreterMonitor* getMonitor() = 0; }; +/** + * @ingroup microstep + * @ingroup impl + */ class USCXML_API MicroStepImpl { public: enum Binding { @@ -83,9 +76,9 @@ public: virtual InterpreterState step(bool blocking) = 0; virtual void reset() = 0; ///< Reset state machine virtual bool isInState(const std::string& stateId) = 0; - virtual std::list<xercesc::DOMElement*> getConfiguration() = 0; + virtual std::list<XERCESC_NS::DOMElement*> getConfiguration() = 0; - virtual void init(xercesc::DOMElement* scxml) = 0; + virtual void init(XERCESC_NS::DOMElement* scxml) = 0; virtual void markAsCancelled() = 0; protected: @@ -93,35 +86,6 @@ protected: }; -class USCXML_API MicroStep { -public: - PIMPL_OPERATORS(MicroStep) - - virtual InterpreterState step(bool blocking) { - return _impl->step(blocking); - } - virtual void reset() { - return _impl->reset(); - } - virtual bool isInState(const std::string& stateId) { - return _impl->isInState(stateId); - } - - std::list<xercesc::DOMElement*> getConfiguration() { - return _impl->getConfiguration(); - } - - virtual void init(xercesc::DOMElement* scxml) { - _impl->init(scxml); - } - - virtual void markAsCancelled() { - _impl->markAsCancelled(); - } -protected: - std::shared_ptr<MicroStepImpl> _impl; -}; - } #endif /* end of include guard: MICROSTEPIMPL_H_98233709 */ |