private async void _Pending(Task task, ScriptContext context, JSValue[] resolving_funcs) { var safeRelease = new SafeRelease(context).Append(resolving_funcs); await task; if (!context.IsValid()) { return; } var ctx = (JSContext)context; object result = null; var taskType = task.GetType(); if (taskType.IsGenericType && taskType.GetGenericTypeDefinition() == typeof(Task <>)) { try { result = taskType.GetProperty("Result").GetValue(task); } catch (Exception exception) { context.GetLogger()?.WriteException(exception); } } var backVal = Binding.Values.js_push_classvalue(ctx, result); if (backVal.IsException()) { ctx.print_exception(); safeRelease.Release(); return; } var argv = new[] { backVal }; var rval = JSApi.JS_Call(ctx, resolving_funcs[0], JSApi.JS_UNDEFINED, 1, argv); JSApi.JS_FreeValue(ctx, backVal); if (rval.IsException()) { ctx.print_exception(); safeRelease.Release(); return; } JSApi.JS_FreeValue(ctx, rval); safeRelease.Release(); context.GetRuntime().ExecutePendingJob(); }
private IEnumerator _Pending(IEnumerator enumerator, ScriptContext context, JSValue[] resolving_funcs) { var safeRelease = new SafeRelease(context).Append(resolving_funcs); while (enumerator.MoveNext()) { var current = enumerator.Current; if (current is UnityEngine.YieldInstruction) { yield return(current); } yield return(null); } if (!context.IsValid()) { yield break; } var ctx = (JSContext)context; var backVal = Binding.Values.js_push_var(ctx, enumerator.Current); if (backVal.IsException()) { ctx.print_exception(); safeRelease.Release(); yield break; } var argv = new[] { backVal }; var rval = JSApi.JS_Call(ctx, resolving_funcs[0], JSApi.JS_UNDEFINED, 1, argv); JSApi.JS_FreeValue(ctx, backVal); if (rval.IsException()) { ctx.print_exception(); safeRelease.Release(); yield break; } JSApi.JS_FreeValue(ctx, rval); safeRelease.Release(); context.GetRuntime().ExecutePendingJob(); }
private IEnumerator _Pending(YieldInstruction instruction, ScriptContext context, JSValue[] resolving_funcs) { var safeRelease = new SafeRelease(context).Append(resolving_funcs); yield return(instruction); if (!context.IsValid()) { yield break; } var ctx = (JSContext)context; var backVal = Binding.Values.js_push_classvalue(ctx, instruction); if (backVal.IsException()) { ctx.print_exception(); safeRelease.Release(); yield break; } var argv = new[] { backVal }; var rval = JSApi.JS_Call(ctx, resolving_funcs[0], JSApi.JS_UNDEFINED, 1, argv); JSApi.JS_FreeValue(ctx, backVal); if (rval.IsException()) { ctx.print_exception(); safeRelease.Release(); yield break; } JSApi.JS_FreeValue(ctx, rval); safeRelease.Release(); context.GetRuntime().ExecutePendingJob(); }
// return promise public JSValue Yield(ScriptContext context, object awaitObject) { if (awaitObject is System.Threading.Tasks.Task) { var resolving_funcs = new[] { JSApi.JS_UNDEFINED, JSApi.JS_UNDEFINED }; var promise = JSApi.JS_NewPromiseCapability(context, resolving_funcs); var safeRelease = new SafeRelease(context).Append(resolving_funcs); var task = awaitObject as System.Threading.Tasks.Task; var runtime = context.GetRuntime(); #if JSB_COMPATIBLE task.ContinueWith(antecedent => runtime.EnqueueAction(_OnTaskCompleted, new JSTaskCompletionArgs(task, safeRelease))); #else task.GetAwaiter().OnCompleted(() => { runtime.EnqueueAction(_OnTaskCompleted, new JSTaskCompletionArgs(task, safeRelease)); }); #endif return(promise); } #if !JSB_UNITYLESS else if (awaitObject is IEnumerator) { //TODO: 合并 IEnumerator 和 YieldInstruction 写法 GetUnityContext(); if (_mb == null) { return(JSApi.JS_ThrowInternalError(context, "no MonoBehaviour for Coroutines")); } if (_mainThreadId != Thread.CurrentThread.ManagedThreadId) { return(JSApi.JS_ThrowInternalError(context, "not supported on background thread")); } var resolving_funcs = new[] { JSApi.JS_UNDEFINED, JSApi.JS_UNDEFINED }; var promise = JSApi.JS_NewPromiseCapability(context, resolving_funcs); _mb.StartCoroutine(_Pending(awaitObject as IEnumerator, context, resolving_funcs)); return(promise); } else { GetUnityContext(); if (_mb == null) { return(JSApi.JS_ThrowInternalError(context, "no MonoBehaviour for Coroutines")); } if (_mainThreadId != Thread.CurrentThread.ManagedThreadId) { return(JSApi.JS_ThrowInternalError(context, "not supported on background thread")); } var resolving_funcs = new[] { JSApi.JS_UNDEFINED, JSApi.JS_UNDEFINED }; var promise = JSApi.JS_NewPromiseCapability(context, resolving_funcs); _mb.StartCoroutine(_Pending(awaitObject as UnityEngine.YieldInstruction, context, resolving_funcs)); return(promise); } #else return(JSApi.JS_ThrowInternalError(context, "not supported await object")); #endif // !JSB_UNITYLESS }
public JSTaskCompletionArgs(System.Threading.Tasks.Task task, SafeRelease safeRelease) { this.task = task; this.safeRelease = safeRelease; }