/** * @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 INTERPRETER_H_6CD5A168 #define INTERPRETER_H_6CD5A168 #include "Common.h" #include #include #include #include "uscxml/interpreter/MicroStep.h" #include "uscxml/interpreter/Logging.h" #include "uscxml/plugins/DataModel.h" #include "uscxml/plugins/Factory.h" #include "uscxml/interpreter/ContentExecutor.h" #include "uscxml/interpreter/EventQueue.h" #include "uscxml/interpreter/InterpreterState.h" #include "uscxml/interpreter/InterpreterMonitor.h" #ifdef max #error define NOMINMAX or undefine the max macro please (https://support.microsoft.com/en-us/kb/143208) #endif namespace uscxml { class InterpreterMonitor; class LambdaMonitor; class InterpreterImpl; class InterpreterIssue; class MicroStepCallbacks; class DataModelCallbacks; class IOProcessorCallbacks; class ContentExecutorCallbacks; class DelayedEventQueueCallbacks; class InvokerCallbacks; /** * @ingroup interpreter * Collection of instances for interpreter that constitute its action language. */ class USCXML_API ActionLanguage { public: Logger logger; ///< The logger instance to use for messages MicroStep microStepper; ///< The microstepper instance to use DataModel dataModel; ///< The datamodel to use ContentExecutor execContent; ///< To process executable content elements EventQueue internalQueue; ///< The queue where internal events will be enqueued EventQueue externalQueue; ///< The queue for external events DelayedEventQueue delayQueue; ///< The queue for delayed events }; /** * @ingroup interpreter * @ingroup facade * Central class to interpret and process SCXML documents. Instances of this class are available from the static constructors. In order to use an interpreter instance to actually *do* things, you will want to provide an ActionLanguage and an InterpreterMonitor. We did avoid threading primitives within the core interpreter (there is threading for nested interpeters in the USCXMLInvoker, though). As such, you will have to call the function continuously. */ class USCXML_API Interpreter { public: /** * Instantiate an Interpeter with a given XML document. * @param dom A pointer to the XML document. * @param baseURL An absolute URL to resolve relative URLs in the document. * @param copy Whether to make a copy of the document, we deallocate it either way. */ static Interpreter fromDocument(XERCESC_NS::DOMDocument* dom, const std::string& baseURL, bool copy = true); /** * Instantiate an Interpeter with a given XML element. * This constructor will create a new document and copy/import the given element. * @param element The element to be copies/imported as the new document element. * @param baseURL An absolute URL to resolve relative URLs in the document. */ static Interpreter fromElement(XERCESC_NS::DOMElement* element, const std::string& baseURL); /** * Instantiate an Interpeter from a string containined proper XML markup. * @param xml Textual representation of an SCXML document. * @param baseURL An absolute URL to resolve relative URLs in the document. */ static Interpreter fromXML(const std::string& xml, const std::string& baseURL); /** * Instantiate an Interpeter with a document located at an URL. * @param url An absolute URL to locate the SCXML document. */ static Interpreter fromURL(const std::string& url); /** * Instantiate an Interpeter as a copy of another. * @param other The other interpreter. */ static Interpreter fromClone(const Interpreter& other); /** * Get the instance of an interpreter with a given sessionId. * @param other The session ID. */ static Interpreter fromSessionId(const std::string& sessionId); /** * See PIMPL_OPERATORS macro in Common.h */ PIMPL_OPERATORS(Interpreter); /** * Advance the state-machine by a single microstep and return. * * This is the central function to drive the state machine. Calling step() * will perform one *microstep* and return the current state of the * interpreter. Here, the state is not to be confused with the interpreter's * configuration. * * \snippet test-snippets.cpp Performing a microstep * * @param blockMs The maximum duration in milli-seconds to wait for an event to become available. * @return The new state of the interpreter object. */ InterpreterState step(size_t blockMs = std::numeric_limits::max()); /** * Unblock and mark for finalize. */ void cancel(); /** * Finalize and reset interpeter. */ void reset(); /** * Deserialize the state for the interpreter from a string. */ void deserialize(const std::string& encodedState); /** * Serialize the interpreter's state in a string. */ std::string serialize(); /** * Get all state elements that constitute the active configuration. * @return A list of XML elements of the active states. */ std::list getConfiguration(); /** * Determine whether the state with the given `id` is in the active configuration. * @param id An identifier for a state from the SCXML document. * @return Whether the interpreter is in state `id`. */ bool isInState(const std::string& stateId); /** * The current state of the interpreter, not to be confused with its configuration. * @return The current state of the interpreter object. */ InterpreterState getState(); /** * Return a list of possible syntactic and semantic issues with the interpreter's state-chart. * @return A list of InterpreterIssue%s */ std::list validate(); /** * Enqueue an event to the interpreter's external queue. * @event An event to be enqueued */ void receive(const Event& event); /** * Adapt the constituting components for a SCXML interpreter. */ void setActionLanguage(ActionLanguage actionLanguage); /** * Return ActionLanguage with the instances actually used (i.e. those from the factory). */ ActionLanguage* getActionLanguage(); /** * Provide a custom Factory to instantiate dynamic instances for this and invoked state-chart instances. */ void setFactory(Factory* factory); /** * Attach a monitor to make more details of the interpreter observable. */ void addMonitor(InterpreterMonitor* monitor); /** * Remove a monitor that was attached previously. */ void removeMonitor(InterpreterMonitor* monitor); /** * Return the logger associated with this interpreter */ Logger getLogger(); /** * Return the actual implementation of the Interperter. */ std::shared_ptr getImpl() const { return _impl; } LambdaMonitor& on(); #if 0 // "Ambiguous user-defined-conversion" with operator bool() on MSVC from Visual Studio 12 explicit operator MicroStepCallbacks*() { return (MicroStepCallbacks*)(_impl.get()); } explicit operator DataModelCallbacks*() { return (DataModelCallbacks*)(_impl.get()); } explicit operator IOProcessorCallbacks*() { return (IOProcessorCallbacks*)(_impl.get()); } explicit operator ContentExecutorCallbacks*() { return (ContentExecutorCallbacks*)(_impl.get()); } explicit operator DelayedEventQueueCallbacks*() { return (DelayedEventQueueCallbacks*)(_impl.get()); } explicit operator InvokerCallbacks*() { return (InvokerCallbacks*)(_impl.get()); } #endif protected: std::shared_ptr _impl; }; } #endif /* end of include guard: INTERPRETER_H_6CD5A168 */