This project has moved. For the latest updates, please go here.

Returning Javascript arrays from HostObjects

Feb 18, 2015 at 8:20 PM
Hi, I am new to the project and I wanted to change over to ClearScript for my SignalR example BoardGame from a different V8 engine host.

In my existing sample, there was an "immediate window" that allowed people to type arbitrary script and have it executed against the currently running script engine. That script was:

var tokens = map.GetTokenList();
for (var i=0; i<tokens.length; i++)
{
tokens[i].X=50i; tokens[i].Y=50i;
}

map refers to a hosted object. GetTokenList is a public method on that instance that returns (currently) a Token[]. So a .NET array was returned. I guess the previous engine was converting that to a JavaScript array, because as you can see the length of the array is accessed via "length", the JavaScript array method for counting the contents.

I struggled getting the exact same code to work when I replaced the engine with ClearScript. But then I figured out that, in this context, tokens was really a .NET array and hadn't been converted, so simply changing the lowercase l to an uppercase L worked, as in:

var tokens = map.GetTokenList();
for (var i=0; i<tokens.Length; i++)
{
tokens[i].X=50i; tokens[i].Y=50i;
}

Not that I am saying this code or sample is ideal, but I was curious if there is a way in the engine to instantiate V8 types (JavaScript types). In other words, could my .NET code instantiate a JavaScript array and return it from a .NET method call. I'm guessing the other engine just does that somehow.

I looked at the FAQ and saw a section on creating arrays from script using the HostFunctions object, but I don't think that is quite what I am going for. I want to be able to return a native JavaScipt array from the host.

It's also possible there is some disconnect between the project and the NuGet package. I used the following to import ClearScript anf get going: Install-Package ClearScript.V8

And it installed and reported: "Successfully added 'ClearScript.V8 5.3.10.0' to GameServer."

Thanks for any insight,
Chris
Coordinator
Feb 19, 2015 at 3:30 AM
Hi Chris,

First, consider upgrading to the latest version of ClearScript (currently 5.4.1). We recommend that you build it from the source code as outlined in the ReadMe.

Second, you've determined correctly that ClearScript prefers to make host objects scriptable rather than convert them to script objects. However, it also aims to make it easy to manipulate script objects from the host. Here's a sample that defines an extension method for converting host arrays to script arrays:
public static class ScriptHelpers {
    public static object ToScriptArray<T>(this T[] array) {
        dynamic scriptArray = ScriptEngine.Current.Evaluate("[]");
        foreach (var element in array) {
            scriptArray.push(element);
        }
        return scriptArray;
    }
}
Note that ScriptEngine.Current is new in ClearScript 5.4.1. With an older version you'd have to pass the engine instance into the conversion method (or use some other technique).

Good luck!
Feb 19, 2015 at 8:25 PM
Thank you for this detailed answer. I'll see if I can get the current version building.