public static void Register(JavaScriptContext context) { JavaScriptValue symbolGlobal = JavaScriptValue.GlobalObject.GetProperty("Symbol"); modulesSymbol = symbolGlobal.GetProperty("for").CallFunction(symbolGlobal, JavaScriptValue.FromString("typescript-for-unity.importedRootModules")); modulesSymbol.AddRef(); JavaScriptValue.GlobalObject.SetProperty(modulesSymbol, JavaScriptValue.CreateObject()); }
public JSValue(JavaScriptValue val) { rawvalue = val; if (rawvalue.IsValid) { rawvalue.AddRef(); } }
/// <summary> /// Creates a new <see cref="JsCallback"/> instance. /// </summary> public JsCallback(JsExecutionContext context, JsContextScope scope, JsInterop interop, JavaScriptValue callback) { _context = context; _scope = scope; _interop = interop; _callback = callback; _callback.AddRef(); }
private static void PromiseContinuationCallback( JavaScriptValue task, IntPtr callbackState ) { task.AddRef(); // call Release later promiseTaskQueue.Enqueue(task); }
public void RecognizeFaces(JavaScriptValue faces, JavaScriptValue callback) { var boundList = new List <BitmapBounds>(); for (int i = 0; i < faces.Length().Value; ++i) { var jsBounds = faces.Get(i).Get("bounds"); var bounds = new BitmapBounds() { X = (uint)jsBounds.Get("x").ToInt32(), Y = (uint)jsBounds.Get("y").ToInt32(), Width = (uint)jsBounds.Get("width").ToInt32(), Height = (uint)jsBounds.Get("height").ToInt32() }; boundList.Add(bounds); } int frameID = faces.Get(0).Get("frame").Get("id").ToInt32(); var frame = SceneCameraManager.Inst.GetFrameFromCache(frameID); callback.AddRef(); faces.AddRef(); server.RecognizeFaces(frame.bitmap, boundList, (s) => { JsonObject json; if (!JsonObject.TryParse(s, out json)) { ProjectRuntime.Inst.DispatchRuntimeCode(() => { for (int i = 0; i < faces.Length().Value; ++i) { faces.Get(i).SetProperty(JavaScriptPropertyId.FromString("name"), JavaScriptValue.FromString("Unknown"), true); } callback.CallFunction(callback, faces); callback.Release(); faces.Release(); }); return; } var responses = json.GetNamedArray("ResponsePerFace"); var names = new List <string>(); for (int i = 0; i < responses.Count; ++i) { var faceResponse = responses.GetObjectAt((uint)i); names.Add(faceResponse.GetNamedString("FaceRecognition")); } ProjectRuntime.Inst.DispatchRuntimeCode(() => { for (int i = 0; i < faces.Length().Value; ++i) { faces.Get(i).SetProperty(JavaScriptPropertyId.FromString("name"), JavaScriptValue.FromString(names[i]), true); } callback.CallFunction(callback, faces); callback.Release(); faces.Release(); }); }); }
public void AddCallback(JavaScriptValue callback) { if (callback.ValueType != JavaScriptValueType.Function) { throw new ArgumentException(); } callback.AddRef(); callbacks.Add(callback); }
public static string SetTimeout(JavaScriptValue callback, int delay) { callback.AddRef(); // call Release later string guid = Guid.NewGuid().ToString(); timeoutTimers[guid] = new TimerCallback(callback, delay); return(guid); }
private static void addOneUpdateHook(JavaScriptValue fn) { if (fn.ValueType != JavaScriptValueType.Function) { throw new Exception("Argument passed to addOneUpdateHook must be a function"); } fn.AddRef(); oneUpdateCallbacks.Enqueue(fn); }
private Guid addCallback(JavaScriptValue value, CancellationTokenSource source) { Guid result = Guid.NewGuid(); ServiceNode.WithContext(() => { value.AddRef();//hold the callback function }); list.Add(result, new Tuple <JavaScriptValue, CancellationTokenSource>(value, source)); return(result); }
GenericWrapper(Type type) { this.type = type; if (!type.IsGenericTypeDefinition) { throw new ChakraSharpException("Generic definition only"); } thisPtr = GCHandle.Alloc(this); mainValueSrc = body; mainValue = JavaScriptValue.CreateFunction(mainValueSrc, GCHandle.ToIntPtr(thisPtr)); mainValue.AddRef(); }
/// <summary> /// A promise continuation callback. /// </summary> /// <remarks> /// The host can specify a promise continuation callback in <c>JsSetPromiseContinuationCallback</c>. If /// a script creates a task to be run later, then the promise continuation callback will be called with /// the task and the task should be put in a FIFO queue, to be run when the current script is /// done executing. /// </remarks> /// <param name="task">The task, represented as a JavaScript function.</param> /// <param name="callbackState">The data argument to be passed to the callback.</param> /// <see cref="JavaScriptPromiseContinuationCallback"></see> private void PromiseContinuationCallback(JavaScriptValue task, IntPtr callbackState) { task.AddRef(); try { task.CallFunction(JavaScriptValue.GlobalObject); } finally { task.Release(); } }
private static string addUpdateHook(JavaScriptValue fn) { if (fn.ValueType != JavaScriptValueType.Function) { throw new Exception("Argument passed to addUpdateHook must be a function"); } string id = Guid.NewGuid().ToString(); fn.AddRef(); updateCallbacks[id] = fn; return(id); }
public JavaScriptValue GetJavaScriptValue() { if (!thisPtr.IsAllocated) { thisPtr = GCHandle.Alloc(this); } if (!jsvalue.IsValid) { jsvalueSrc = Wrap(); jsvalue = JavaScriptValue.CreateFunction(jsvalueSrc, GCHandle.ToIntPtr(thisPtr)); jsvalue.AddRef(); } return(jsvalue); }
internal void SetJSSource(JavaScriptValue value, IContextSwitchService context) { if (JSSource.IsValid) { throw new InvalidOperationException("cannot set jsvalue twice"); } if (!value.IsValid) { throw new ArgumentException("not a valid javascriptvalue", nameof(value)); } value.AddRef(); JSSource = value; releaseJSValue = new Action(() => { context.With(() => value.Release()); }); }
public static void Register(JavaScriptContext context) { var http = JavaScriptValue.CreateObject(); JavaScriptValue.GlobalObject.SetProperty("http", http); http.SetProperty( "get", Bridge.CreateFunction((args) => { string url = args[1].ToString(); JavaScriptValue callback = args[2]; if (callback.ValueType != JavaScriptValueType.Function) { throw new Exception("arg 2 not function"); } bool wantsArrayBuffer = args.Length > 3 ? args[3].ToBoolean() : false; callback.AddRef(); // call Release later! Engine.instance.StartCoroutine(HttpGet(url, MakeHttpCallback(callback, wantsArrayBuffer))); })); // http.get http.SetProperty( "post", Bridge.CreateFunction((args) => { string url = args[1].ToString(); string postData = args[2].ToString(); JavaScriptValue callback = args[3]; if (callback.ValueType != JavaScriptValueType.Function) { throw new Exception("arg 2 not function"); } bool wantsArrayBuffer = args.Length > 4 ? args[4].ToBoolean() : false; callback.AddRef(); // call Release later! Engine.instance.StartCoroutine(HttpPost(url, postData, MakeHttpCallback(callback, wantsArrayBuffer))); })); // http.post } // Register
public FunctionLease(JavaScriptNativeFunction function) { Function = JavaScriptValue.CreateFunction(function); Function.AddRef(); _handle = GCHandle.Alloc(function); }
/// <summary> /// Creates and caches a multicast delegate wrapper which forwards parameters into the JS /// callback. /// </summary> /// <remarks> /// This currently handles well defined delegates (with Invoke). For instance: /// <see cref="Action{T}"/> and <see cref="Func{TResult}"/> work appropriately. /// Some of the parameter handling may need some work (ie: <c>params T[] rest</c>). /// /// This conversion occurs when executing javascript code needs to pass a callback to /// C#. Instead of forcing implementers to use <see cref="JavaScriptNativeFunction"/>, /// we dynamically build the callback methods using the <see cref="Expression"/> utility /// class. Assuming a callback of type <see cref="Func{int, string, float}"/>, the following /// will build an expression tree similar to the following: /// <example> /// <code> /// .Block(JavaScriptValue $returnValue) /// { /// .Try /// { /// .Block() /// { /// $returnValue = .Call .Constant[JavaScriptValue](JavaScriptValue).CallFunction( /// .NewArray JavaScriptValue[] /// { /// .Constant[JavaScriptValue](JavaScriptValue), /// .Call .JsInterop.ToJsObject((object)$arg1_0, .Constant[Type](int)), /// .Call .JsInterop.ToJsObject($arg2_1, .Constant[Type](string)) /// }); /// (float) .Call JsInterop.ToJsObject($returnValue, .Constant[Type](float)) /// } /// } /// .Catch (Exception $e) /// { /// .Block() /// { /// .Call JavaScriptContext.SetException(.Call JavaScriptValue.CreateError(.Call JavaScriptValue.FromString($e.Message))); /// .Default(float) /// } /// } /// .Finally /// { /// .Call .Constant[.JavaScriptValue](.JavaScriptValue).Release() /// } /// } /// </code> /// </example> /// </remarks> private object ToMulticastDelegate(JavaScriptValue arg, Type toType) { // Get the JS function reference pointer, and determine if we've adapted this function to a host delegate before. // If so, return the cached expression. This also ensures that the delegate passed out stays consistent. var fnReference = arg.Reference; if (_delegateCache.ContainsKey(fnReference)) { return(_delegateCache[fnReference]); } var method = toType.GetMethod("Invoke"); if (null == method) { throw new Exception($"Delegate/Function type must contain an Invoke method."); } var parameters = method.GetParameters(); var funcLength = arg.GetProperty(JavaScriptPropertyId.FromString("length")).ToInt32(); if (parameters.Length != funcLength) { throw new Exception($"Host function parameters: {parameters.Length} does not match JS parameters: {funcLength}"); } // Target Return Type var returnType = method.ReturnType; // Increase reference count to ensure function doesn't get GC'd // Expression Body will Release() the reference after calling. arg.AddRef(); // Create Parameter Expressions for Invoke Parameters, then wrap in conversion expressions var parameterExpressions = ExpressionHelper.ToParameterExpressions(parameters); var convertedParameters = ParametersToJsValueParameters(parameterExpressions); // Define the constant expression for the JS Func argument var jsFunc = Expression.Constant(arg, typeof(JavaScriptValue)); var paramsArray = Expression.NewArrayInit(typeof(JavaScriptValue), convertedParameters); // Define a JavaScriptValue return value and assign it to the result of calling the JS Function var jsReturn = Expression.Variable(typeof(JavaScriptValue), "returnValue"); var assignJsReturn = Expression.Assign(jsReturn, Expression.Call(jsFunc, JsValueCallFunctionInfo, paramsArray)); // Call the ToHostObject() method passing in the return value and return type // Then, cast the resulting object to the return type var convertCall = Expression.Call(Expression.Constant(this), ConvertMethodInfo, jsReturn, Expression.Constant(returnType)); var conversionExpr = ExpressionHelper.ConvertExpression(convertCall, returnType); // Block Expression setting JavaScriptValue variable, then converting to correct host type var callAndConvert = Expression.Block(assignJsReturn, conversionExpr); // ------------------------------------------------------------------------------- // Wrap the entire call in a try/catch/finally where we execute the callAndConvert // in the try, the function release in the finally, and handle Js Exceptions in Catch // Setup Exception.Message extraction var exceptionParam = Expression.Parameter(typeof(Exception), "e"); var messageProp = Expression.Call(JsExtractErrorInfo, exceptionParam); // JavaScriptContext.SetException(JavaScriptValue.FromString(e.Message)); var message = Expression.Call(JsValueFromString, messageProp); var fromString = Expression.Call(JsValueCreateError, message); var setJsException = Expression.Call(JsContextSetException, fromString); var assignAndBody = Expression.Block(new[] { jsReturn }, Expression.TryCatch(callAndConvert, ExpressionHelper.CatchBlock(exceptionParam, setJsException, returnType))); var hostFn = Expression.Lambda(toType, assignAndBody, parameterExpressions).Compile(); // Add to Delegate Cache for the reference // TODO: Look into hooking this into the GC management in JsBinder _delegateCache[arg.Reference] = hostFn; return(hostFn); }
/// <summary> /// Creates a new safe handle for the JS Value. /// </summary> public JsValueHolder(JavaScriptValue value, JsContextScope scope) : base(value.Reference, true) { _value = value; _value.AddRef(); }
public void GetEmotionForFaces(JavaScriptValue faces, JavaScriptValue callback) { if (RecognitionServer.Inst.IsBusy) { return; } var boundList = new List <BitmapBounds>(); for (int i = 0; i < faces.Length().Value; ++i) { var jsBounds = faces.Get(i).Get("bounds"); var bounds = new BitmapBounds() { X = (uint)jsBounds.Get("x").ToInt32(), Y = (uint)jsBounds.Get("y").ToInt32(), Width = (uint)jsBounds.Get("width").ToInt32(), Height = (uint)jsBounds.Get("height").ToInt32() }; boundList.Add(bounds); } int frameID = faces.Get(0).Get("frame").Get("id").ToInt32(); var frame = SceneCameraManager.Inst.GetFrameFromCache(frameID); callback.AddRef(); faces.AddRef(); server.RecognizeEmotions(frame.bitmap, boundList, (s) => { JsonObject json; if (!JsonObject.TryParse(s, out json)) { ProjectRuntime.Inst.DispatchRuntimeCode(() => { var emotions = JavaScriptValue.CreateArray(0); var pushFunc = emotions.GetProperty(JavaScriptPropertyId.FromString("push")); for (var i = 0; i < faces.Length().Value; ++i) { pushFunc.CallFunction(faces, JavaScriptValue.FromString("Unknown")); } callback.CallFunction(callback, faces); callback.Release(); faces.Release(); }); return; } var responses = json.GetNamedArray("ResponsePerFace"); ProjectRuntime.Inst.DispatchRuntimeCode(() => { var emotions = JavaScriptValue.CreateArray(0); var pushFunc = emotions.GetProperty(JavaScriptPropertyId.FromString("push")); for (int i = 0; i < faces.Length().Value; ++i) { var emotion = responses.GetObjectAt((uint)i).GetNamedString("Emotion"); pushFunc.CallFunction(emotions, JavaScriptValue.FromString(emotion)); } callback.CallFunction(callback, emotions); callback.Release(); faces.Release(); }); }); }
public JavaScriptValue CreateQuery(string[] components, JavaScriptValue callback) { Array.Sort(components, StringComparer.InvariantCulture); var key = string.Join("_", components); if (!queryRefs.ContainsKey(key)) { var componentTypes = new ComponentType[components.Length]; var offsetMap = new Dictionary <string, int>(); //First slot is designated for entity reference offsetMap.Add("Entity", 0); var offset = UnsafeUtility.SizeOf <Entity>(); for (var i = 0; i < components.Length; i++) { var factory = JSTypeFactories.GetFactory(components[i]); componentTypes[i] = factory.ReadComponentType; offsetMap.Add(components[i], offset); offset += factory.ComponentSize; } var q = GetEntityQuery(componentTypes); callback.AddRef(); queryRefs.Add(key, new QueryData { HasData = false, Query = q, Components = components, OffsetMap = offsetMap, SlotSize = offset, OnChangeCallback = callback, ComponentTypes = componentTypes }); } var getSizeFunction = JavaScriptValue.CreateFunction("getSize", (callee, call, arguments, count, data) => { var currentQueryData = arguments[0].ObjectFromJavaScriptValue <QueryData>(); return(JavaScriptValue.FromInt32(currentQueryData.Size)); }); var getVersionFunction = JavaScriptValue.CreateFunction("getVersion", (callee, call, arguments, count, data) => { var currentQueryData = arguments[0].ObjectFromJavaScriptValue <QueryData>(); unsafe { var ptr = (int *)currentQueryData.DataPtr; return(JavaScriptValue.FromInt32(*ptr)); } }); var getHasDataFunction = JavaScriptValue.CreateFunction("getHasData", (callee, call, arguments, count, data) => { var currentQueryData = arguments[0].ObjectFromJavaScriptValue <QueryData>(); return(JavaScriptValue.FromBoolean(currentQueryData.HasData)); }); var getElementAtFunction = JavaScriptValue.CreateFunction("getElementAt", (callee, call, arguments, count, data) => { var currentQueryData = arguments[0].ObjectFromJavaScriptValue <QueryData>(); if (arguments.Length < 3 || arguments[1].ValueType != JavaScriptValueType.String || arguments[2].ValueType != JavaScriptValueType.Number || currentQueryData == null || currentQueryData.IsDisposed || !currentQueryData.HasData) { return(JavaScriptValue.Null); } var slot = arguments[1].ToString(); if (!currentQueryData.OffsetMap.ContainsKey(slot)) { return(JavaScriptValue.Null); } if (arguments[2].ToInt32() >= currentQueryData.Size) { return(JavaScriptValue.Null); } var indexInArray = currentQueryData.SlotSize * arguments[2].ToInt32(); var slotIndex = currentQueryData.OffsetMap[slot]; var factory = JSTypeFactories.GetFactory(slot); if (!JavaScriptContext.Current.IsValid) { return(JavaScriptValue.Null); } unsafe { var ptr = (byte *)currentQueryData.DataPtr + HeaderDataOffset + indexInArray + slotIndex; var output = UnsafeUtility.Malloc(factory.ComponentSize, 4, Allocator.Persistent); UnsafeUtility.MemCpy(output, ptr, factory.ComponentSize); return(factory.CreateJsObjectForNative(output, true)); } }); var disposeFunction = JavaScriptValue.CreateFunction("dispose", (callee, call, arguments, count, data) => { var currentQueryData = arguments[0].ObjectFromJavaScriptValue <QueryData>(); currentQueryData.Dispose(); return(JavaScriptValue.Undefined); }); var queryData = queryRefs[key]; var handle = GCHandle.Alloc(queryData); var p = GCHandle.ToIntPtr(handle); var ret = JavaScriptValue.CreateExternalObject(p, Finalizer); ret.SetProperty(JavaScriptPropertyId.FromString("getSize"), getSizeFunction, true); ret.SetProperty(JavaScriptPropertyId.FromString("hasData"), getHasDataFunction, true); ret.SetProperty(JavaScriptPropertyId.FromString("getElementAt"), getElementAtFunction, true); ret.SetProperty(JavaScriptPropertyId.FromString("dispose"), disposeFunction, true); ret.SetProperty(JavaScriptPropertyId.FromString("getVersion"), getVersionFunction, true); return(ret); }
private JavaScriptValue AddRef(JavaScriptValue value) { value.AddRef(); return(value); }
private static void promiseContinuationCallback(JavaScriptValue task, IntPtr callbackState) { taskQueue.Enqueue(task); task.AddRef(); }
TypeWrapper(Type type) { TypeWrapper baseTypeWrapper = null; if (type.BaseType != null) { baseTypeWrapper = TypeWrapper.Wrap(type.BaseType); } this.type = type; var ctors = type.GetConstructors(); thisPtr = GCHandle.Alloc(this); if (ctors.Length == 0) { constructorValue = JavaScriptValue.CreateFunction(NoConstructorDg, GCHandle.ToIntPtr(thisPtr)); } else if (ctors.Length == 1) { var ctorw = ConstructorWrapper.Wrap(ctors[0]); constructorValue = ctorw.GetJavaScriptValue(); ctorWrapper = ctorw; } else { var os = new OverloadSelector(); foreach (var m in ctors) { os.AppendMethod(m); } constructorValue = os.GetJavaScriptValue(); ctorWrapper = os; } constructorValue.AddRef(); prototypeValue = JavaScriptValue.CreateObject(); prototypeValue.AddRef(); typePtr = GCHandle.Alloc(type); constructorValue.SetIndexedProperty(JavaScriptValue.FromString("_clrtypevalue"), JavaScriptValue.CreateExternalObject(GCHandle.ToIntPtr(typePtr), FreeDg)); // statics ctorStr = type.FullName; constructorValue.SetIndexedProperty(JavaScriptValue.FromString("toString"), JavaScriptValue.CreateFunction(InternalUtil.GetSavedStringDg, GCHandle.ToIntPtr(GCHandle.Alloc(ctorStr)))); AssignMethodProc(constructorValue, type.GetMethods(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Static)); AssignFieldProc(constructorValue, type.GetFields(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Static)); AssignPropertyProc(constructorValue, type.GetProperties(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Static)); // instances prototypeStr = type.FullName + " Instance"; prototypeValue.SetIndexedProperty(JavaScriptValue.FromString("toString"), JavaScriptValue.CreateFunction(InternalUtil.GetSavedStringDg, GCHandle.ToIntPtr(GCHandle.Alloc(prototypeStr)))); AssignMethodProc(prototypeValue, type.GetMethods(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance)); AssignFieldProc(prototypeValue, type.GetFields(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance)); AssignPropertyProc(prototypeValue, type.GetProperties(BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance)); constructorValue.SetIndexedProperty(JavaScriptValue.FromString("prototype"), prototypeValue); if (baseTypeWrapper != null) { constructorValue.Prototype = baseTypeWrapper.constructorValue; prototypeValue.Prototype = baseTypeWrapper.prototypeValue; } }