Skip to content

ScriptRunningMachine

Jing Lu edited this page May 28, 2013 · 51 revisions

ScriptRunningMachine (sometimes called SRM) is the main class of ReoScript to run script.

Create ScriptRunningMachine

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);

See CoreFeatures for more details.

Using ScriptRunningMachine to Run Script

ScriptRunningMachine provides two types of method to run script:

Load

  • void Load(string filepath)
  • void Load(Uri uri)
  • void Load(Stream stream)

Run

  • object Run(string script)
  • object Run(FileInfo fileInfo)

Load method used to load script library (file or resource), it runs script without retrieving return value. Run method usually used to run a piece of code of script, call a function and get the return value.

Run script from string

srm.Run("alert('hello world!');");

Run script from file

srm.Load("C:\\folder\\Script.rs");

Run script from Internal Resource

using (MemoryStream ms = new MemoryStream(Resources.script))
{
    srm.Load(ms);
}

Calculate Expression

You may 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

Run script repeatedly

If you could expect your script will be executed for many times, per-execute your code will improve the executing speed. For example:

CompiledScript code = srm.Compile(script);
...
for (int i = 0; i < 10; i++) {
    srm.RunCompiledScript(code); 
}

Data exchange with .Net program

Understand GlobalObject

There is an invisible object always existed in script context. For example:

a = 10;    // assume 'a' does not exist

If we use the following code to view 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 which belongs 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 outer scope (not called in function), everything will be stored as property to global object even the function define:

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();

Modify GlobalObject in .Net program

GlobalObject can be accessed or modified directly from .Net program using these methods:

  • srm.SetGlobalVariable(string key, object object)
  • srm.GetGlobalVariable(string key)
  • srm.RemoveGlobalVariable(string key)
  • srm[string key] = object;

Add variable into GlobalObject

To modify the global object in .Net program:

srm["k"] = 10;

Then use this variable in script:

console.log(k);

The result is:

10

Add function into GlobalObject

To define a function which created in .Net but be used in script, you may use NativeFunctionObject class.

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 this function in script:

exec('notepad.exe');

The Windows Notepad should be started up.

Call script's function from .Net program

If there is function defined in script:

function hello(arg) {
  alert('hello ' + arg + '!');
}

It is able to call from .Net program by calling srm.InvokeFunctionIfExisted method:

srm.InvokeFunctionIfExisted(string functionName, params object[] args);

e.g.:

srm.InvokeFunctionIfExisted("hello", "world");

The message box with the text below will be displayed:

hello world!

And it is possible to call function that belongs to an object by passing the object as below:

srm.InvokeFunctionIfExisted(object, "hello", "world");

Retrieve data from script returning

In the following cases if you getting a return value from script, or deal with an argument that passed from extended function, you may need to convert the data type into .Net 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 that may used to convert the data type:

string ConvertToString(object obj);
bool GetBoolValue(object obj);
double GetDoubleValue(object obj);    
float GetFloatValue(object obj);
int GetIntValue(object obj);
long GetLongValue(object obj);

And the following methods could be used to get a value from arguments of extended function:

int GetIntParam(object[] args, int index, int def)
long GetLongParam(object[] args, int index, long def)

Check ScriptRunningMachine status

IsRunning

IsRunning is a property of ScriptRunningMachine to indicate whether the script currently keeps running on. 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 be 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 is running now.

ForceStop

If script is running and you want to kill it, you may use ForceStop method:

if (srm.IsRunning)
{
    srm.ForceStop();
}

See Enhanced Async-Calling.

Standard I/O Interface

Standard I/O Interface for script

There are 4 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 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); };

Standard I/O Interface for .Net

There are two interfaces 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 SRM using the following method:

srm.AddStandardOutputListener(new MyOutputListener());

Setting ScriptRunningMachine

WorkMode

WorkMode is a property of ScriptRunningMachine to decide how the mode does ScriptRunningMachine works on. Like enable or disable DirectAccess feature. (See WorkMode)

WorkPath

WorkPath is a property of ScriptRunningMachine to indicate if there is another script file will be imported into current script context, where to find the script file. WorkPath is default path where ScriptRunningMachine started up and works in.

CoreFeatures

CoreFeatures is a property of ScriptRunningMachine to decide what features can be supported for script executing. (See CoreFeatures)

Clone this wiki locally