/[svn]/linuxsampler/trunk/src/scriptvm/common.h
ViewVC logotype

Contents of /linuxsampler/trunk/src/scriptvm/common.h

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2594 - (show annotations) (download) (as text)
Thu Jun 5 00:16:25 2014 UTC (5 years, 4 months ago) by schoenebeck
File MIME type: text/x-c++hdr
File size: 10144 byte(s)
* ScriptVM (WIP): started to integrate real-time instrument script
  support into the sampler engine implementations. The code is
  shared among all sampler engines, however currently only the gig
  file format supports storing instrument scripts (as LinuxSampler
  extension to the original GigaStudio 4 file format).
* gig engine: Added support for loading instrument scripts from .gig
  files.
* ScriptVM (WIP): Implemented built-in script variables %CC, $CC_NUM,
  $EVENT_NOTE, $EVENT_VELOCITY, $VCC_MONO_AT, $VCC_PITCH_BEND.
* ScriptVM (WIP): Implemented execution of script event handler "init".
* ScriptVM (WIP): Implemented execution of script event handler
  "controller".
* Bumped version (1.0.0.svn42).

1 /*
2 * Copyright (c) 2014 Christian Schoenebeck
3 *
4 * http://www.linuxsampler.org
5 *
6 * This file is part of LinuxSampler and released under the same terms.
7 * See README file for details.
8 */
9
10 // This header defines data types shared between the VM core implementation
11 // (inside the current source directory) and other parts of the sampler
12 // (located at other source directories).
13
14 #ifndef LS_INSTR_SCRIPT_PARSER_COMMON_H
15 #define LS_INSTR_SCRIPT_PARSER_COMMON_H
16
17 #include "../common/global.h"
18 #include <vector>
19 #include <map>
20 #include <stddef.h> // offsetof()
21
22 namespace LinuxSampler {
23
24 enum ParserIssueType_t {
25 PARSER_ERROR,
26 PARSER_WARNING
27 };
28
29 enum ExprType_t {
30 EMPTY_EXPR, ///< i.e. on invalid expressions or i.e. a function call that does not return a result value
31 INT_EXPR,
32 INT_ARR_EXPR,
33 STRING_EXPR,
34 STRING_ARR_EXPR,
35 };
36
37 enum StmtFlags_t {
38 STMT_SUCCESS = 0, ///< Function / statement was executed successfully, no error occurred.
39 STMT_ABORT_SIGNALLED = 1, ///< VM should stop the current callback execution (usually because of an error, but might also be without an error reason).
40 STMT_SUSPEND_SIGNALLED = (1<<1),
41 STMT_ERROR_OCCURRED = (1<<2),
42 };
43
44 enum VMExecStatus_t {
45 VM_EXEC_NOT_RUNNING = 0,
46 VM_EXEC_RUNNING = 1,
47 VM_EXEC_SUSPENDED = (1<<1),
48 VM_EXEC_ERROR = (1<<2),
49 };
50
51 class VMExpr {
52 public:
53 virtual ExprType_t exprType() const = 0;
54 };
55
56 class VMIntExpr : virtual public VMExpr {
57 public:
58 virtual int evalInt() = 0;
59 ExprType_t exprType() const { return INT_EXPR; }
60 };
61
62 class VMStringExpr : virtual public VMExpr {
63 public:
64 virtual String evalStr() = 0;
65 ExprType_t exprType() const { return STRING_EXPR; }
66 };
67
68 class VMFnArgs {
69 public:
70 virtual int argsCount() const = 0;
71 virtual VMExpr* arg(int i) = 0;
72 };
73
74 class VMFnResult {
75 public:
76 virtual VMExpr* resultValue() = 0;
77 virtual StmtFlags_t resultFlags() { return STMT_SUCCESS; }
78 };
79
80 class VMFunction {
81 public:
82 virtual ExprType_t returnType() = 0;
83 virtual int minRequiredArgs() const = 0;
84 virtual int maxAllowedArgs() const = 0;
85 virtual ExprType_t argType(int iArg) const = 0;
86 virtual bool acceptsArgType(int iArg, ExprType_t type) const = 0;
87 virtual VMFnResult* exec(VMFnArgs* args) = 0;
88 };
89
90 /**
91 * POD base of VMIntRelPtr and VMInt8RelPtr structures. Not intended to be
92 * used directly. Use VMIntRelPtr or VMInt8RelPtr instead.
93 */
94 struct VMRelPtr {
95 void** base; ///< Base pointer.
96 int offset; ///< Offset (in bytes) to base pointer.
97 };
98
99 /** @brief Pointer to built-in VM integer variable (of C/C++ type int).
100 *
101 * Used for defining built-in integer script variables.
102 *
103 * @b CAUTION: You may only use this class for pointing to C/C++ variables
104 * of type "int" (which on most systems is 32 bit in size). If the C/C++ int
105 * variable you want to reference is only 8 bit in size, then you @b must
106 * use VMInt8RelPtr instead!
107 *
108 * For efficiency reasons the actual native C/C++ int variable is referenced
109 * by two components here. The actual native int C/C++ variable in memory
110 * is dereferenced at VM run-time by taking the @c base pointer dereference
111 * and adding @c offset bytes. This has the advantage that for a large
112 * number of built-in int variables, only one (or few) base pointer need
113 * to be re-assigned before running a script, instead of updating each
114 * built-in variable each time before a script is executed.
115 *
116 * Refer to DECLARE_VMINT() for example code.
117 *
118 * @see VMInt8RelPtr, DECLARE_VMINT()
119 */
120 struct VMIntRelPtr : VMRelPtr {
121 VMIntRelPtr() {
122 base = NULL;
123 offset = 0;
124 }
125 VMIntRelPtr(const VMRelPtr& data) {
126 base = data.base;
127 offset = data.offset;
128 }
129 virtual int evalInt() { return *(int*)&(*(uint8_t**)base)[offset]; }
130 virtual void assign(int i) { *(int*)&(*(uint8_t**)base)[offset] = i; }
131 };
132
133 /** @brief Pointer to built-in VM integer variable (of C/C++ type int8_t).
134 *
135 * Used for defining built-in integer script variables.
136 *
137 * @b CAUTION: You may only use this class for pointing to C/C++ variables
138 * of type "int8_t" (8 bit integer). If the C/C++ int variable you want to
139 * reference is an "int" type (which is 32 bit on most systems), then you
140 * @b must use VMIntRelPtr instead!
141 *
142 * For efficiency reasons the actual native C/C++ int variable is referenced
143 * by two components here. The actual native int C/C++ variable in memory
144 * is dereferenced at VM run-time by taking the @c base pointer dereference
145 * and adding @c offset bytes. This has the advantage that for a large
146 * number of built-in int variables, only one (or few) base pointer need
147 * to be re-assigned before running a script, instead of updating each
148 * built-in variable each time before a script is executed.
149 *
150 * Refer to DECLARE_VMINT() for example code.
151 *
152 * @see VMIntRelPtr, DECLARE_VMINT()
153 */
154 struct VMInt8RelPtr : VMIntRelPtr {
155 VMInt8RelPtr() : VMIntRelPtr() {}
156 VMInt8RelPtr(const VMRelPtr& data) : VMIntRelPtr(data) {}
157 virtual int evalInt() OVERRIDE {
158 return *(uint8_t*)&(*(uint8_t**)base)[offset];
159 }
160 virtual void assign(int i) OVERRIDE {
161 *(uint8_t*)&(*(uint8_t**)base)[offset] = i;
162 }
163 };
164
165 /**
166 * Convenience macro for initializing VMIntRelPtr and VMInt8RelPtr
167 * structures. Example:
168 * @code
169 * struct Foo {
170 * uint8_t a;
171 * int b;
172 * };
173 *
174 * Foo foo1 = (Foo) { 1, 3000 };
175 * Foo foo2 = (Foo) { 2, 4000 };
176 *
177 * Foo* pFoo;
178 *
179 * VMInt8RelPtr var1 = DECLARE_VMINT(pFoo, class Foo, a);
180 * VMIntRelPtr var2 = DECLARE_VMINT(pFoo, class Foo, b);
181 *
182 * pFoo = &foo1;
183 * printf("%d\n", var1->evalInt()); // will print 1
184 * printf("%d\n", var2->evalInt()); // will print 3000
185 *
186 * pFoo = &foo2;
187 * printf("%d\n", var1->evalInt()); // will print 2
188 * printf("%d\n", var2->evalInt()); // will print 4000
189 * @endcode
190 */
191 #define DECLARE_VMINT(basePtr, T_struct, T_member) ( \
192 (VMRelPtr) { \
193 (void**) &basePtr, \
194 offsetof(T_struct, T_member) \
195 } \
196 ) \
197
198 /** @brief Built-in VM 8 bit integer array variable.
199 *
200 * Used for defining built-in integer array script variables.
201 */
202 struct VMInt8Array {
203 int8_t* data;
204 int size;
205
206 VMInt8Array() : data(NULL), size(0) {}
207 };
208
209 class VMFunctionProvider {
210 public:
211 virtual VMFunction* functionByName(const String& name) = 0;
212 virtual std::map<String,VMIntRelPtr*> builtInIntVariables() = 0;
213 virtual std::map<String,VMInt8Array*> builtInIntArrayVariables() = 0;
214 virtual std::map<String,int> builtInConstIntVariables() = 0;
215 };
216
217 /** @brief Execution state of a virtual machine.
218 *
219 * An instance of this abstract base class represents exactly one execution
220 * state of a virtual machine. This encompasses most notably the VM
221 * execution stack, and VM polyphonic variables. You might see it as one
222 * virtual thread of the virtual machine.
223 *
224 * @see VMParserContext
225 */
226 class VMExecContext {
227 public:
228 virtual ~VMExecContext() {}
229 virtual int suspensionTimeMicroseconds() const = 0;
230 };
231
232 class VMEventHandler {
233 public:
234 virtual String eventHandlerName() const = 0;
235 };
236
237 struct ParserIssue {
238 String txt;
239 int line;
240 ParserIssueType_t type;
241
242 inline void dump() {
243 switch (type) {
244 case PARSER_ERROR:
245 printf("[ERROR] line %d: %s\n", line, txt.c_str());
246 break;
247 case PARSER_WARNING:
248 printf("[Warning] line %d: %s\n", line, txt.c_str());
249 break;
250 }
251 }
252
253 inline bool isErr() const { return type == PARSER_ERROR; }
254 inline bool isWrn() const { return type == PARSER_WARNING; }
255 };
256
257 inline String typeStr(const ExprType_t& type) {
258 switch (type) {
259 case EMPTY_EXPR: return "empty";
260 case INT_EXPR: return "integer";
261 case INT_ARR_EXPR: return "integer array";
262 case STRING_EXPR: return "string";
263 case STRING_ARR_EXPR: return "string array";
264 }
265 return "invalid";
266 }
267
268 /** @brief Virtual machine representation of a script.
269 *
270 * An instance of this abstract base class represents a parsed script,
271 * translated into a virtual machine. You should first check if there were
272 * any parser errors. If there were any parser errors, you should refrain
273 * from executing the virtual machine. Otherwise if there were no parser
274 * errors (i.e. only warnings), then you might access one of the script's
275 * event handlers by i.e. calling eventHandlerByName() and pass the
276 * respective event handler to the ScriptVM class (or to one of its
277 * descendants) for execution.
278 *
279 * @see VMExecContext
280 */
281 class VMParserContext {
282 public:
283 virtual ~VMParserContext() {}
284 virtual std::vector<ParserIssue> issues() const = 0;
285 virtual std::vector<ParserIssue> errors() const = 0;
286 virtual std::vector<ParserIssue> warnings() const = 0;
287 virtual VMEventHandler* eventHandler(uint index) = 0;
288 virtual VMEventHandler* eventHandlerByName(const String& name) = 0;
289 };
290
291 } // namespace LinuxSampler
292
293 #endif // LS_INSTR_SCRIPT_PARSER_COMMON_H

  ViewVC Help
Powered by ViewVC