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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2594 - (hide annotations) (download) (as text)
Thu Jun 5 00:16:25 2014 UTC (9 years, 9 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 schoenebeck 2581 /*
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 schoenebeck 2588 #include <vector>
19 schoenebeck 2594 #include <map>
20     #include <stddef.h> // offsetof()
21 schoenebeck 2581
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 schoenebeck 2594 /**
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 schoenebeck 2581 class VMFunctionProvider {
210     public:
211     virtual VMFunction* functionByName(const String& name) = 0;
212 schoenebeck 2594 virtual std::map<String,VMIntRelPtr*> builtInIntVariables() = 0;
213     virtual std::map<String,VMInt8Array*> builtInIntArrayVariables() = 0;
214     virtual std::map<String,int> builtInConstIntVariables() = 0;
215 schoenebeck 2581 };
216    
217 schoenebeck 2594 /** @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 schoenebeck 2581 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 schoenebeck 2594 /** @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 schoenebeck 2588 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 schoenebeck 2581 } // namespace LinuxSampler
292    
293     #endif // LS_INSTR_SCRIPT_PARSER_COMMON_H

  ViewVC Help
Powered by ViewVC