//register direct call delegate and callback delegate public static void RegisterFunctionConverter <T1, T2, T3, TResult>(this IJSValueConverterService service) { if (!service.CanConvert <Func <bool, T1, T2, T3, TResult> >()) { service.RegisterConverter <Func <bool, T1, T2, T3, TResult> >(toJSFunction <T1, T2, T3, TResult>, fromJSFunction <T1, T2, T3, TResult>, false); } if (!service.CanConvert <Func <T1, T2, T3, TResult> >()) { service.RegisterConverter <Func <T1, T2, T3, TResult> >(toJSCallbackFunction <T1, T2, T3, TResult>, fromJSCallbackFunction <T1, T2, T3, TResult>, false); } }
public static void RegisterProxyConverter <T>(this IJSValueConverterService service, Action <JSValueBinding, T, IServiceNode> createBinding) where T : class { toJSValueDelegate <T> tojs = (IServiceNode node, T value) => { return(node.GetService <IContextSwitchService>().With(() => { var result = JavaScriptValue.CreateExternalObject(IntPtr.Zero, null); JSValueBinding binding = new JSValueBinding(node, result); var handle = node.GetService <IGCSyncService>().SyncWithJsValue(value, result); result.ExternalData = GCHandle.ToIntPtr(handle);//save the object reference to javascript values's external data createBinding?.Invoke(binding, value, node); return result; })); }; fromJSValueDelegate <T> fromjs = (IServiceNode node, JavaScriptValue value) => { if (value.HasExternalData) { GCHandle handle = GCHandle.FromIntPtr(value.ExternalData); return(handle.Target as T); } else { throw new ArgumentOutOfRangeException("Convert from jsValue to proxy object failed, jsValue does not have a linked CLR object"); } }; service.RegisterConverter <T>(tojs, fromjs); }
public static void RegisterMethodConverter <T1, T2, T3, T4>(this IJSValueConverterService service) { if (service.CanConvert <Action <T1, T2, T3, T4> >()) { return; } service.RegisterConverter <Action <T1, T2, T3, T4> >(toJSMethod <T1, T2, T3, T4>, fromJSMethod <T1, T2, T3, T4>, false); }
public static void RegisterTask <TResult>(this IJSValueConverterService target) { if (target.CanConvert <Task <TResult> >()) { return; } //register internal call back types target.RegisterFunctionConverter <TResult>(); target.RegisterMethodConverter <TResult>(); target.RegisterMethodConverter <string>(); target.RegisterFunctionConverter <JSValue>(); target.RegisterMethodConverter <JavaScriptValue>(); target.RegisterMethodConverter <Action <TResult>, Action <JavaScriptValue> >(); target.RegisterConverter <Task <TResult> >( (node, value) => { //convert resolve, reject Action <Action <TResult>, Action <JavaScriptValue> > promiseBody = async(resolve, reject) => { try { var result = await value; resolve(result); } catch (PromiseRejectedException ex) { reject(ex.Error); } catch (Exception) { throw; } }; var jsValueService = node.GetService <IJSValueService>(); var globalObject = jsValueService.JSGlobalObject; var jsGlobalObject = new JSValue(node, globalObject); return(jsGlobalObject.CallFunction <Action <Action <TResult>, Action <JavaScriptValue> >, JavaScriptValue>("Promise", promiseBody, true)); }, (node, value) => { //from a promise return(Task.Factory.FromAsync( (callback, state) => { return BeginMethod <TResult>(value, node, callback, state); } , EndMethod <TResult>, null )); }, false ); }
public static void RegisterProxyConverter <T>(this IJSValueConverterService service, Action <JSValueBinding, T, IServiceNode> createBinding) where T : class { toJSValueDelegate <T> tojs = (IServiceNode node, T value) => { var mapService = node.GetService <IProxyMapService>(); return(mapService.Map <T>(value, createBinding)); }; fromJSValueDelegate <T> fromjs = (IServiceNode node, JavaScriptValue value) => { var mapService = node.GetService <IProxyMapService>(); return(mapService.Get <T>(value)); }; service.RegisterConverter <T>(tojs, fromjs); }
public static void RegisterStructConverter <T>(this IJSValueConverterService service, Action <JSValue, T> toJSValue, Func <JSValue, T> fromJSValue) //where T:struct { service.RegisterConverter <T>( (node, value) => { JavaScriptValue jsObj = node.GetService <IJSValueService>().CreateObject(); JSValue v = new JSValue(node, jsObj); toJSValue(v, value); return(jsObj); }, (node, value) => { JSValue v = new JSValue(node, value); return(fromJSValue(v)); } ); }
public static void RegisterArrayConverter <T>(this IJSValueConverterService service) { toJSValueDelegate <IEnumerable <T> > tojs = (node, value) => { return(node.WithContext <JavaScriptValue>(() => { var result = node.GetService <IJSValueService>().CreateArray(Convert.ToUInt32(value.Count())); int index = 0; foreach (T item in value) { result.SetIndexedProperty(service.ToJSValue <int>(index++), service.ToJSValue <T>(item)); } return result; } )); }; fromJSValueDelegate <IEnumerable <T> > fromjs = (node, value) => { return(node.WithContext <IEnumerable <T> >(() => { var jsValueService = node.GetService <IJSValueService>(); var length = service.FromJSValue <int>(value.GetProperty(JavaScriptPropertyId.FromString("length"))); List <T> result = new List <T>(length);//copy the data to avoid context switch in user code for (int i = 0; i < length; i++) { result.Add( service.FromJSValue <T>(value.GetIndexedProperty( service.ToJSValue <int>(i)) ) ); } return result; } )); }; service.RegisterConverter <IEnumerable <T> >(tojs, fromjs, false); }
private void registerBasicTypes(IJSValueConverterService converter) { converter.RegisterStructConverter <PointF>( (jsvalue, value) => { jsvalue.WriteProperty("X", value.X); jsvalue.WriteProperty("Y", value.Y); }, (jsvalue) => { return(new PointF( jsvalue.ReadProperty <float>("X") , jsvalue.ReadProperty <float>("Y"))); }); converter.RegisterStructConverter <SizeF>( (jsvalue, value) => { jsvalue.WriteProperty("Width", value.Width); jsvalue.WriteProperty("Height", value.Height); }, (jsvalue) => { return(new SizeF( jsvalue.ReadProperty <float>("Width") , jsvalue.ReadProperty <float>("Height"))); }); converter.RegisterStructConverter <RectangleF>( (jsvalue, value) => { jsvalue.WriteProperty("X", value.X); jsvalue.WriteProperty("Y", value.Y); jsvalue.WriteProperty("Width", value.Width); jsvalue.WriteProperty("Height", value.Height); }, (jsvalue) => { return(new RectangleF( jsvalue.ReadProperty <float>("X") , jsvalue.ReadProperty <float>("Y") , jsvalue.ReadProperty <float>("Width") , jsvalue.ReadProperty <float>("Height"))); }); converter.RegisterArrayConverter <PointF>(); converter.RegisterConverter <BlendModeEnum>( (node, value) => { return(node.GetService <IContextSwitchService>().With(() => { return API.JavaScriptValue.FromInt32((int)value); })); }, (node, jsvalue) => { return(node.GetService <IContextSwitchService>().With(() => { return (BlendModeEnum)jsvalue.ToInt32(); })); } ); converter.RegisterStructConverter <Effect>( (jsvalue, value) => { jsvalue.WriteProperty <string>(nameof(value.Name), value.Name); jsvalue.WriteProperty <string>(nameof(value.ConfigJson), value.ConfigJson); }, (jsvalue) => { return(new Effect() { Name = jsvalue.ReadProperty <string>(nameof(Effect.Name)), ConfigJson = jsvalue.ReadProperty <string>(nameof(Effect.ConfigJson)) }); } ); }