public virtual object didReceiveScriptMessageSync(NKScriptMessage message)
        {
            // A workaround for when postMessage(undefined)
            if (message.body == null)
            {
                return(false);
            }

            // thread static
            NKScriptValue._currentContext = this.context;
            object result;

            var body = message.body as Dictionary <string, object>;

            if (body != null && body.ContainsKey("$opcode"))
            {
                string opcode = body["$opcode"] as String;
                int    target = Int32.Parse(body["$target"].ToString());
                if (_instances.ContainsKey(target))
                {
                    var obj = _instances[target];
                    if (opcode == "-")
                    {
                        if (target == 0)
                        {
                            // Dispose plugin
                            this.unbind();
                            result = true;
                        }
                        else if (_instances.ContainsKey(target))
                        {
                            obj.setNKScriptValue(null);
                            result = true;
                        }
                        else
                        {
                            NKLogging.log(String.Format("!Invalid instance id: {0}", target));
                            result = false;
                        }
                    }
                    else if (typeInfo.ContainsProperty(opcode))
                    {
                        // Update property
                        obj.updateNativeProperty(opcode, body["$operand"] as object);
                        result = true;
                    }
                    else if (typeInfo.ContainsMethod(opcode))
                    {
                        // Invoke method
                        result = obj.invokeNativeMethodSync(opcode, body["$operand"] as object[]);
                    }
                    else
                    {
                        NKLogging.log(String.Format("!Invalid member name: {0}", opcode));
                        result = false;
                    }
                }
                else if (opcode == "+")
                {
                    // Create instance
                    var args       = body["$operand"] as object[];
                    var nsInstance = String.Format("{0}[{1}]", this.ns, target);
                    _instances[target] = new NKScriptValueNative(nsInstance, this, target, args, true);
                    result             = true;
                }
                else
                {
                    // else Unknown opcode
                    var obj = _principal.plugin as NKScriptMessageHandler;
                    if (obj != null)
                    {
                        result = obj.didReceiveScriptMessageSync(message);
                    }
                    else
                    {
                        // discard unknown message
                        NKLogging.log(String.Format("!Unknown message: {0}", message.body.ToString()));
                        result = false;
                    }
                }
            }
            else
            {
                // null body
                result = false;
            }

            //thread static
            NKScriptValue._currentContext = null;
            return(result);
        }
 // HOST-MAIN PROCESS
 public static NKScriptMessageHandler createClient(string ns, string id, int nativeSeqMax, NKScriptMessage message, NKScriptContext context, CancellationToken cancelToken)
 {
     var proxy = new NKRemotingProxy(ns, id, nativeSeqMax, message, context, cancelToken);
     var _ = ((NKScriptMessageHandler)proxy).didReceiveScriptMessageSync(message);
     return proxy;
 }
        public object didReceiveScriptMessageSync(NKScriptMessage message)
        {
            // A workaround for when postMessage(undefined)
            if (message.body == null) return false;

            // thread static
            NKScriptChannel._currentContext = this.context;
            object result;

            var body = message.body as Dictionary<string, object>;
            if (body != null && body.ContainsKey("$opcode"))
            {
                string opcode = body["$opcode"] as String;
                int target = Convert.ToInt32(body["$target"] as String);
                if (instances.ContainsKey(target))
                {
                    var obj = instances[target];
                    if (opcode == "-")
                    {
                        if (target == 0)
                        {
                            // Dispose plugin
                            this.unbind();
                            result = true;
                        }
                        else if (instances.ContainsKey(target))
                        {
                            obj.setNKScriptValue(null);
                            result = true;
                        }
                        else
                        {
                            NKLogging.log(String.Format("!Invalid instance id: {0}", target));
                            result = false;
                        }
                    }
                    else if (typeInfo.ContainsProperty(opcode))
                    {
                        // Update property
                        obj.updateNativeProperty(opcode, body["$operand"] as object);
                        result = true;
                    }
                    else if (typeInfo.ContainsMethod(opcode))
                    {
                        // Invoke method
                        result = obj.invokeNativeMethodSync(opcode, body["$operand"] as object[]);
                    }
                    else {
                        NKLogging.log(String.Format("!Invalid member name: {0}", opcode));
                        result = false;
                    }
                }
                else if (opcode == "+")
                {
                    // Create instance
                    var args = body["$operand"] as Array;
                    var ns = String.Format("{0}[{1}]", principal.ns, target);
                    instances[target] = new NKScriptValueNative(ns, this, args);
                    result = true;
                }
                else
                {
                    // else Unknown opcode
                    var obj = principal.plugin as NKScriptMessageHandler;
                    if (obj != null)
                    {
                        result = obj.didReceiveScriptMessageSync(message);
                    }
                    else
                    {
                        // discard unknown message
                        NKLogging.log(String.Format("!Unknown message: {0}", message.body.ToString()));
                        result = false;
                    }
                }
            }
            else
            {
                // null body
                result = false;
            }

            //thread static
            NKScriptChannel._currentContext = null;
            return result;
        }
 // MAIN PROCESS NKScriptMessageHandler 
 void NKScriptMessageHandler.didReceiveScriptMessage(NKScriptMessage message)
 {
     var msg = new NKRemotingMessage();
     msg.command = NKRemotingMessage.Command.NKScriptMessage;
     msg.args = new[] { message.name, context.NKserialize(message.body) };
     writeObject(syncPipeOut, msg);
 }
        object NKScriptMessageHandler.didReceiveScriptMessageSync(NKScriptMessage message)
        {
            var loger = context.NKserialize(message.body);
            var task = Task.Factory.StartNew(() =>
            {
                var msg = new NKRemotingMessage();
                msg.command = NKRemotingMessage.Command.NKScriptMessageSync;
                msg.args = new[] { message.name, context.NKserialize(message.body) };
                writeObject(syncPipeOut, msg);
                return readObject(syncPipeIn);
            }
          , cancelToken, TaskCreationOptions.None, TaskScheduler.Default);

            if (!task.Wait(10000, cancelToken) && !cancelToken.IsCancellationRequested)
            {
                NKLogging.log("!Renderer is not responsive " + loger );
                if (!process.HasExited)
                    process.Kill();
                return null;
            }

            NKRemotingMessage nkr = task.Result;
            if (nkr == null)
                return null;

            object result = null;
            if (nkr.args.Length>0)
               result = context.NKdeserialize(nkr.args[0]);
     
            return result;
        }
        //MAIN
        private NKRemotingProxy(string ns, string id, int nativeSeqMax, NKScriptMessage message, NKScriptContext context, CancellationToken cancelToken)
        {
            this.context = context;
            this._localHandlers = null;
            this.ns = ns;

            this.cancelToken = cancelToken;
            
            var exe = System.Reflection.Assembly.GetEntryAssembly().Location;
            var path = System.IO.Path.GetDirectoryName(exe);
            ProcessStartInfo startInfo = Process.GetCurrentProcess().StartInfo;
            startInfo.FileName = exe;
            startInfo.WorkingDirectory = path;
            startInfo.UseShellExecute = false;
         
            var syncPipeOut = new AnonymousPipeServerStream(PipeDirection.Out, HandleInheritability.Inheritable);
            var syncPipeIn = new AnonymousPipeServerStream(PipeDirection.In, HandleInheritability.Inheritable);
            var pipeOutHandle = syncPipeOut.GetClientHandleAsString();
            var pipeInHandle = syncPipeIn.GetClientHandleAsString();

            this.syncPipeOut = syncPipeOut;
            this.syncPipeIn = syncPipeIn;
            
            startInfo.Arguments = "NKR=" + buildInitMessage(pipeOutHandle, pipeInHandle);

            this.id = id;
            process = Process.Start(startInfo);
            NKEventEmitter.global.emit<string>("NKS.ProcessAdded", id, false);
            process.EnableRaisingEvents = true;
            process.Exited += Process_Exited;
       
            var pipeName = Convert.ToBase64String(getUniqueKey());
            var asyncPipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.Asynchronous | PipeOptions.WriteThrough);
            this.asyncPipe = asyncPipe;
            NKScriptChannel.nativeFirstSequence -= 5;

            string nativeFirstSeq = NKScriptChannel.nativeFirstSequence.ToString();
   
            var handshake = new NKRemotingMessage();
            handshake.command = NKRemotingMessage.Command.NKRemotingHandshake;
            handshake.args = new string[] { pipeName, ns, id, nativeSeqMax.ToString() };

            syncPipeOut.WriteByte(100);
            syncPipeOut.Flush();
            syncPipeOut.WaitForPipeDrain();
            syncPipeOut.DisposeLocalCopyOfClientHandle();
            syncPipeIn.DisposeLocalCopyOfClientHandle();

            writeObject(syncPipeOut, handshake);
            syncPipeOut.WaitForPipeDrain();

            var handshakeReply = readObject(syncPipeIn);
            if (handshakeReply == null || handshakeReply.command != NKRemotingMessage.Command.NKRemotingHandshake)
                Environment.Exit(911);

            asyncPipe.WaitForConnection();
            cancelToken.Register(requestClientTeardown);
            var nkready = readObject(asyncPipe);
            if (nkready == null || nkready.command != NKRemotingMessage.Command.NKRemotingReady)
               Environment.Exit(910);
     
            Task.Factory.StartNew((s)=> _processServerMessages(asyncPipe), null, cancelToken, TaskCreationOptions.LongRunning, TaskScheduler.Default);
            NKEventEmitter.global.forward<NKEvent>(eventForwarderFromMain);

        }
        // RENDERER PROCESS PIPE EVENT LOOP
        private async Task _processClientMessages()
        {
             var message = await readObjectAsync(syncPipeIn);
            if (message == null)
            {
                NKLogging.log("!Renderer Received Empty Message");
                cancelTokenSource.Cancel();
                return;
            }

            if (message.command == NKRemotingMessage.Command.NKScriptMessageSync)
            {
          
                var name = message.args[0];
                Dictionary<string, object> body = null;
                try
                {
                    body = context.NKdeserialize(message.args[1]) as Dictionary<string, object>;
                }
                catch (Exception ex)
                {
                    NKLogging.log("!Renderer Message Deserialization Error: " + ex.Message);
                }
                var nks = new NKScriptMessage(name, body);

                NKScriptMessageHandler handler = null;
                if (_localHandlers.ContainsKey(name))
                    handler = _localHandlers[name];
                else
                {
                    int target = Int32.Parse(body["$target"].ToString());
                    handler = NKScriptChannel.getNative(target);
                }
                if (handler != null)
                {
                    var nkr = new NKRemotingMessage();
                    nkr.command = NKRemotingMessage.Command.NKScriptMessageSyncReply;

                    try
                    {
                        var result = handler.didReceiveScriptMessageSync(nks);
                        nkr.args = new string[] { context.NKserialize(result) };
                    } catch (Exception ex)
                    {
                        NKLogging.log("!Renderer Message Processing Error: " + ex.Message);
                        NKLogging.log(ex.StackTrace);
                        nkr.args = new string[] { };
                    }
                    writeObject(syncPipeOut, nkr);
                }
                else
                {
                    NKLogging.log("+Renderer Received Unknown Script Message Sync");             
                }
            }
            else if (message.command == NKRemotingMessage.Command.NKScriptMessage)
            {

                var name = message.args[0];
                Dictionary<string, object> body = null;
                try
                {
                    body = context.NKdeserialize(message.args[1]) as Dictionary<string, object>;
                }
                catch (Exception ex)
                {
                    NKLogging.log("!Renderer Message Deserialization Error: " + ex.Message);

                }
                var nks = new NKScriptMessage(name, body);

                NKScriptMessageHandler handler = null;
                if (_localHandlers.ContainsKey(name))
                    handler = _localHandlers[name];
                else
                {
                    int target = Int32.Parse(body["$target"].ToString());
                    handler = NKScriptChannel.getNative(target);
                }
                if (handler != null)
                {
                      handler.didReceiveScriptMessage(nks);
              } else
                {
                    NKLogging.log("+Renderer Received Unknown Script Message " + message.args[1]);

                }
            }
            else if (message.command == NKRemotingMessage.Command.NKRemotingClose)
            {
                try
                {
                    syncPipeIn.Close();
                    syncPipeOut.Close();
                    asyncPipe.Close();

                }
                catch { }

                Environment.Exit(0);
            }
            else if (message.command == NKRemotingMessage.Command.NKEvent)
            {
                var eventType = message.args[0];
                NKEvent eventObject = new NKEvent((IDictionary<string, object>)(NKData.jsonDeserialize(message.args[1])));
                NKEventEmitter.global.emit<NKEvent>(eventType, eventObject, false);
            }

            if (!cancelToken.IsCancellationRequested)
                await _processClientMessages();
            else
                return;
        }
        public override void didReceiveScriptMessage(NKScriptMessage message)
        {
            // A workaround for when postMessage(undefined)
            if (message.body == null) return;

            var body = message.body as Dictionary<string, object>;
            if (body != null && body.ContainsKey("$opcode"))
            {
                string opcode = body["$opcode"] as String;
                int target = Int32.Parse(body["$target"].ToString());
                NKScriptMessageHandler proxy = null;
                if (_proxies.ContainsKey(target))
                {
                    proxy = _proxies[target];
                }
                else if (target > 1500)
                {
                    var targetFloor = target - (target % NKRANGEPERPROCESS);
                    if (_proxiesNatives.ContainsKey(targetFloor))
                        proxy = _proxiesNatives[targetFloor];
                }

                if (proxy != null)
                {
                    if (opcode == "-")
                    {
                        if (target == 0)
                        {
                            // TRANSFER TO REMOTE, WITH SYNC
                            var _ = proxy.didReceiveScriptMessageSync(message);
                            this.unbind();
                        }
                        else 
                        {
                            // TRANSFER TO REMOTE, WITH SYNC
                            var _ = proxy.didReceiveScriptMessageSync(message);

                            // UNBIND PROXY
                            _cancelTokens[target].Cancel();
                        }
                    }
                    else if (typeInfo.ContainsProperty(opcode))
                    {
                        // ALSO TRANSFER TO REMOTE
                       proxy.didReceiveScriptMessage(message);
                    }
                    else if (typeInfo.ContainsMethod(opcode))
                    {
                        // Invoke method

                        // TRANSFER TO REMOTE ONLY
                        proxy.didReceiveScriptMessage(message);
                    }
                    else {
                        NKLogging.log(String.Format("!Invalid member name: {0}", opcode));
                    }
                }
                else if (opcode == "+")
                {
                    throw new NotImplementedException("+ opcode must be called using synchronous messages");
                }
                else
                {
                    // else Unknown opcode
                    var obj = _principal.plugin as NKScriptMessageHandler;
                    if (obj != null)
                    {
                        obj.didReceiveScriptMessage(message);
                    }
                    else
                    {
                        // discard unknown message
                        NKLogging.log(String.Format("!Unknown message: {0}", message.body.ToString()));
                    }
                }
            }
            else
            {
                // null body, ignore
            }

        }
        public override object didReceiveScriptMessageSync(NKScriptMessage message)
        {
            // A workaround for when postMessage(undefined)
            if (message.body == null) return false;

            // thread static
            NKScriptValue._currentContext = this.context;
            object result;

            var body = message.body as Dictionary<string, object>;
            if (body != null && body.ContainsKey("$opcode"))
            {
                string opcode = body["$opcode"] as String;
                int target = Int32.Parse(body["$target"].ToString());
                NKScriptMessageHandler proxy = null;
                if (_proxies.ContainsKey(target))
                {
                    proxy = _proxies[target];
                } else if (target > 1500)
                {
                    var targetFloor = target - (target % 10);
                    if (_proxiesNatives.ContainsKey(targetFloor))
                        proxy = _proxiesNatives[targetFloor];
                }

                if (proxy != null)
                {
                    if (opcode == "-")
                    {
                        if (target == 0)
                        {
                            // TRANSFER TO REMOTE
                            var _ = proxy.didReceiveScriptMessageSync(message);

                            this.unbind();
                            result = true;
                        }
                        else
                        {
                            // TRANSFER TO REMOTE
                            var _ = proxy.didReceiveScriptMessageSync(message);

                            // UNBIND PROXY
                            _cancelTokens[target].Cancel();

                            result = true;
                        }
                          }
                    else if (typeInfo.ContainsProperty(opcode))
                    {
                        // TRANSFER TO REMOTE
                        proxy.didReceiveScriptMessageSync(message);
                       result = true;
                    }
                    else if (typeInfo.ContainsMethod(opcode))
                    {
                        // Invoke method via REMOTE proxy
                         result = proxy.didReceiveScriptMessageSync(message);
                    }
                    else {
                        NKLogging.log(String.Format("!Invalid member name: {0}", opcode));
                        result = false;
                    }
                }
                else if (opcode == "+")
                {
                   _instances[target] = null;

                    int maxNativeFirst = NKScriptChannel.nativeFirstSequence - (NKScriptChannel.nativeFirstSequence % NKRANGEPERPROCESS) - 1;
                    int minNativeFirst = (maxNativeFirst - NKRANGEPERPROCESS) + 1;
                    NKScriptChannel.nativeFirstSequence = minNativeFirst - 1;
              
                    var cancelTokenSource = new CancellationTokenSource();
                    _cancelTokens[target] = cancelTokenSource;
                     proxy = NKRemoting.NKRemotingProxy.createClient(ns, id, maxNativeFirst, message, context, cancelTokenSource.Token);
                    _proxies[target] = proxy;
                    _proxiesNatives[minNativeFirst] = proxy;

                    result = true;
                }
                else
                {
                    // else Unknown opcode
                    var obj = _principal.plugin as NKScriptMessageHandler;
                    if (obj != null)
                    {
                        result = obj.didReceiveScriptMessageSync(message);
                    }
                    else
                    {
                        // discard unknown message
                        NKLogging.log(String.Format("!Unknown message: {0}", message.body.ToString()));
                        result = false;
                    }
                }
            }
            else
            {
                // null body
                result = false;
            }

            //thread static
            NKScriptValue._currentContext = null;
            return result;
        }
示例#10
0
        public void didReceiveScriptMessage(NKScriptMessage message)
        {
            // A workaround for when postMessage(undefined)
            if (message.body == null)
            {
                return;
            }

            // thread static
            NKScriptChannel._currentContext = this.context;

            var body = message.body as Dictionary <string, object>;

            if (body != null && body.ContainsKey("$opcode"))
            {
                string opcode = body["$opcode"] as String;
                int    target = Convert.ToInt32(body["$target"] as String);
                if (instances.ContainsKey(target))
                {
                    var obj = instances[target];
                    if (opcode == "-")
                    {
                        if (target == 0)
                        {
                            // Dispose plugin
                            this.unbind();
                        }
                        else if (instances.ContainsKey(target))
                        {
                            obj.setNKScriptValue(null);
                        }
                        else
                        {
                            NKLogging.log(String.Format("!Invalid instance id: {0}", target));
                        }
                    }
                    else if (typeInfo.ContainsProperty(opcode))
                    {
                        // Update property
                        obj.updateNativeProperty(opcode, body["$operand"] as object);
                    }
                    else if (typeInfo.ContainsMethod(opcode))
                    {
                        // Invoke method
                        obj.invokeNativeMethod(opcode, body["$operand"] as object[]);
                    }
                    else
                    {
                        NKLogging.log(String.Format("!Invalid member name: {0}", opcode));
                    }
                }
                else if (opcode == "+")
                {
                    // Create instance
                    var args = body["$operand"] as Array;
                    var ns   = String.Format("{0}[{1}]", principal.ns, target);
                    instances[target] = new NKScriptValueNative(ns, this, args);
                }
                else
                {
                    // else Unknown opcode
                    var obj = principal.plugin as NKScriptMessageHandler;
                    if (obj != null)
                    {
                        obj.didReceiveScriptMessage(message);
                    }
                    else
                    {
                        // discard unknown message
                        NKLogging.log(String.Format("!Unknown message: {0}", message.body.ToString()));
                    }
                }
            }
            else
            {
                // null body, ignore
            }

            //thread static
            NKScriptChannel._currentContext = null;
        }
        public override void didReceiveScriptMessage(NKScriptMessage message)
        {
            // A workaround for when postMessage(undefined)
            if (message.body == null)
            {
                return;
            }

            var body = message.body as Dictionary <string, object>;

            if (body != null && body.ContainsKey("$opcode"))
            {
                string opcode = body["$opcode"] as String;
                int    target = Int32.Parse(body["$target"].ToString());
                NKScriptMessageHandler proxy = null;
                if (_proxies.ContainsKey(target))
                {
                    proxy = _proxies[target];
                }
                else if (target > 1500)
                {
                    var targetFloor = target - (target % NKRANGEPERPROCESS);
                    if (_proxiesNatives.ContainsKey(targetFloor))
                    {
                        proxy = _proxiesNatives[targetFloor];
                    }
                }

                if (proxy != null)
                {
                    if (opcode == "-")
                    {
                        if (target == 0)
                        {
                            // TRANSFER TO REMOTE, WITH SYNC
                            var _ = proxy.didReceiveScriptMessageSync(message);
                            this.unbind();
                        }
                        else
                        {
                            // TRANSFER TO REMOTE, WITH SYNC
                            var _ = proxy.didReceiveScriptMessageSync(message);

                            // UNBIND PROXY
                            _cancelTokens[target].Cancel();
                        }
                    }
                    else if (typeInfo.ContainsProperty(opcode))
                    {
                        // ALSO TRANSFER TO REMOTE
                        proxy.didReceiveScriptMessage(message);
                    }
                    else if (typeInfo.ContainsMethod(opcode))
                    {
                        // Invoke method

                        // TRANSFER TO REMOTE ONLY
                        proxy.didReceiveScriptMessage(message);
                    }
                    else
                    {
                        NKLogging.log(String.Format("!Invalid member name: {0}", opcode));
                    }
                }
                else if (opcode == "+")
                {
                    throw new NotImplementedException("+ opcode must be called using synchronous messages");
                }
                else
                {
                    // else Unknown opcode
                    var obj = _principal.plugin as NKScriptMessageHandler;
                    if (obj != null)
                    {
                        obj.didReceiveScriptMessage(message);
                    }
                    else
                    {
                        // discard unknown message
                        NKLogging.log(String.Format("!Unknown message: {0}", message.body.ToString()));
                    }
                }
            }
            else
            {
                // null body, ignore
            }
        }
        public override object didReceiveScriptMessageSync(NKScriptMessage message)
        {
            // A workaround for when postMessage(undefined)
            if (message.body == null)
            {
                return(false);
            }

            // thread static
            NKScriptValue._currentContext = this.context;
            object result;

            var body = message.body as Dictionary <string, object>;

            if (body != null && body.ContainsKey("$opcode"))
            {
                string opcode = body["$opcode"] as String;
                int    target = Int32.Parse(body["$target"].ToString());
                NKScriptMessageHandler proxy = null;
                if (_proxies.ContainsKey(target))
                {
                    proxy = _proxies[target];
                }
                else if (target > 1500)
                {
                    var targetFloor = target - (target % 10);
                    if (_proxiesNatives.ContainsKey(targetFloor))
                    {
                        proxy = _proxiesNatives[targetFloor];
                    }
                }

                if (proxy != null)
                {
                    if (opcode == "-")
                    {
                        if (target == 0)
                        {
                            // TRANSFER TO REMOTE
                            var _ = proxy.didReceiveScriptMessageSync(message);

                            this.unbind();
                            result = true;
                        }
                        else
                        {
                            // TRANSFER TO REMOTE
                            var _ = proxy.didReceiveScriptMessageSync(message);

                            // UNBIND PROXY
                            _cancelTokens[target].Cancel();

                            result = true;
                        }
                    }
                    else if (typeInfo.ContainsProperty(opcode))
                    {
                        // TRANSFER TO REMOTE
                        proxy.didReceiveScriptMessageSync(message);
                        result = true;
                    }
                    else if (typeInfo.ContainsMethod(opcode))
                    {
                        // Invoke method via REMOTE proxy
                        result = proxy.didReceiveScriptMessageSync(message);
                    }
                    else
                    {
                        NKLogging.log(String.Format("!Invalid member name: {0}", opcode));
                        result = false;
                    }
                }
                else if (opcode == "+")
                {
                    _instances[target] = null;

                    int maxNativeFirst = NKScriptChannel.nativeFirstSequence - (NKScriptChannel.nativeFirstSequence % NKRANGEPERPROCESS) - 1;
                    int minNativeFirst = (maxNativeFirst - NKRANGEPERPROCESS) + 1;
                    NKScriptChannel.nativeFirstSequence = minNativeFirst - 1;

                    var cancelTokenSource = new CancellationTokenSource();
                    _cancelTokens[target] = cancelTokenSource;
                    proxy            = NKRemoting.NKRemotingProxy.createClient(ns, id, maxNativeFirst, message, context, cancelTokenSource.Token);
                    _proxies[target] = proxy;
                    _proxiesNatives[minNativeFirst] = proxy;

                    result = true;
                }
                else
                {
                    // else Unknown opcode
                    var obj = _principal.plugin as NKScriptMessageHandler;
                    if (obj != null)
                    {
                        result = obj.didReceiveScriptMessageSync(message);
                    }
                    else
                    {
                        // discard unknown message
                        NKLogging.log(String.Format("!Unknown message: {0}", message.body.ToString()));
                        result = false;
                    }
                }
            }
            else
            {
                // null body
                result = false;
            }

            //thread static
            NKScriptValue._currentContext = null;
            return(result);
        }