Jurassic passing wrong instance of .NET call back handler?

Jun 2, 2014 at 4:52 AM
Edited Jun 2, 2014 at 5:08 AM
First of all let me congratulate you guys for coming up with such a nice project. I am using Jurassic in one of my projects for the past 2 years and very happy about it.

Now the problem. I have an instance method (inside a class say MyClass) that I want to expose and call via JavaScript.
public delegate double DelegateSumIfNew(string gridName, string columnnameToSum, string criteria);
public double SumIfNew(string gridName, string columnnameToSum, string criteria)
{
    MessageBox.Show(string.Format("'{0}' == '{1}'", this.Name, gridName));
    return (this.Name == gridName) ? this.SumIf(columnnameToSum, criteria) : 0;
}
Here is how I init/get Jurassic engine.
        private static Jurassic.ScriptEngine GetJurassicEngine(Delegate[] handlers)
        {
            const string cachekey = "jurassic_engine_with_handlers";
            var engine = CacheHelper.Get<Jurassic.ScriptEngine>(cachekey);

            if (engine == null)
            {
                engine = new Jurassic.ScriptEngine();
                engine.ForceStrictMode = true;
                string xdatescript = GetXDateScript();
                engine.Execute(xdatescript);

                CacheHelper.Set(cachekey, engine);
            }

            if (handlers != null)
            {
                foreach (Delegate d in handlers)
                    engine.SetGlobalFunction(d.Method.Name, d);
            }

            return engine;
        }
Call from JavaScript is working fine when there is only one MyClass object. The moment I have 2 MyClass objects the problem starts to appear. I see that the method in the second instance is always called.

I have tried both 2.1 and 2.2 versions.

I have a feeling that Jurassic passes the second handler always or am I doing anything wrong?
Please help.
Jun 2, 2014 at 5:13 AM
I realized that the issue is here.... The global function set is overwritten as the name of function is same though they are from different instances. How to get that resolved?
foreach (Delegate d in handlers)
                    engine.SetGlobalFunction(d.Method.Name, d);
Coordinator
Jun 3, 2014 at 2:38 AM
I think you need to create a javascript array with the handlers.

Something like this (warning: untested!)
var functions = new List<object>();
foreach (Delegate d in handlers)
{
  engine.SetGlobalFunction("temp", d);
  functions.Add(engine.GetGlobalValue("temp"));
}
engine.SetGlobalValue("sumIfNewArray", ArrayConstructor.New(functions.ToArray()));
engine.Execute(@"function SumIfNew(gridName, columnnameToSum, criteria)
{
  for (var i = 0; i < sumIfNewArray.length; i ++)
    sumIfNewArray[i](gridName, columnnameToSum, criteria);
}");