diff options
Diffstat (limited to 'src/uscxml/interpreter/InterpreterImpl.h')
-rw-r--r-- | src/uscxml/interpreter/InterpreterImpl.h | 290 |
1 files changed, 290 insertions, 0 deletions
diff --git a/src/uscxml/interpreter/InterpreterImpl.h b/src/uscxml/interpreter/InterpreterImpl.h new file mode 100644 index 0000000..7c64779 --- /dev/null +++ b/src/uscxml/interpreter/InterpreterImpl.h @@ -0,0 +1,290 @@ +/** + * @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 INTERPRETERIMPL_H_29D5BEBA +#define INTERPRETERIMPL_H_29D5BEBA + +#include <memory> +#include <mutex> +#include <list> +#include <map> +#include <string> + +#include "uscxml/Common.h" +#include "uscxml/util/URL.h" +#include "uscxml/plugins/Factory.h" +#include "uscxml/plugins/DataModel.h" +#include "uscxml/interpreter/MicroStepImpl.h" +#include "uscxml/interpreter/ContentExecutorImpl.h" +#include "uscxml/interpreter/EventQueueImpl.h" +#include "uscxml/util/DOM.h" +#include <xercesc/dom/DOM.hpp> + +namespace uscxml { + +class InterpreterMonitor; +class InterpreterIssue; + +class USCXML_API ActionLanguage { +public: + MicroStep microStepper; + DataModel dataModel; + ContentExecutor execContent; +}; + +class USCXML_API InterpreterImpl : + public MicroStepCallbacks, + public DataModelCallbacks, + public ContentExecutorCallbacks, + public DelayedEventQueueCallbacks +// public std::enable_shared_from_this<InterpreterImpl> +{ +public: + enum Binding { + EARLY = 0, + LATE = 1 + }; + + InterpreterImpl(); + virtual ~InterpreterImpl(); + + void cloneFrom(InterpreterImpl* other); + void cloneFrom(std::shared_ptr<InterpreterImpl> other); + + virtual InterpreterState step(bool blocking) { + if (!_isInitialized) { + init(); + _state = USCXML_INITIALIZED; + } else { + _state = _microStepper.step(blocking); + } + return _state; + } + + virtual void reset() {///< Reset state machine + _microStepper.reset(); + _isInitialized = false; + _state = USCXML_INSTANTIATED; +// _dataModel.reset(); +// _eventQueue.reset(); +// _contentExecutor.reset(); + } + + virtual void cancel(); ///< Cancel and finalize state machine + + InterpreterState getState() { + return _state; + } + + std::list<xercesc::DOMElement*> getConfiguration() { + return _microStepper.getConfiguration(); + } + + void setMonitor(InterpreterMonitor* monitor) { + _monitor = monitor; + } + + /** + MicrostepCallbacks + */ + virtual Event dequeueInternal() { + _currEvent = _internalQueue.dequeue(false); + if (_currEvent) + _dataModel.setEvent(_currEvent); + return _currEvent; + } + virtual Event dequeueExternal(bool blocking); + virtual bool isTrue(const std::string& expr); + + virtual void raiseDoneEvent(xercesc::DOMElement* state, xercesc::DOMElement* doneData) { + _execContent.raiseDoneEvent(state, doneData); + } + + virtual void process(xercesc::DOMElement* block) { + _execContent.process(block, _xmlPrefix); + } + + virtual bool isMatched(const Event& event, const std::string& eventDesc); + virtual void initData(xercesc::DOMElement* element); + + virtual void invoke(xercesc::DOMElement* invoke) { + _execContent.invoke(invoke); + } + + virtual void uninvoke(xercesc::DOMElement* invoke) { + _execContent.uninvoke(invoke); + } + + virtual InterpreterMonitor* getMonitor() { + return _monitor; + } + + /** + DataModelCallbacks + */ + virtual const std::string& getName() { + return _name; + } + virtual const std::string& getSessionId() { + return _sessionId; + } + virtual const std::map<std::string, IOProcessor>& getIOProcessors() { + return _ioProcs; + } + virtual const std::map<std::string, Invoker>& getInvokers() { + return _invokers; + } + + virtual bool isInState(const std::string& stateId) { + return _microStepper.isInState(stateId); + } + virtual xercesc::DOMDocument* getDocument() const { + return _document; + } + + /** + ContentExecutorCallbacks + */ + + virtual void enqueueInternal(const Event& event) { + return _internalQueue.enqueue(event); + } + virtual void enqueueExternal(const Event& event) { + return _externalQueue.enqueue(event); + } + virtual void enqueueExternalDelayed(const Event& event, size_t delayMs, const std::string& eventUUID) { + return _delayQueue.enqueueDelayed(event, delayMs, eventUUID); + } + virtual void cancelDelayed(const std::string& eventId); + + virtual size_t getLength(const std::string& expr) { + return _dataModel.getLength(expr); + } + + virtual void setForeach(const std::string& item, + const std::string& array, + const std::string& index, + uint32_t iteration) { + return _dataModel.setForeach(item, array, index, iteration); + } + virtual Data evalAsData(const std::string& expr) { + return _dataModel.evalAsData(expr); + } + + virtual Data getAsData(const std::string& expr) { + return _dataModel.getAsData(expr); + } + + virtual void assign(const std::string& location, const Data& data); + + virtual std::string getInvokeId() { + return _invokeId; + } + virtual std::string getBaseURL() { + return _baseURL; + } + + 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 uninvoke(const std::string& invokeId); + virtual void enqueue(const std::string& type, const std::string& target, size_t delayMs, const Event& sendEvent); + + virtual const Event& getCurrentEvent() { + return _currEvent; + } + + /** + DelayedEventQueueCallbacks + */ + + virtual void eventReady(Event& event, const std::string& eventUUID); + + /** --- */ + + void setActionLanguage(const ActionLanguage& al) { + _execContent = al.execContent; + _microStepper = al.microStepper; + _dataModel = al.dataModel; + } + + static std::map<std::string, std::weak_ptr<InterpreterImpl> > getInstances(); + + virtual xercesc::DOMDocument* getDocument() { + return _document; + } + +protected: + static void addInstance(std::shared_ptr<InterpreterImpl> instance); + + Binding _binding; + + std::string _sessionId; + std::string _name; + std::string _invokeId; // TODO: Never set! + + bool _isInitialized; + xercesc::DOMDocument* _document; + xercesc::DOMElement* _scxml; + + std::map<std::string, std::tuple<std::string, std::string, std::string> > _delayedEventTargets; + + virtual void init(); + + static std::map<std::string, std::weak_ptr<InterpreterImpl> > _instances; + static std::recursive_mutex _instanceMutex; + std::recursive_mutex _delayMutex; + + friend class Interpreter; + friend class InterpreterIssue; + friend class TransformerImpl; + friend class USCXMLInvoker; + friend class SCXMLIOProcessor; + + X _xmlPrefix; + X _xmlNS; + Factory* _factory; + + URL _baseURL; + + MicroStep _microStepper; + DataModel _dataModel; + ContentExecutor _execContent; + + InterpreterState _state; + + EventQueue _internalQueue; + EventQueue _externalQueue; + EventQueue _parentQueue; + DelayedEventQueue _delayQueue; + + Event _currEvent; + Event _invokeReq; + + std::map<std::string, IOProcessor> _ioProcs; + std::map<std::string, Invoker> _invokers; + std::set<std::string> _autoForwarders; + InterpreterMonitor* _monitor; + +private: + void setupDOM(); +}; + +} + +#endif /* end of include guard: INTERPRETERIMPL_H_29D5BEBA */ |