private NKSNKRemotingContext(NKScriptContextRemotingProxy proxy, Dictionary <string, object> options) : base(proxy.NKid) { _async_queue = null; this._proxy = proxy; proxy.context = this; NKLogging.log("+NodeKit Renderer Remoting JavaScript Proxy E" + _id); }
public NKE_BrowserWindow(Dictionary <string, object> options) { _thread_id = (int)startupOptions["NKS.MainThreadId"]; syncContext = new TaskFactory((TaskScheduler)startupOptions["NKS.MainThreadScheduler"]); _id = NKScriptContextFactory.sequenceNumber++; if (options == null) { options = new Dictionary <string, object>(); } windowArray[_id] = this; try { _webContents = new NKE_WebContents(this); var _ = ensureOnUIThread(createBrowserWindow, options); } catch (Exception ex) { NKLogging.log("!Error Creating Window" + ex.Message); NKLogging.log(ex.StackTrace); } events.on <int>("NKE.DidFinishLoad", (e, id) => { this.getNKScriptValue().invokeMethod("emit", new[] { "did-finish-load" }); }); }
private async Task createBrowserWindow(object optionsObject) { Dictionary <string, object> options = optionsObject as Dictionary <string, object>; // PARSE & STORE OPTIONS if (options.ContainsKey(NKEBrowserOptions.nkBrowserType)) { browserType = (NKEBrowserType)Enum.Parse(typeof(NKEBrowserType), (options[NKEBrowserOptions.nkBrowserType]) as string); } else { browserType = NKEBrowserDefaults.nkBrowserType; } switch (browserType) { case NKEBrowserType.WKWebView: throw new PlatformNotSupportedException(); case NKEBrowserType.UIWebView: throw new PlatformNotSupportedException(); case NKEBrowserType.MSWebView: NKLogging.log("+creating Native (Edge/Trident) Renderer"); await _webContents.createWebView(options); break; default: break; } }
// incoming data receive loop private async Task _receiveData() { try { var stream = _socket.InputStream; IBuffer buffer = new Windows.Storage.Streams.Buffer(10240); while (true) { IBuffer data = await stream.ReadAsync(buffer, buffer.Capacity, InputStreamOptions.Partial); if (data.Length == 0) { break; } _emitData(data); } // Client disconnected. _emitEnd(); _socket = null; if (_server != null) { _server._connectionDidClose(this); } } catch (System.IO.IOException ex) { NKLogging.log(ex.ToString()); } catch (Exception ex) { NKLogging.log(ex.ToString()); } }
private NKSMSWebBrowserContext(int id, WebBrowser webView, Dictionary <string, object> options) : base(id) { try { _async_queue = TaskScheduler.FromCurrentSynchronizationContext(); this._isLoaded = false; this._isFirstLoaded = false; this._webView = webView; this._id = id; this.tcs = new TaskCompletionSource <NKScriptContext>(); _webViewScriptDelegate = new NKSMSWebViewScriptDelegate(this); _webViewCallbackBridge = new NKSMSWebBrowserCallback(_webViewScriptDelegate); _webView.Navigating += _webView_Navigating; #if WINDOWS_WIN32_WPF webView.LoadCompleted += _webView_LoadCompleted; #elif WINDOWS_WIN32_WF webView.DocumentCompleted += _webView_DocumentCompleted; #endif _webView.ObjectForScripting = _webViewCallbackBridge; } catch (Exception ex) { NKLogging.log("!Error creating Trident context: " + ex.Message); NKLogging.log(ex.StackTrace); } }
internal async Task createWebView(Dictionary <string, object> options) { try { // throw new NotImplementedException(); #if WINDOWS_WIN32_WPF _browserWindow.createWindow(options); WebBrowser webView = _browserWindow._window.webBrowser; #elif WINDOWS_WIN32_WF WebBrowser webView = new WebBrowser(); _browserWindow.createWindow(options, webView); #endif this.webView = webView; _browserWindow.webView = webView; string url; if (options.ContainsKey(NKEBrowserOptions.kPreloadURL)) { url = (string)options[NKEBrowserOptions.kPreloadURL]; } else { url = NKEBrowserDefaults.kPreloadURL; } webView.Navigate(new Uri(url)); #if WINDOWS_WIN32_WPF webView.Navigating += this.WebView_Navigating; webView.LoadCompleted += this.WebView_LoadCompleted; #elif WINDOWS_WIN32_WF webView.Navigating += this.WebView_Navigating; webView.DocumentCompleted += this.WebView_DocumentCompleted; #endif this.init_IPC(); _browserWindow.context = await NKSMSWebBrowserContext.getScriptContext(_id, webView, options); this._type = NKEBrowserType.MSWebView.ToString(); if (options.itemOrDefault <bool>("NKE.InstallElectro", true)) { await Renderer.addElectro(_browserWindow.context, options); } NKLogging.log(string.Format("+E{0} Renderer Ready", _id)); _browserWindow.events.emit("NKE.DidFinishLoad", _id); } catch (Exception ex) { NKLogging.log("!Error creating browser webcontent: " + ex.Message); NKLogging.log(ex.StackTrace); } options = null; }
private void Process_Exited(object sender, EventArgs e) { NKLogging.log("+[MAIN] The Renderer Process has exited"); try { asyncPipe.Close(); syncPipeIn.Close(); syncPipeOut.Close(); } catch { } NKEventEmitter.global.emit <string>("NKS.ProcessRemoved", id, false); }
public async Task NKinjectScript(NKScriptSource source) { if (_injectedScripts.Contains(source)) { throw new InvalidOperationException("Script has already been injected to a context; create separate NKSCriptSource for each instance"); } _injectedScripts.Add(source); source.registerInject(this); await InjectScript(source); NKLogging.log(string.Format("+E{0} Injected {1}", this.NKid, source.filename)); }
public async Task <Dictionary <string, object> > stat(string path) { if (appResources.exists(path)) { return(appResources.stat(path)); } if (localResources.exists(path)) { return(localResources.stat(path)); } Dictionary <string, object> storageItem = new Dictionary <string, object>(); NKLogging.log("Stat Not Found " + path); return(storageItem); var foldername = System.IO.Path.GetDirectoryName(path); var filename = System.IO.Path.GetFileName(path); try { var folder = await StorageFolder.GetFolderFromPathAsync(foldername); var item = await folder.GetItemAsync(filename); storageItem["birthtime"] = item.DateCreated; storageItem["path"] = item.Path; var properties = await item.GetBasicPropertiesAsync(); storageItem["mtime"] = properties.DateModified; if (item.IsOfType(StorageItemTypes.Folder)) { storageItem["size"] = 0; storageItem["filetype"] = "Directory"; } else { storageItem["size"] = properties.Size; storageItem["filetype"] = "File"; } return(storageItem); } catch { NKLogging.log("Stat Not Found " + path); return(storageItem); } }
private void _emitData(IBuffer data) { string str = Windows.Security.Cryptography.CryptographicBuffer.EncodeToBase64String(data); var js = this.getNKScriptValue(); if (js != null) { js.invokeMethod("emit", new object[] { "data", str }); } else { NKLogging.log("!TCP: Cannot find NKScriptValue"); } }
protected async Task LoadPluginBase <T>(T plugin, string ns, Dictionary <string, object> options) where T : class { bool mainThread = (bool)options["NKS.MainThread"]; bool remoteProcess = NKOptions.itemOrDefault(options, "NKS.RemoteProcess", false); NKScriptExportType bridge = (NKScriptExportType)options["NKS.PluginBridge"]; NKScriptChannelProtocol channel; switch (bridge) { case NKScriptExportType.NKScriptExport: if (remoteProcess) { channel = new NKScriptChannelRemote((NKScriptContext)this); } else if (mainThread) { channel = new NKScriptChannel((NKScriptContext)this, (TaskScheduler)options["NKS.MainThreadScheduler"]); } else { channel = new NKScriptChannel((NKScriptContext)this); } var scriptValue = await channel.bindPlugin <T>(plugin, ns); _injectedPlugins.Add(scriptValue); NKLogging.log("+NKScripting Plugin loaded at " + ns); break; case NKScriptExportType.NKScriptExportRemote: if (mainThread) { channel = new NKScriptChannelRemote((NKScriptContext)this, (TaskScheduler)options["NKS.MainThreadScheduler"]); } else { channel = new NKScriptChannelRemote((NKScriptContext)this); } var scriptValueRemote = await channel.bindPlugin <T>(plugin, ns); _injectedPlugins.Add(scriptValueRemote); NKLogging.log("+NKScripting Remote Plugin loaded at " + ns); break; default: throw new InvalidOperationException("Load Plugin Base called for non-handled bridge type"); } }
private NKSMSWebViewContext(int id, WebView webView, Dictionary <string, object> options) : base(id) { _async_queue = TaskScheduler.FromCurrentSynchronizationContext(); this._isLoaded = false; this._isFirstLoaded = false; this._webView = webView; this._id = id; this.tcs = new TaskCompletionSource <NKScriptContext>(); _webViewScriptDelegate = new NKSMSWebViewScriptDelegate(this); _webViewCallbackBridge = new NKSMSWebViewCallback(_webViewScriptDelegate); _webView.NavigationStarting += _webView_NavigationStarting; _webView.DOMContentLoaded += _webView_DOMContentLoaded; NKLogging.log("+NodeKit Edge JavaScript Engine E" + id); }
private JavaScriptValue log(JavaScriptValue callee, bool isConstructCall, JavaScriptValue[] arguments, ushort argumentCount, IntPtr callbackData) { var arg = arguments[1]; if (arg.ValueType == JavaScriptValueType.Undefined || arg.ValueType == JavaScriptValueType.Null) { NKLogging.log(arg.ValueType.ToString()); } else { NKLogging.log(arg.ToString()); } return(JavaScriptValue.Null); }
private NKRemotingMessage readObject(Stream stream) { NKRemotingMessage obj = null; try { var len = _readLength(stream); if (len == 0) { return(null); } obj = _readObject(stream, len); } catch (Exception ex) { NKLogging.log("!Read Error" + ex.Message); } return(obj); }
protected override object RunScript(string javaScriptString, string filename) { IntPtr returnValue; try { JavaScriptValue result; switchContextifNeeded(); if (filename != null && filename != "") { result = JavaScriptContext.RunScript(javaScriptString, currentSourceContext, filename); currentSourceContext = JavaScriptSourceContext.Increment(currentSourceContext); } else { result = JavaScriptContext.RunScript(javaScriptString, JavaScriptSourceContext.None, string.Empty); } // Execute promise tasks stored in taskQueue while (_jsTaskQueue.Count != 0) { JavaScriptValue jsTask = (JavaScriptValue)_jsTaskQueue.Dequeue(); JavaScriptValue promiseResult; JavaScriptValue global; Native.JsGetGlobalObject(out global); JavaScriptValue[] args = new JavaScriptValue[1] { global }; Native.JsCallFunction(jsTask, args, 1, out promiseResult); } // Convert the return value. JavaScriptValue stringResult; UIntPtr stringLength; Native.ThrowIfError(Native.JsConvertValueToString(result, out stringResult)); Native.ThrowIfError(Native.JsStringToPointer(stringResult, out returnValue, out stringLength)); } catch (Exception e) { // throw e; NKLogging.log(e.Message); return(null); } return(Marshal.PtrToStringUni(returnValue)); }
//RENDERER private NKRemotingProxy(string[] args) { NKLogging.log("+Started Renderer in new Process"); this.context = null; this._localHandlers = new Dictionary <string, NKScriptMessageHandler>(); this.cancelTokenSource = new CancellationTokenSource(); this.cancelToken = cancelTokenSource.Token; var outHandle = args[2]; var inHandle = args[1]; var syncPipeOut = new AnonymousPipeClientStream(PipeDirection.Out, outHandle); var syncPipeIn = new AnonymousPipeClientStream(PipeDirection.In, inHandle); this.syncPipeOut = syncPipeOut; this.syncPipeIn = syncPipeIn; syncPipeIn.ReadByte(); var handshake = readObject(syncPipeIn); if (handshake.command != NKRemotingMessage.Command.NKRemotingHandshake) { Environment.Exit(911); } var pipeName = handshake.args[0]; ns = handshake.args[1]; id = handshake.args[2]; NKScriptChannel.nativeFirstSequence = Int32.Parse(handshake.args[3]); handshake.args = new string[] { }; writeObject(syncPipeOut, handshake); var asyncPipe = new NamedPipeClientStream(".", pipeName, PipeDirection.InOut, PipeOptions.Asynchronous | PipeOptions.WriteThrough); asyncPipe.Connect(); cancelToken.Register(requestSelfTeardown); this.asyncPipe = asyncPipe; Task.Factory.StartNew((s) => _processClientMessages(), null, cancelToken, TaskCreationOptions.LongRunning, TaskScheduler.Default); }
// RENDERER NKScriptContextRemotingProxy Methods void NKScriptContextRemotingProxy.NKready() { var _channel = NKScriptChannel.getChannel(ns); context = _channel.context; _localHandlers[id] = _channel; _channel.singleInstance = true; NKEventEmitter.global.once("NKS.SingleInstanceComplete", (string e, string s) => { Task.Delay(500).ContinueWith((t) => { NKLogging.log("+[RENDERER] Window Closed"); this.cancelTokenSource.Cancel(); }); }); var msg = new NKRemotingMessage(); msg.command = NKRemotingMessage.Command.NKRemotingReady; msg.args = new string[] { }; writeObject(asyncPipe, msg); NKEventEmitter.global.forward <NKEvent>(eventForwarderFromRenderer); }
public async Task <NKScriptValue> bindPlugin(object obj, string ns) { await this.prepareForPlugin(); if ((this.id != null) || (context == null)) { return(null); } if (this.userContentController == null) { return(null); } this.id = (this.sequenceNumber++).ToString(); this.userContentController.NKaddScriptMessageHandler(this, id); if (obj.GetType() == typeof(Type)) { // Class, not instance, passed to bindPlugin -- to be used in Factory constructor/instance pattern in js isFactory = true; typeInfo = new NKScriptTypeInfo((Type)obj); // Need to store the channel on the class itself so it can be found when native construct requests come in from other plugins obj.setNKScriptChannel(this); } else { // Instance of Princpal passed to bindPlugin -- to be used in singleton/static pattern in js isFactory = false; typeInfo = new NKScriptTypeInfo(obj.GetType()); } _principal = new NKScriptValueNative(ns, this, obj); this.instances[0] = _principal; var script = new NKScriptSource(_generateStubs(typeInfo.Name), ns + "/plugin/" + typeInfo.Name + ".js"); NKLogging.log(script.source); await script.inject(context); return(_principal); }
async private Task prepareForPlugin() { if (preparationComplete) { return; } try { context.setNKScriptChannel(this); var source = await getResource("nkscripting.js", "lib"); if (source == null) { throw new FileNotFoundException("Could not find file nkscripting.js"); } var script = new NKScriptSource(source, "io.nodekit.scripting/NKScripting/nkscripting.js", "NKScripting", null); await script.inject(context); preparationComplete = true; } catch { preparationComplete = false; } var source2 = await getResource("promise.js", "lib"); var script2 = new NKScriptSource(source2, "io.nodekit.scripting/NKScripting/promise.js", "Promise", null); await script2.inject(context); if (preparationComplete) { NKLogging.log(String.Format("+E{0} JavaScript Engine is ready for loading plugins", context.NKid)); } else { NKLogging.log(String.Format("+E{0} JavaScript Engine could not load NKScripting.js", context.NKid)); } }
async public Task <NKScriptContext> completeInitialization() { if (preparationComplete) { return(this); } try { var source = await NKStorage.getResourceAsync(typeof(NKScriptContext), "nkscripting.js", "lib"); if (source == null) { throw new FileNotFoundException("Could not find file nkscripting.js"); } var script = new NKScriptSource(source, "io.nodekit.scripting/NKScripting/nkscripting.js", "NKScripting", null); await this.NKinjectScript(script); await ensureOnEngineThread(async() => { await PrepareEnvironment(); preparationComplete = true; }).Unwrap(); } catch { preparationComplete = false; } if (preparationComplete) { NKLogging.log(String.Format("+E{0} JavaScript Engine is ready for loading plugins", this.NKid)); } else { NKLogging.log(String.Format("+E{0} JavaScript Engine could not load NKScripting.js", this.NKid)); } return(this); }
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); }
internal async Task createWebView(Dictionary <string, object> options) { _browserWindow._window = await _browserWindow.createWindow(options); string url; if (options.ContainsKey(NKEBrowserOptions.kPreloadURL)) { url = (string)options[NKEBrowserOptions.kPreloadURL]; } else { url = NKEBrowserDefaults.kPreloadURL; } WebView webView = new WebView(WebViewExecutionMode.SeparateThread); this.webView = webView; _browserWindow.webView = webView; _browserWindow._window.controls.Add(webView); webView.Navigate(new Uri(url)); _browserWindow.context = await NKSMSWebViewContext.getScriptContext(_id, webView, options); webView.NavigationStarting += WebView_NavigationStarting; webView.NavigationCompleted += this.WebView_NavigationCompleted; this.init_IPC(); this._type = NKEBrowserType.MSWebView.ToString(); if (options.itemOrDefault <bool>("NKE.InstallElectro", true)) { await Renderer.addElectro(_browserWindow.context, options); } NKLogging.log(string.Format("+E{0} Renderer Ready", _id)); _browserWindow.events.emit("NKE.DidFinishLoad", _id); }
// 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; } }
void NKSMSWebBrowserCallbackProtocol.log(string message) { NKLogging.log(message); }
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); }
public void error(String msg) { NKLogging.log(msg); }
public void log(object msg) { NKLogging.log(msg); }
protected override async Task LoadPlugin <T>(T plugin, string ns, Dictionary <string, object> options) { bool mainThread = (bool)options["NKS.MainThread"]; NKScriptExportType bridge = (NKScriptExportType)options["NKS.PluginBridge"]; switch (bridge) { case NKScriptExportType.JSExport: throw new NotSupportedException("JSExport option is for darwin platforms only"); case NKScriptExportType.WinRT: if (plugin == null) { switchContextifNeeded(); if (!_projectedNamespaces.Contains(ns)) { Native.ThrowIfError(Native.JsProjectWinRTNamespace(ns)); _projectedNamespaces.Add(ns); NKLogging.log("+Windows Unversal Component namespace loaded at " + ns); } } else if (typeof(T) != typeof(Type)) { throw new ArgumentException("Windows Universal Components can only be provided as a type"); } else { var t = (plugin as Type); var projectionNamespace = t.Namespace; var projectionName = t.Name; var projectionFullName = projectionNamespace + "." + projectionName; var targetNamespace = ns; switchContextifNeeded(); if (!_projectedNamespaces.Contains(projectionNamespace)) { Native.ThrowIfError(Native.JsProjectWinRTNamespace(projectionNamespace)); _projectedNamespaces.Add(projectionNamespace); } var cs = new NKScriptExportProxy <T>(plugin); var localstub = cs.rewriteGeneratedStub("", ".local"); var globalstubber = "(function(exports) {\n" + localstub + "})(NKScripting.createProjection('" + targetNamespace + "', " + projectionFullName + "));\n"; var globalstub = cs.rewriteGeneratedStub(globalstubber, ".global"); var script = new NKScriptSource(globalstub, targetNamespace + "/plugin/" + projectionName + ".js"); await this.NKinjectScript(script); await cs.initializeForContext(this); plugin.setNKScriptValue(this.NKgetScriptValue(targetNamespace)); NKLogging.log("+Windows Unversal Component Plugin with script loaded at " + targetNamespace); } break; default: throw new NotImplementedException("Unknown Scripting Plugin Bridge Option"); } }
void NKSMSWebViewCallbackProtocol.log(string message) { NKLogging.log(message); }
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; }