summaryrefslogtreecommitdiffstats
path: root/src/uscxml/Interpreter.h
blob: 7cf8a0e535b2b8bf5b85a715489d22a9fc6ca91d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
/**
 *  @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 INTERPRETER_H_6CD5A168
#define INTERPRETER_H_6CD5A168


#include "Common.h"

#include <map>
#include <string>
#include <vector>

#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 <step> 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<size_t>::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<XERCESC_NS::DOMElement*> 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<InterpreterIssue> 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<InterpreterImpl> 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<InterpreterImpl> _impl;

};

}

#endif /* end of include guard: INTERPRETER_H_6CD5A168 */