-
Notifications
You must be signed in to change notification settings - Fork 35
ScriptRunningMachine
ScriptRunningMachine (also called SRM) is the main class of ReoScript to run scripts.
Create ScriptRunningMachine using default constructor:
ScriptRunningMachine srm = new ScriptRunningMachine();
ScriptRunningMachine will be created with default Standard Features. If you want to specify what kind of features should be supported you may use the following constructor:
ScriptRunningMachine srm = new ScriptRunningMachine(CoreFeatures.FullFeatures);
Learn more CoreFeatures.
ScriptRunningMachine provides two types of method to run script:
- void Load(string filepath)
- void Load(Uri uri)
- void Load(Stream stream)
- object Run(string script)
- object Run(FileInfo fileInfo)
Load
method used to load script library (file or resource), it runs script without return value. Run
method usually used to run a piece of script, can be used to call a function and get the return value.
srm.Run("alert('hello world!');");
srm.Load("C:\\folder\\Script.rs");
using (MemoryStream ms = new MemoryStream(Resources.script))
{
srm.Load(ms);
}
It's able to use srm.CalcExpression
to calculate an expression and retrieve its result. (See Language Specification about Expression)
object result = srm.CalcExpression("2 * (3 + 4)");
The result is:
14
To run a script repeatedly, compiling the script and running the compiled script will get higher execution performance. For example:
CompiledScript code = srm.Compile(script);
for (int i = 0; i < 10; i++) {
srm.RunCompiledScript(code);
}
You can also use srm.Compile
method to check whether there is syntax errors before run a script. See Error Handling.
Another function of ScriptRunningMachine is to manage the memory shared between script and .NET runtime.
There is a pre-defined global object in script context, it holds all global variable as properties. For example:
a = 10; // assume 'a' does not exist
If we use the following code to check the value of a
in JavaScript:
console.log(window.a);
Then 10
will be printed out in console:
10
In fact, a
is defined as a property to the global object window
. In ReoScript, the global object called script
:
debug.assert( a === script.a );
When the code of script runs in most outside scope (not called in any function), everything will be stored as property to global object, including functions:
function start() {
console.log('start!');
}
It is same as:
script.start = function() {
console.log('start!');
};
Call this global function:
start();
Or call it using following syntax:
script.start();
GlobalObject can be accessed from .NET program using these methods:
- srm.SetGlobalVariable(string key, object value)
- srm.GetGlobalVariable(string key)
- srm.RemoveGlobalVariable(string key)
- srm[string key] = object;
To access the global object in .NET program:
srm["k"] = 10;
It is same as this in script:
script.k = 10;
To access the variable in script:
console.log(k);
or via global object:
console.log(script.k);
The result is:
10
To make a .NET function can be used in script, use NativeFunctionObject class. Define the function and put it into the global object of script.
srm["exec"] = new NativeFunctionObject("exec", (ctx, owner, args) =>
{
if (args.Length <= 0) return null;
string exeName = Convert.ToString(args[0]);
System.Diagnostics.Process.Start(exeName);
return null;
});
Then call the function in script:
exec('notepad.exe');
The Windows Notepad should be started up.
Assume a function defined in script:
function hello(arg) {
alert('hello ' + arg + '!');
}
It is able to call it from .NET program using srm.InvokeFunctionIfExisted
method:
srm.InvokeFunctionIfExisted(string functionName, params object[] args);
e.g.:
srm.InvokeFunctionIfExisted("hello", "world");
A message box will display:
hello world!
When you have an instance that has been added to script's global object, pass the object as first parameter, then it is possible to access the object's property like:
srm.InvokeFunctionIfExisted(object, "hello", "world");
But for a simpler syntax, always it is possible to access variables by run script:
srm.Run("object.hello()");
Since the data type are different between script and .NET runtime, when getting return value from script, It is may necessary to convert the data type.
object result = srm.Run(string script);
object result = srm.CalcExpression(string expression);
srm["func"] = new NativeFunctionObject("func", (ctx, owner, args) => {
object arg1 = args[0];
});
ScriptRunningMachine provides the following static
methods to help and simplify the data type conversation from script's return.
string ConvertToString(object obj);
bool GetBoolValue(object obj);
double GetDoubleValue(object obj);
float GetFloatValue(object obj);
int GetIntValue(object obj);
long GetLongValue(object obj);
The following methods can be used to get argument's value in extended function:
int GetIntParam(object[] args, int index, int def)
long GetLongParam(object[] args, int index, long def)
float GetIntParam(object[] args, int index, float def)
IsRunning
is a property of ScriptRunningMachine
to indicate whether the script currently on running. For example:
function check_run() {
if (!request_quit) {
setTimeout(check_run, 1000);
}
}
This script will keep check request_quit
flag every one second. If request_quit
is false, setTimeout
will be invoked and an asynchronous-calling will be performed. This script will keeps running after check_run
be invoked until request_quit
set to true, so we need to know whether the script executing is finished or not.
bool running = srm.IsRunning;
If running
is true
, it means script currently is still running.
If you want to kill the script running, use ForceStop
method:
if (srm.IsRunning)
{
srm.ForceStop();
}
There are some built-in functions provided for script:
function __stdin__() {} // read a byte from Standard Input
function __stdout__(obj) {} // write an object to Standard Output
function __stdinln__() {} // read a string line from Standard Input
function __stdoutln__(line) {} // write a string line to Standard Output
The console
object actually wraps these functions:
console.read = function() { return __stdin__(); };
console.readline = function() { return __stdinln__(); };
console.write = function(t) { __stdout__(t); };
console.log = function(t) { __stdoutln__(t); };
There are some interfaces to be used for Standard I/O Interface in .NET:
interface IStandardInputProvider;
interface IStandardOutputListener;
When data redirected by built-in standard I/O functions, the implementation of above interface will be invoked.
Only one IStandardInputProvider
can be set to SRM using the following method:
srm.StandardInputProvider = new MyInputProvider();
One or more IStandardOutputListener
could be added into ScriptRunningMachine
:
srm.AddStandardOutputListener(new MyOutputListener());
WorkMode is a property of ScriptRunningMachine
to decide the mode of ScriptRunningMachine. Like enable or disable DirectAccess feature. (See WorkMode)
WorkPath
is a property of ScriptRunningMachine
to decide the path during loading scripts. By default, WorkPath
points to .NET application startup path.
CoreFeatures is a property of ScriptRunningMachine
to decide what features can be used in script execution. (See CoreFeatures)