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

Diff of /linuxsampler/trunk/src/scriptvm/ScriptVM.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2581 by schoenebeck, Fri May 30 12:48:05 2014 UTC revision 3551 by schoenebeck, Thu Aug 1 10:22:56 2019 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (c) 2014 Christian Schoenebeck   * Copyright (c) 2014-2019 Christian Schoenebeck
3   *   *
4   * http://www.linuxsampler.org   * http://www.linuxsampler.org
5   *   *
# Line 15  Line 15 
15    
16  #include "../common/global.h"  #include "../common/global.h"
17  #include "common.h"  #include "common.h"
 #include "CoreVMFunctions.h"  
18    
19  namespace LinuxSampler {  namespace LinuxSampler {
20    
21      class ParserContext;      class ParserContext;
22        class ExecContext;
23    
24        /** @brief Core virtual machine for real-time instrument scripts.
25         *
26         * This is the core of the virtual machine and main entry class, used for
27         * running real-time instrument scripts. This VM core encompasses the
28         * instrument script parser, generalized virtual machine and very generic
29         * built-in script functions. Thus this class only provides functionalities
30         * which are yet independent of the actual purpose the virtual machine is
31         * going to be used for.
32         *
33         * The actual use case specific functionalites (i.e. MIDI processing) is
34         * then implemented by sampler engines' VM classes which are derived from
35         * this generalized ScriptVM class.
36         *
37         * Typical usage of this class:
38         *
39         * - 1. Create an instance of this ScriptVM class (or of one of its deriving
40         *      classes).
41         * - 2. Load a script by passing its source code to method loadScript(),
42         *      which will return the parsed representation of the script.
43         * - 3. Create a VM execution context by calling createExecContext().
44         * - 4. Execute the script by calling method exec().
45         *
46         * This class is re-entrant safe, but not thread safe. So you can share one
47         * instance of this class between multiple (native) threads, but you @b must
48         * @b not execute methods of the same class instance simultaniously from
49         * different (native) threads. If you want to execute scripts simultaniously
50         * multi threaded, then create a separate ScriptVM instance for each
51         * (native) thread. Also note that one VMParserContext instance is tied to
52         * exactly one ScriptVM instance. So you @b must @b not create a
53         * VMParserContext with one ScriptVM instance and run it with a different
54         * ScriptVM instance!
55         */
56      class ScriptVM : public VMFunctionProvider {      class ScriptVM : public VMFunctionProvider {
57      public:      public:
58          ScriptVM();          ScriptVM();
59          virtual ~ScriptVM();          virtual ~ScriptVM();
60          void loadScript(const String& s);  
61          void loadScript(std::istream* is);          /**
62          std::vector<ParserIssue> issues() const;           * Loads a script given by its source code (passed as argument @a s to
63          std::vector<ParserIssue> errors() const;           * this method) and returns the parsed representation of that script.
64          std::vector<ParserIssue> warnings() const;           * After calling this method you must check the returned VMParserContext
65          void dumpParsedScript();           * object whether there had been any parser errors. If there were no
66          VMExecContext* createExecContext();           * parser errors, you may pass the VMParserContext object to method
67          VMEventHandler* eventHandler(uint index);           * exec() for actually executing the script.
68          VMEventHandler* eventHandlerByName(const String& name);           *
69          VMExecStatus_t exec(VMEventHandler* handler, VMExecContext* execContex);           * It is your responsibility to free the returned VMParserContext
70          VMExecContext* currentVMExecContext();           * object once you don't need it anymore.
71          VMFunction* functionByName(const String& name);           *
72             * @param s - entire source code of the script to be loaded
73             * @returns parsed representation of the script
74             */
75            VMParserContext* loadScript(const String& s);
76    
77            /**
78             * Same as above's loadScript() method, but this one reads the script's
79             * source code from an input stream object (i.e. stdin or a file).
80             *
81             * @param is - input stream from which the entire source code of the
82             *             script is to be read and loaded from
83             * @returns parsed representation of the script
84             */
85            VMParserContext* loadScript(std::istream* is);
86    
87            /**
88             * Parses a script's source code (passed as argument @a s to this
89             * method), splits that input up in its individual tokens (i.e.
90             * keyword, variable name, event name, etc.) and returns all those
91             * tokens, for the purpose that the caller can provide syntax syntax
92             * highlighting for the passed script.
93             *
94             * This method is actually not used by the sampler at all, it is rather
95             * provided for external script editor applications, to provide them a
96             * convenient backend for parsing scripts and providing syntax
97             * highlighting.
98             *
99             * @returns recognized tokens of passed script's source code
100             */
101            std::vector<VMSourceToken> syntaxHighlighting(const String& s);
102    
103            /**
104             * Same as above's syntaxHighlighting() method, but this one reads the
105             * script's source code from an input stream object (i.e. stdin or a
106             * file).
107             *
108             * @param is - input stream from which the entire source code of the
109             *             script is to be read and loaded from
110             * @returns recognized tokens of passed script's source code
111             */
112            std::vector<VMSourceToken> syntaxHighlighting(std::istream* is);
113    
114            /**
115             * Dumps the translated tree of the already parsed script, given by
116             * argument @a context, to stdout. This method is for debugging purposes
117             * only.
118             *
119             * @param context - parsed representation of the script
120             * @see loadScript()
121             */
122            void dumpParsedScript(VMParserContext* context);
123    
124            /**
125             * Creates a so called VM exceution context for a specific, already
126             * parsed script (provided by argument @a parserContext). Due to the
127             * general real-time design of this virtual machine, the VM execution
128             * context differs for every script. So you must (re)create the
129             * execution context for each script being loaded.
130             *
131             * @param parserContext - parsed representation of the script
132             * @see loadScript()
133             */
134            VMExecContext* createExecContext(VMParserContext* parserContext);
135    
136            /**
137             * Execute a script by virtual machine. Since scripts are event-driven,
138             * you actually execute only one specific event handler block (i.e. a
139             * "on note ... end on" code block) by calling this method (not the
140             * entire script), and hence you must provide one precise handler of the
141             * script to be executed by this method.
142             *
143             * This method usually blocks until the entire script event handler
144             * block has been executed completely. It may however also return before
145             * completion if either a) a script runtime error occurred or b) the
146             * script was suspended by the VM (either because script execution
147             * exceeded a certain limit of time or the script called the built-in
148             * wait() function). You must check the return value of this method to
149             * find out which case applies.
150             *
151             * @param parserContext - parsed representation of the script (see loadScript())
152             * @param execContext - VM execution context (see createExecContext())
153             * @param handler - precise event handler (i.e. "on note ... end on"
154             *                  code block) to be executed
155             *                  (see VMParserContext::eventHandlerByName())
156             * @returns current status of the vitual machine (i.e. script succeeded,
157             *          script runtime error occurred or script was suspended for
158             *          some reason).
159             */
160            VMExecStatus_t exec(VMParserContext* parserContext, VMExecContext* execContext, VMEventHandler* handler);
161    
162            /**
163             * Returns built-in script function for the given function @a name. To
164             * get the implementation of the built-in message() script function for
165             * example, you would pass "message" here).
166             *
167             * This method is re-implemented by deriving classes to add more use
168             * case specific built-in functions.
169             *
170             * @param name - name of the function to be retrieved (i.e. "wait" for the
171             *               built-in wait() function).
172             */
173            VMFunction* functionByName(const String& name) OVERRIDE;
174    
175            /**
176             * Whether the passed built-in function is disabled and should thus be
177             * ignored by the parser at the passed parser context (parser state
178             * where the built-in function call occurs).
179             *
180             * @param fn - built-in function to be checked
181             * @param ctx - parser context at the position where the built-in
182             *              function call is located within the script
183             */
184            bool isFunctionDisabled(VMFunction* fn, VMParserContext* ctx) OVERRIDE;
185    
186            /**
187             * Returns all built-in integer script variables. This method returns a
188             * STL map, where the map's key is the variable name and the map's value
189             * is the native pointer to the actual built-in variable.
190             *
191             * This method is re-implemented by deriving classes to add more use
192             * case specific built-in variables.
193             */
194            std::map<String,VMIntRelPtr*> builtInIntVariables() OVERRIDE;
195    
196            /**
197             * Returns all built-in (8 bit) integer array script variables. This
198             * method returns a STL map, where the map's key is the array variable
199             * name and the map's value is the native pointer to the actual built-in
200             * array variable.
201             *
202             * This method is re-implemented by deriving classes to add more use
203             * case specific built-in array variables.
204             */
205            std::map<String,VMInt8Array*> builtInIntArrayVariables() OVERRIDE;
206    
207            /**
208             * Returns all built-in constant integer script variables, which are
209             * constant and their final data is already available at parser time
210             * and won't change during runtime. Providing your built-in constants
211             * this way may lead to performance benefits compared to using other
212             * ways of providing built-in variables, because the script parser
213             * can perform optimizations when the script is refering to such
214             * constants.
215             *
216             * This type of built-in variable can only be read, but not be altered
217             * by scripts. This method returns a STL map, where the map's key is
218             * the variable name and the map's value is the final constant data.
219             *
220             * This method is re-implemented by deriving classes to add more use
221             * case specific built-in constant integers.
222             *
223             * @b Note: In case your built-in variable should be read-only but its
224             * value is not already available at parser time (i.e. because its
225             * value may change at runtime), then you should add it to
226             * builtInIntVariables() instead and use the macro
227             * DECLARE_VMINT_READONLY() to define the variable for read-only
228             * access by scripts.
229             */
230            std::map<String,int> builtInConstIntVariables() OVERRIDE;
231    
232            /**
233             * Returns all built-in dynamic variables. This method returns a STL
234             * map, where the map's key is the dynamic variable's name and the
235             * map's value is the pointer to the actual object implementing the
236             * behavior which is actually generating the content of the dynamic
237             * variable.
238             *
239             * This method is re-implemented by deriving classes to add more use
240             * case specific built-in dynamic variables.
241             */
242            std::map<String,VMDynVar*> builtInDynamicVariables() OVERRIDE;
243    
244            /**
245             * Enables or disables automatic suspension of scripts by the VM.
246             * If automatic suspension is enabled then scripts are monitored
247             * regarding their execution time and in case they are execution
248             * for too long, then they are automatically suspended by the VM for
249             * a certain amount of time in order to avoid any RT instablity
250             * issues caused by bugs in the script, i.e. endless while() loops
251             * or very large scripts.
252             *
253             * Automatic suspension is enabled by default due to the aimed
254             * real-time context of this virtual machine.
255             *
256             * @param b - true: enable auto suspension [default],
257             *            false: disable auto suspension
258             */
259            void setAutoSuspendEnabled(bool b = true);
260    
261            /**
262             * Returns true in case automatic suspension of scripts by the VM is
263             * enabled. See setAutoSuspendEnabled() for details.
264             *
265             * Automatic suspension is enabled by default due to the aimed
266             * real-time context of this virtual machine.
267             */
268            bool isAutoSuspendEnabled() const;
269    
270            /**
271             * By default (i.e. in production use) the built-in exit() function
272             * prohibits any arguments to be passed to its function by scripts. So
273             * by default, scripts trying to pass any arguments to the built-in
274             * exit() function will yield in a parser error.
275             *
276             * By calling this method the built-in exit() function will optionally
277             * accept one argument to be passed to its function call by scripts. The
278             * value of that function argument will become available by calling
279             * VMExecContext::exitResult() after execution of the script.
280             *
281             * @see VMExecContext::exitResult()
282             */
283            void setExitResultEnabled(bool b = true);
284    
285            /**
286             * Returns @c true if the built-in exit() function optionally accepts
287             * a function argument by scripts.
288             *
289             * @see setExitResultEnabled()
290             */
291            bool isExitResultEnabled() const;
292    
293            VMEventHandler* currentVMEventHandler(); //TODO: should be protected (only usable during exec() calls, intended only for VMFunctions)
294            VMParserContext* currentVMParserContext(); //TODO: should be protected (only usable during exec() calls, intended only for VMFunctions)
295            VMExecContext* currentVMExecContext(); //TODO: should be protected (only usable during exec() calls, intended only for VMFunctions)
296    
297      protected:      protected:
298          ParserContext* m_context;          VMEventHandler* m_eventHandler;
299          CoreVMFunction_message fnMessage;          ParserContext* m_parserContext;
300          CoreVMFunction_exit fnExit;          bool m_autoSuspend;
301          CoreVMFunction_wait fnWait;          bool m_acceptExitRes;
302            class CoreVMFunction_message* m_fnMessage;
303            class CoreVMFunction_exit* m_fnExit;
304            class CoreVMFunction_wait* m_fnWait;
305            class CoreVMFunction_abs* m_fnAbs;
306            class CoreVMFunction_random* m_fnRandom;
307            class CoreVMFunction_num_elements* m_fnNumElements;
308            class CoreVMFunction_inc* m_fnInc;
309            class CoreVMFunction_dec* m_fnDec;
310            class CoreVMFunction_in_range* m_fnInRange;
311            class CoreVMFunction_sh_left* m_fnShLeft;
312            class CoreVMFunction_sh_right* m_fnShRight;
313            class CoreVMFunction_min* m_fnMin;
314            class CoreVMFunction_max* m_fnMax;
315            class CoreVMFunction_array_equal* m_fnArrayEqual;
316            class CoreVMFunction_search* m_fnSearch;
317            class CoreVMFunction_sort* m_fnSort;
318            class CoreVMDynVar_NKSP_REAL_TIMER* m_varRealTimer;
319            class CoreVMDynVar_NKSP_PERF_TIMER* m_varPerfTimer;
320      };      };
321    
322  } // namespace LinuxSampler  } // namespace LinuxSampler

Legend:
Removed from v.2581  
changed lines
  Added in v.3551

  ViewVC Help
Powered by ViewVC