/** * @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 . * @endcond */ #ifndef INTERPRETERIMPL_H_2A79C83D #define INTERPRETERIMPL_H_2A79C83D #include #include #include #include #include #include #include "uscxml/Common.h" #include "uscxml/util/URL.h" #include "uscxml/plugins/Factory.h" #include "uscxml/plugins/DataModelImpl.h" #include "uscxml/plugins/IOProcessorImpl.h" #include "uscxml/plugins/InvokerImpl.h" #include "uscxml/plugins/ExecutableContent.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" namespace uscxml { class InterpreterMonitor; class InterpreterIssue; /** * @ingroup interpreter * @ingroup impl */ class USCXML_API InterpreterImpl : public MicroStepCallbacks, public DataModelCallbacks, public IOProcessorCallbacks, public ContentExecutorCallbacks, public DelayedEventQueueCallbacks, public InvokerCallbacks, public std::enable_shared_from_this { public: enum Binding { EARLY = 0, LATE = 1 }; InterpreterImpl(); virtual ~InterpreterImpl(); void cloneFrom(InterpreterImpl* other); void cloneFrom(std::shared_ptr other); virtual InterpreterState step(size_t blockMs); virtual void reset();///< Reset state machine virtual void cancel(); ///< Cancel and finalize state machine virtual void deserialize(const std::string& encodedState); virtual std::string serialize(); InterpreterState getState() { return _state; } std::list getConfiguration() { return _microStepper.getConfiguration(); } void addMonitor(InterpreterMonitor* monitor) { _monitors.insert(monitor); } void removeMonitor(InterpreterMonitor* monitor) { _monitors.erase(monitor); } /** MicrostepCallbacks */ virtual Event dequeueInternal() { _currEvent = _internalQueue.dequeue(0); if (_currEvent) _dataModel.setEvent(_currEvent); return _currEvent; } virtual Event dequeueExternal(size_t blockMs); virtual bool isTrue(const std::string& expr); virtual void raiseDoneEvent(XERCESC_NS::DOMElement* state, XERCESC_NS::DOMElement* doneData) { _execContent.raiseDoneEvent(state, doneData); } virtual void process(XERCESC_NS::DOMElement* block) { _execContent.process(block); } virtual bool isMatched(const Event& event, const std::string& eventDesc); virtual void initData(XERCESC_NS::DOMElement* element); virtual void invoke(XERCESC_NS::DOMElement* invoke) { _execContent.invoke(invoke); } virtual void uninvoke(XERCESC_NS::DOMElement* invoke) { _execContent.uninvoke(invoke); } virtual std::set getMonitors() { return _monitors; } virtual Interpreter getInterpreter() { return Interpreter(shared_from_this()); } virtual Data& getCache() { return _cache; } /** DataModelCallbacks */ virtual const std::string& getName() { return _name; } virtual const std::string& getSessionId() { return _sessionId; } virtual const std::map& getIOProcessors() { return _ioProcs; } virtual const std::map& getInvokers() { return _invokers; } virtual bool isInState(const std::string& stateId) { return _microStepper.isInState(stateId); } virtual XERCESC_NS::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 void eval(const std::string& content) { _dataModel.eval(content); } virtual Data getAsData(const std::string& expr) { return _dataModel.getAsData(expr); } virtual void assign(const std::string& location, const Data& data, const std::map& attrs); 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_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); virtual const Event& getCurrentEvent() { return _currEvent; } virtual ExecutableContent createExecutableContent(const std::string& localName, const std::string& nameSpace) { return Factory::getInstance()->createExecutableContent(localName, nameSpace, this); } /** IOProcessorCallbacks */ virtual void enqueueAtInvoker(const std::string& invokeId, const Event& event); virtual void enqueueAtParent(const Event& event); /** DelayedEventQueueCallbacks */ virtual void eventReady(Event& event, const std::string& eventUUID); /** --- */ void setActionLanguage(const ActionLanguage& al) { if (al.logger) // we intialized _logger as the default logger already _logger = al.logger; _execContent = al.execContent; _microStepper = al.microStepper; _dataModel = al.dataModel; _internalQueue = al.internalQueue; _externalQueue = al.externalQueue; _delayQueue = al.delayQueue; } ActionLanguage* getActionLanguage() { _al.logger = _logger; _al.execContent = _execContent; _al.microStepper = _microStepper; _al.dataModel = _dataModel; _al.internalQueue = _internalQueue; _al.externalQueue = _externalQueue; _al.delayQueue = _delayQueue; return &_al; } void setFactory(Factory* factory) { _factory = factory; } virtual Logger getLogger() { return _logger; } static std::map > getInstances(); virtual XERCESC_NS::DOMDocument* getDocument() { return _document; } LambdaMonitor& on(); protected: static void addInstance(std::shared_ptr instance); LambdaMonitor* _lambdaMonitor = NULL; Binding _binding; ActionLanguage _al; std::string _sessionId; std::string _name; std::string _invokeId; // TODO: Never set! bool _isInitialized; XERCESC_NS::DOMDocument* _document; XERCESC_NS::DOMElement* _scxml; std::map > _delayedEventTargets; virtual void init(); static std::map > _instances; static std::recursive_mutex _instanceMutex; std::recursive_mutex _delayMutex; std::recursive_mutex _serializationMutex; friend class Interpreter; friend class InterpreterIssue; friend class TransformerImpl; friend class USCXMLInvoker; friend class SCXMLIOProcessor; friend class DebugSession; friend class Debugger; std::string _xmlPrefix; std::string _xmlNS; Factory* _factory; URL _baseURL; std::string _md5; MicroStep _microStepper; DataModel _dataModel; ContentExecutor _execContent; Logger _logger = Logger::getDefault(); InterpreterState _state; EventQueue _internalQueue; EventQueue _externalQueue; EventQueue _parentQueue; DelayedEventQueue _delayQueue; Event _currEvent; Event _invokeReq; std::map _ioProcs; std::map _invokers; std::map _finalize; std::set _autoForwarders; std::set _monitors; Data _cache; private: void setupDOM(); }; } #endif /* end of include guard: INTERPRETERIMPL_H_2A79C83D */