protected virtual void unbind() { var context = this.context; if (_channels.ContainsKey(ns)) { _channels.Remove(ns); } if (id == null) { return; } id = null; _instances.Clear(); if (isFactory) { _principal.nativeObject.setNKScriptChannel(null); } _principal = null; context.NKremoveScriptMessageHandlerForName(id); _context = null; _typeInfo = null; _queue = null; _instances = null; context = null; }
// Public methods public virtual async Task <NKScriptValue> bindPlugin <T>(T obj, string ns) where T : class { var context = this.context; context.setNKScriptChannel(this); if ((this.id != null) || (context == null)) { return(null); } this.id = (NKScriptChannel.sequenceNumber++).ToString(); context.NKaddScriptMessageHandler(this, id); string name; if (typeof(T) == typeof(Type)) { // Class, not instance, passed to bindPlugin -- to be used in Factory constructor/instance pattern in js isFactory = true; _typeInfo = new NKScriptTypeInfo <T>(obj); name = (obj as Type).Name; // 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 { name = (typeof(T)).Name; // Instance of Princpal passed to bindPlugin -- to be used in singleton/static pattern in js isFactory = false; _typeInfo = new NKScriptTypeInfo <T>(obj); } _principal = new NKScriptValueNative(ns, this, 0, obj); this._instances[0] = _principal; _channels[ns] = this; obj.setNKScriptValue(_principal); var export = new NKScriptExportProxy <T>(obj); var script = new NKScriptSource(_generateStubs(export, name), ns + "/plugin/" + name + ".js"); await context.NKinjectScript(script); await export.initializeForContext(context); return(_principal); }
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); }
internal void unbind() { if (id == null) { return; } id = null; instances.Clear(); if (isFactory) { _principal.nativeObject.setNKScriptChannel(null); } _principal = null; userContentController.NKremoveScriptMessageHandlerForName(id); _userContentController.SetTarget(null); _context.SetTarget(null); typeInfo = null; queue = null; instances = null; }
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 virtual void addInstance(int id, NKScriptValueNative instance) { _instances[id] = instance; }
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; }
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; }
internal void unbind() { if (id == null) return; id = null; instances.Clear(); if (isFactory) _principal.nativeObject.setNKScriptChannel(null); _principal = null; userContentController.NKremoveScriptMessageHandlerForName(id); _userContentController.SetTarget(null); _context.SetTarget(null); typeInfo = null; queue = null; instances = null; }
public virtual string NKserialize(object obj) { IFormatProvider invariant = System.Globalization.CultureInfo.InvariantCulture; Type t = obj.GetType(); TypeInfo ti = t.GetTypeInfo(); if (obj == null) { return("undefined"); } if (obj != null && obj.GetType().GetTypeInfo().IsPrimitive) { // The primitive types are Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Int64, UInt64, IntPtr, UIntPtr, Char, Double, and Single. if (obj is Char) { return("'" + Convert.ToString(((Char)obj), invariant) + "'"); } if (obj is Boolean) { return((Boolean)obj ? "true" : "false"); } return(Convert.ToString(obj, System.Globalization.CultureInfo.InvariantCulture)); } if (obj is NKScriptValue) { return(((NKScriptValue)obj).ns); } if (obj is NKScriptExport) { var scriptValueObject = obj.getNKScriptValue(); if (scriptValueObject != null) { return(scriptValueObject.ns); } var newScriptValueObject = new NKScriptValueNative(obj, (NKScriptContext)this); return(newScriptValueObject.ns); } if (obj is string) { var str = NKData.jsonSerialize((string)obj); return(str); // str.Substring(1, str.Length - 2); } if (obj is DateTime) { return("\"" + ((DateTime)obj).ToString("u") + "\""); } if (typeof(IDictionary).GetTypeInfo().IsAssignableFrom(ti)) { var genericKey = ti.GenericTypeArguments[0]; if (typeof(string).GetTypeInfo().IsAssignableFrom(genericKey.GetTypeInfo())) { var dict = (IDictionary <string, dynamic>)obj; return("{" + string.Join(", ", dict.Keys.Select(k => "\"" + k + "\":" + NKserialize(dict[k]))) + "}"); } } if (typeof(IEnumerable).GetTypeInfo().IsAssignableFrom(ti)) { return("[" + string.Join(", ", ((IEnumerable <dynamic>)obj).Select(o => NKserialize(o))) + "]"); } return(Convert.ToString(obj, System.Globalization.CultureInfo.InvariantCulture)); }
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; }