diff --git a/Assets/Examples/Source/BasicRun.cs b/Assets/Examples/Source/BasicRun.cs index 335e6079..684a5441 100644 --- a/Assets/Examples/Source/BasicRun.cs +++ b/Assets/Examples/Source/BasicRun.cs @@ -1,6 +1,7 @@ using QuickJS; using QuickJS.Native; using System.Collections; +using System.Collections.Generic; namespace Example { @@ -8,27 +9,82 @@ namespace Example public class BasicRun : MonoBehaviour { - public bool execRuntime; + public enum RunCase + { + None, + QuickJSCodebase, + Codegen, + } + public RunCase runCase; unsafe void Start() { - if (execRuntime) + switch (runCase) { - var rt = JSApi.JS_NewRuntime(); - JSMemoryUsage s; - JSApi.JS_ComputeMemoryUsage(rt, &s); - Debug.Log($"test {rt}: {s.malloc_count} {s.malloc_size} {s.malloc_limit}"); - var ctx = JSApi.JS_NewContext(rt); - Debug.Log("test:" + ctx); + case RunCase.QuickJSCodebase: + { + var rt = JSApi.JS_NewRuntime(); + JSMemoryUsage s; + JSApi.JS_ComputeMemoryUsage(rt, &s); + Debug.Log($"test {rt}: {s.malloc_count} {s.malloc_size} {s.malloc_limit}"); + var ctx = JSApi.JS_NewContext(rt); + Debug.Log("test:" + ctx); + + // // // JSApi.JS_AddIntrinsicOperators(ctx); + // // var obj = JSApi.JS_NewObject(ctx); + // // JSApi.JS_FreeValue(ctx, obj); - // // // JSApi.JS_AddIntrinsicOperators(ctx); - // // var obj = JSApi.JS_NewObject(ctx); - // // JSApi.JS_FreeValue(ctx, obj); + JSApi.JS_FreeContext(ctx); + JSApi.JS_FreeRuntime(rt); + Debug.Log("it's a good day"); + GameObject.CreatePrimitive(PrimitiveType.Cube); + break; + } + case RunCase.Codegen: + { + var options = new Dictionary(); + System.Reflection.MethodInfo Call = null; + using (var p = System.CodeDom.Compiler.CodeDomProvider.CreateProvider("cs", options)) + { + var compilerParameters = new System.CodeDom.Compiler.CompilerParameters(); + compilerParameters.GenerateInMemory = true; + compilerParameters.TreatWarningsAsErrors = false; + compilerParameters.CompilerOptions = "-unsafe"; + compilerParameters.ReferencedAssemblies.Add(typeof(Debug).Assembly.Location); + var result = p.CompileAssemblyFromSource(compilerParameters, @" + using UnityEngine; + namespace _Hidden { + public static class Foo { + public static unsafe void Call(ref int a0) { + Debug.Log(""Hello "" + a0); + a0 += 1; + } + } + } + "); + if (result.Errors.HasErrors) + { + foreach (var err in result.Errors) + { + Debug.LogError(err); + } + } + else + { + var Foo = result.CompiledAssembly.GetType("_Hidden.Foo"); + Call = Foo.GetMethod("Call"); + } + } - JSApi.JS_FreeContext(ctx); - JSApi.JS_FreeRuntime(rt); - Debug.Log("it's a good day"); - GameObject.CreatePrimitive(PrimitiveType.Cube); + if (Call != null) + { + var v = 99; + var ps = new object[] { v }; + Call.Invoke(null, ps); + Debug.Log($"Call: {ps[0]}"); + } + break; + } } } } diff --git a/Assets/Examples/Source/DelegateTest.cs b/Assets/Examples/Source/DelegateTest.cs index 613f215d..e84039ea 100644 --- a/Assets/Examples/Source/DelegateTest.cs +++ b/Assets/Examples/Source/DelegateTest.cs @@ -5,10 +5,14 @@ namespace Example { public delegate int WithByRefParametersCallback(int b, ref int a, out int v); + public delegate void WithByRefParametersCallback2(ref UnityEngine.Vector3 v); + [JSType] public class DelegateTest { public WithByRefParametersCallback complexCall; + public WithByRefParametersCallback2 complexCall2; + public void TestComplexCall() { if (complexCall != null) @@ -16,8 +20,17 @@ public void TestComplexCall() int b = 1; int a = 2; int v; + UnityEngine.Debug.Log($"TestComplexCall (before): b={b} a={a}"); int r = complexCall(b, ref a, out v); - UnityEngine.Debug.Log($"TestComplexCall: b={b} a={a} v={v} r={r}"); + UnityEngine.Debug.Log($"TestComplexCall (after): b={b} a={a} v={v} r={r}"); + } + + if (complexCall2 != null) + { + var v = new UnityEngine.Vector3(1f, 2f, 3f); + UnityEngine.Debug.Log($"TestComplexCall2 (before): v={v}"); + complexCall2(ref v); + UnityEngine.Debug.Log($"TestComplexCall2 (after): v={v}"); } } diff --git a/Assets/Examples/Source/Editor/CustomBinding.cs b/Assets/Examples/Source/Editor/CustomBinding.cs index 9a72e10d..2cd97407 100644 --- a/Assets/Examples/Source/Editor/CustomBinding.cs +++ b/Assets/Examples/Source/Editor/CustomBinding.cs @@ -35,8 +35,6 @@ public override void OnPreExporting(BindingManager bindingManager) bindingManager.AddExportedType(typeof(TWrapper)); bindingManager.AddExportedType(typeof(DisposableObject)).SetDisposable(); - bindingManager.CollectRefectedDelegateTemplates(typeof(CustomReflectBindDelegates)); - #if CUSTOM_DEF_FOO && UNITY_EDITOR bindingManager.AddExportedType(typeof(FOO)).AddRequiredDefines("CUSTOM_DEF_FOO", "UNITY_EDITOR") #if CUSTOM_DEF_PROP diff --git a/Assets/Examples/Source/Editor/CustomReflectBindDelegates.cs b/Assets/Examples/Source/Editor/CustomReflectBindDelegates.cs deleted file mode 100644 index e6a580d3..00000000 --- a/Assets/Examples/Source/Editor/CustomReflectBindDelegates.cs +++ /dev/null @@ -1,105 +0,0 @@ -using System.Reflection; -using System; - -namespace Example.Editor -{ - using QuickJS; - using QuickJS.Native; - using QuickJS.Binding; - - /// - /// [TEMP][ONLY REQUIRED IN ReflectBind mode] need to manually write code for delegates which have by-ref parameters - /// - public static class CustomReflectBindDelegates - { - public static unsafe RT Call(QuickJS.ScriptDelegate fn, T1 a1, ref T2 a2, out T3 a3) - { - if (!fn.isValid) - { - throw new Exception("invalid script delegate handle"); - } - var ctx = fn.ctx; - var argv = stackalloc JSValue[3]; - argv[0] = ReflectBindValueOp.js_push_tvar(ctx, a1); - if (argv[0].IsException()) - { - throw new Exception(ctx.GetExceptionString()); - } - argv[1] = JSApi.JS_NewObject(ctx); - if (argv[1].IsException()) - { - JSApi.JS_FreeValue(ctx, argv[0]); - throw new Exception(ctx.GetExceptionString()); - } - var context = ScriptEngine.GetContext(ctx); - JSApi.JS_SetProperty(ctx, argv[1], context.GetAtom("value"), ReflectBindValueOp.js_push_tvar(ctx, a2)); - argv[2] = JSApi.JS_NewObject(ctx); - if (argv[2].IsException()) - { - JSApi.JS_FreeValue(ctx, argv[0]); - JSApi.JS_FreeValue(ctx, argv[1]); - throw new Exception(ctx.GetExceptionString()); - } - var rval = fn.Invoke(ctx, 3, argv); - if (rval.IsException()) - { - JSApi.JS_FreeValue(ctx, argv[0]); - JSApi.JS_FreeValue(ctx, argv[1]); - JSApi.JS_FreeValue(ctx, argv[2]); - throw new Exception(ctx.GetExceptionString()); - } - var refVal1 = Values.js_read_wrap(ctx, argv[1]); - if (refVal1.IsException()) - { - JSApi.JS_FreeValue(ctx, rval); - JSApi.JS_FreeValue(ctx, argv[0]); - JSApi.JS_FreeValue(ctx, argv[1]); - JSApi.JS_FreeValue(ctx, argv[2]); - throw new Exception(ctx.GetExceptionString()); - } - if (!ReflectBindValueOp.js_get_tvar(ctx, refVal1, out a2)) - { - JSApi.JS_FreeValue(ctx, rval); - JSApi.JS_FreeValue(ctx, argv[0]); - JSApi.JS_FreeValue(ctx, argv[1]); - JSApi.JS_FreeValue(ctx, argv[2]); - JSApi.JS_FreeValue(ctx, refVal1); - throw new ParameterException(typeof(CustomReflectBindDelegates), "FuncCall", typeof(T2), 1); - } - JSApi.JS_FreeValue(ctx, refVal1); - var refVal2 = Values.js_read_wrap(ctx, argv[2]); - if (refVal2.IsException()) - { - JSApi.JS_FreeValue(ctx, rval); - JSApi.JS_FreeValue(ctx, argv[0]); - JSApi.JS_FreeValue(ctx, argv[1]); - JSApi.JS_FreeValue(ctx, argv[2]); - throw new Exception(ctx.GetExceptionString()); - } - if (!ReflectBindValueOp.js_get_tvar(ctx, refVal2, out a3)) - { - JSApi.JS_FreeValue(ctx, rval); - JSApi.JS_FreeValue(ctx, argv[0]); - JSApi.JS_FreeValue(ctx, argv[1]); - JSApi.JS_FreeValue(ctx, argv[2]); - JSApi.JS_FreeValue(ctx, refVal2); - throw new ParameterException(typeof(CustomReflectBindDelegates), "FuncCall", typeof(T3), 2); - } - JSApi.JS_FreeValue(ctx, refVal2); - RT ret0; - var succ = ReflectBindValueOp.js_get_tvar(ctx, rval, out ret0); - JSApi.JS_FreeValue(ctx, rval); - JSApi.JS_FreeValue(ctx, argv[0]); - JSApi.JS_FreeValue(ctx, argv[1]); - JSApi.JS_FreeValue(ctx, argv[2]); - if (succ) - { - return ret0; - } - else - { - throw new Exception("js exception caught"); - } - } - } -} \ No newline at end of file diff --git a/Assets/Examples/Source/Editor/CustomReflectBindDelegates.cs.meta b/Assets/Examples/Source/Editor/CustomReflectBindDelegates.cs.meta deleted file mode 100644 index 8b887746..00000000 --- a/Assets/Examples/Source/Editor/CustomReflectBindDelegates.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 628df448a7d9a5740a73d77ded31f64b -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Generated/Typings/jsb.autogen.d.ts b/Assets/Generated/Typings/jsb.autogen.d.ts index b3871162..3a229d75 100644 --- a/Assets/Generated/Typings/jsb.autogen.d.ts +++ b/Assets/Generated/Typings/jsb.autogen.d.ts @@ -19705,6 +19705,7 @@ declare module "Example" { declare module "Example" { import * as jsb from "jsb"; import { Object, Array } from "System"; + import { Vector3 } from "UnityEngine"; class DelegateTest extends Object { constructor() TestComplexCall(): void @@ -19723,6 +19724,9 @@ declare module "Example" { complexCall(op: "get"): (b: number, a: jsb.Ref, v: jsb.Out) => number complexCall(op: "add" | "remove" | "set", fn?: (b: number, a: jsb.Ref, v: jsb.Out) => number): void complexCall(op: "add" | "remove" | "set" | "get", fn?: (b: number, a: jsb.Ref, v: jsb.Out) => number): (b: number, a: jsb.Ref, v: jsb.Out) => number | void + complexCall2(op: "get"): (v: jsb.Ref) => void + complexCall2(op: "add" | "remove" | "set", fn?: (v: jsb.Ref) => void): void + complexCall2(op: "add" | "remove" | "set" | "get", fn?: (v: jsb.Ref) => void): (v: jsb.Ref) => void | void actionFieldRW(op: "get"): () => void actionFieldRW(op: "add" | "remove" | "set", fn?: () => void): void actionFieldRW(op: "add" | "remove" | "set" | "get", fn?: () => void): () => void | void diff --git a/Assets/jsb/Source/Binding/Editor/BindingCallback/IBindingCallback.cs b/Assets/jsb/Source/Binding/Editor/BindingCallback/IBindingCallback.cs index 8c026ea7..4274d1d8 100644 --- a/Assets/jsb/Source/Binding/Editor/BindingCallback/IBindingCallback.cs +++ b/Assets/jsb/Source/Binding/Editor/BindingCallback/IBindingCallback.cs @@ -7,10 +7,12 @@ namespace QuickJS.Binding { public interface IBindingCallback { + void Begin(BindingManager bindingManager); void BeginStaticModule(string moduleName, int capacity); void AddTypeReference(string moduleName, TypeBindingInfo typeBindingInfo); void EndStaticModule(string moduleName); void AddDelegate(DelegateBridgeBindingInfo bindingInfo); + void End(); } } diff --git a/Assets/jsb/Source/Binding/Editor/BindingCallback/ReflectBindingCallback.cs b/Assets/jsb/Source/Binding/Editor/BindingCallback/ReflectBindingCallback.cs index 664d725a..6ba1e981 100644 --- a/Assets/jsb/Source/Binding/Editor/BindingCallback/ReflectBindingCallback.cs +++ b/Assets/jsb/Source/Binding/Editor/BindingCallback/ReflectBindingCallback.cs @@ -9,6 +9,7 @@ namespace QuickJS.Binding public class ReflectBindingCallback : IBindingCallback { private ScriptRuntime _runtime; + private BindingManager _bindingManager; private Module.ProxyModuleRegister _moduleReg; public ReflectBindingCallback(ScriptRuntime runtime) @@ -46,9 +47,18 @@ public ReflectBindingCallback(ScriptRuntime runtime) #endif } + public void Begin(BindingManager bindingManager) + { + _bindingManager = bindingManager; + } + + public void End() + { + } + public void BeginStaticModule(string moduleName, int capacity) { - _moduleReg = _runtime.AddStaticModuleProxy(moduleName); + _moduleReg = _runtime.AddStaticModuleProxy(moduleName); // _moduleReg = new Module.ProxyModuleRegister(_runtime); } @@ -65,11 +75,17 @@ public void EndStaticModule(string moduleName) public void AddDelegate(DelegateBridgeBindingInfo bindingInfo) { var typeDB = _runtime.GetTypeDB(); - var method = bindingInfo.reflect; foreach (var delegateType in bindingInfo.types) { - typeDB.AddDelegate(delegateType, method); + if (!typeDB.ContainsDelegate(delegateType)) + { + var method = _bindingManager.GetReflectedDelegateMethod(bindingInfo.returnType, bindingInfo.parameters); + if (method != null) + { + typeDB.AddDelegate(delegateType, method); + } + } } } diff --git a/Assets/jsb/Source/Binding/Editor/BindingManager.cs b/Assets/jsb/Source/Binding/Editor/BindingManager.cs index 89719972..f2a6a65f 100644 --- a/Assets/jsb/Source/Binding/Editor/BindingManager.cs +++ b/Assets/jsb/Source/Binding/Editor/BindingManager.cs @@ -648,7 +648,7 @@ public void CollectDelegate(Type delegateType) } var delegateBindingInfo = new DelegateBridgeBindingInfo(returnType, parameters, defs); delegateBindingInfo.types.Add(delegateType); - delegateBindingInfo.reflect = GetReflect(returnType, parameters); + delegateBindingInfo.reflect = GetReflectedDelegateMethod(returnType, parameters); _exportedDelegates.Add(delegateType, delegateBindingInfo); Info("add delegate: {0} required defines: {1}", delegateType, defs); for (var i = 0; i < parameters.Length; i++) @@ -685,7 +685,7 @@ public bool AddReflectedDelegateTemplate(MethodInfo methodInfo) return false; } - public static bool IsGenericMethodSuitable(MethodInfo methodTemplate, int startIndex, ParameterInfo[] parameters, Type returnType) + public static bool IsDelegateMethodSuitable(MethodInfo methodTemplate, int startIndex, ParameterInfo[] parameters, Type returnType) { if (methodTemplate.ReturnType != returnType && methodTemplate.ReturnType == typeof(void)) { @@ -712,30 +712,104 @@ public static bool IsGenericMethodSuitable(MethodInfo methodTemplate, int startI return true; } - public MethodInfo GetReflectedDelegateTemplate(List list, ParameterInfo[] parameters, Type returnType) + public MethodInfo GenerateReflectedDelegateMethod(List templates, Type returnType, ParameterInfo[] parameters) { - for (int i = 0, count = list.Count; i < count; ++i) + for (int i = 0, count = templates.Count; i < count; ++i) { - var methodTemplate = list[i]; - if (IsGenericMethodSuitable(methodTemplate, 1, parameters, returnType)) + var template = templates[i]; + if (IsDelegateMethodSuitable(template, 1, parameters, returnType)) { - if (!methodTemplate.IsGenericMethodDefinition) + if (!template.IsGenericMethodDefinition) { - return methodTemplate; + return template; } var parametersTypes = from p in parameters select p.ParameterType; - return methodTemplate.MakeGenericMethod( + return template.MakeGenericMethod( returnType != typeof(void) ? AppendEnumerable(parametersTypes, returnType) : parametersTypes.ToArray()); } } + // dynamically emit method + var emittedMethod = _EmitDelegateMethod(returnType, parameters); + if (emittedMethod != null) + { + templates.Add(emittedMethod); + return emittedMethod; + } + + return null; + } + + public MethodInfo _EmitDelegateMethod(Type returnType, ParameterInfo[] parameters) + { + try + { + var cg = new CodeGenerator(this, TypeBindingFlags.Default); + var ns = "_Generated" + Guid.NewGuid().ToString().Replace("-", ""); + var className = CodeGenerator.NameOfDelegates; + var assemblies = new HashSet(); + + if (returnType != null) + { + assemblies.Add(returnType.Assembly); + } + foreach (var parameterAssembly in from p in parameters select p.ParameterType.Assembly) + { + assemblies.Add(parameterAssembly); + } + assemblies.Add(typeof(Values).Assembly); + assemblies.Add(typeof(Exception).Assembly); + using (new CSNamespaceCodeGen(cg, ns)) + { + cg.cs.AppendLine("public static class " + className); + cg.cs.AppendLine("{"); + cg.cs.AddTabLevel(); + using (new DelegateCodeGen(cg, "_Generated", returnType, parameters)) + { + } + cg.cs.DecTabLevel(); + cg.cs.AppendLine("}"); + } + + var source = cg.cs.Submit(); + + using (var codeDomProvider = System.CodeDom.Compiler.CodeDomProvider.CreateProvider("cs")) + { + var compilerParameters = new System.CodeDom.Compiler.CompilerParameters(); + compilerParameters.GenerateInMemory = true; + compilerParameters.TreatWarningsAsErrors = false; + compilerParameters.CompilerOptions = "-unsafe"; + compilerParameters.ReferencedAssemblies.AddRange((from a in assemblies select a.Location).ToArray()); + var result = codeDomProvider.CompileAssemblyFromSource(compilerParameters, source); + + if (result.Errors.HasErrors) + { + Error(string.Format("failed to compile source [{0} errors]", result.Errors.Count)); + foreach (var err in result.Errors) + { + Error(err.ToString()); + } + } + else + { + var Class = result.CompiledAssembly.GetType(ns + "." + className); + return Class?.GetMethod("_Generated"); + } + } + // UnityEngine.Debug.Log("gen: \n" + cg.cs.Submit()); + } + catch (Exception exception) + { + Error(exception); + } + return null; } - public MethodInfo GetReflect(Type returnType, ParameterInfo[] parameters) + public MethodInfo GetReflectedDelegateMethod(Type returnType, ParameterInfo[] parameters) { // skip unsupported types if (Binding.Values.IsVarargParameter(parameters)) @@ -743,15 +817,13 @@ public MethodInfo GetReflect(Type returnType, ParameterInfo[] parameters) return null; } + List templates = null; var argc = parameters.Length; - List genMethods = null; - - if (_reflectedDelegateTemplates.TryGetValue(argc, out genMethods)) + if (!_reflectedDelegateTemplates.TryGetValue(argc, out templates)) { - return GetReflectedDelegateTemplate(genMethods, parameters, returnType); + _reflectedDelegateTemplates[argc] = templates = new List(); } - - return null; + return GenerateReflectedDelegateMethod(templates, returnType, parameters); } public static T[] AppendEnumerable(IEnumerable e, T item) @@ -809,11 +881,11 @@ private string GetScriptObjectPropertyGetter(Type type) { if (type.IsPrimitive) { - return "js_get_primitive"; + return "Values.js_get_primitive"; } if (type.IsEnum) { - return "js_get_enumvalue"; + return "Values.js_get_enumvalue"; } if (type.IsGenericType) { @@ -822,29 +894,29 @@ private string GetScriptObjectPropertyGetter(Type type) var gArgs = type.GetGenericArguments(); if (gArgs[0].IsValueType && gArgs[0].IsPrimitive) { - return "js_get_primitive"; + return "Values.js_get_primitive"; } } } - return "js_get_structvalue"; + return "Values.js_get_structvalue"; } if (type == typeof(string)) { - return "js_get_primitive"; + return "Values.js_get_primitive"; } if (type == typeof(object)) { - return "js_get_var"; + return "Values.js_get_var"; } if (type.BaseType == typeof(MulticastDelegate)) { - return "js_get_delegate"; + return "Values.js_get_delegate"; } - return "js_get_classvalue"; + return "Values.js_get_classvalue"; } public string GetScriptObjectPusher(Type type, string ctx, string value) @@ -875,19 +947,19 @@ public string GetScriptObjectPusher(Type type, out string op) if (type == typeof(Delegate) || type.BaseType == typeof(MulticastDelegate)) { - return "js_push_delegate"; + return "Values.js_push_delegate"; } if (type.IsValueType) { if (type.IsPrimitive) { - return "js_push_primitive"; + return "Values.js_push_primitive"; } if (type.IsEnum) { - return "js_push_enumvalue"; + return "Values.js_push_enumvalue"; } if (type.IsGenericType) @@ -898,26 +970,26 @@ public string GetScriptObjectPusher(Type type, out string op) if (gArgs[0].IsValueType && gArgs[0].IsPrimitive) { - return "js_push_primitive"; + return "Values.js_push_primitive"; } } } // op = "ref "; - return "js_push_structvalue"; + return "Values.js_push_structvalue"; } if (type == typeof(string)) { - return "js_push_primitive"; + return "Values.js_push_primitive"; } if (type == typeof(object)) { - return "js_push_var"; + return "Values.js_push_var"; } - return "js_push_classvalue"; + return "Values.js_push_classvalue"; } public string GetTSVariable(string name) @@ -1579,7 +1651,7 @@ public bool IsAssemblyBlocked(Assembly assembly) return true; } } - + return _assemblyBlacklist.Contains(GetSimplifiedAssemblyName(assembly)); } @@ -1813,6 +1885,7 @@ public void Generate(TypeBindingFlags typeBindingFlags) var total = _exportedTypes.Count; cg.Begin(); + _bindingCallback?.Begin(this); foreach (var typeKV in _exportedTypes) { var typeBindingInfo = typeKV.Value; @@ -1917,6 +1990,7 @@ orderby t.tsTypeNaming.jsDepth } } cg.End(); + _bindingCallback?.End(); if (!cancel) { diff --git a/Assets/jsb/Source/Binding/Editor/BindingManager_Log.cs b/Assets/jsb/Source/Binding/Editor/BindingManager_Log.cs index e13c3dd4..8061b434 100644 --- a/Assets/jsb/Source/Binding/Editor/BindingManager_Log.cs +++ b/Assets/jsb/Source/Binding/Editor/BindingManager_Log.cs @@ -1,78 +1,88 @@ -using System; -using System.IO; -using System.Collections.Generic; -using System.Reflection; - -namespace QuickJS.Binding -{ - public partial class BindingManager - { - public void Info(string message) - { - _logWriter?.AppendLine(message); - } - - public void Info(string fmt, object arg1) - { - _logWriter?.AppendLine(fmt, arg1); - } - - public void Info(string fmt, object arg1, string arg2) - { - _logWriter?.AppendLine(fmt, arg1, arg2); - } - - public void Info(string fmt, params object[] args) - { - _logWriter?.AppendLine(fmt, args); - } - - public void Error(string message) - { - _bindingLogger?.LogError(message); - _logWriter?.AppendLine(message); - } - - public void Error(string fmt, object arg1) - { - _bindingLogger?.LogError(string.Format(fmt, arg1)); - _logWriter?.AppendLine(fmt, arg1); - } - - public void Error(string fmt, object arg1, string arg2) - { - _bindingLogger?.LogError(string.Format(fmt, arg1, arg2)); - _logWriter?.AppendLine(fmt, arg1, arg2); - } - - public void Error(string fmt, params object[] args) - { - _bindingLogger?.LogError(string.Format(fmt, args)); - _logWriter?.AppendLine(fmt, args); - } - - public void Warn(string message) - { - _bindingLogger?.LogWarning(message); - _logWriter?.AppendLine(message); - } - - public void Warn(string fmt, object arg1) - { - _bindingLogger?.LogWarning(string.Format(fmt, arg1)); - _logWriter?.AppendLine(fmt, arg1); - } - - public void Warn(string fmt, object arg1, string arg2) - { - _bindingLogger?.LogWarning(string.Format(fmt, arg1, arg2)); - _logWriter?.AppendLine(fmt, arg1, arg2); - } - - public void Warn(string fmt, params object[] args) - { - _bindingLogger?.LogWarning(string.Format(fmt, args)); - _logWriter?.AppendLine(fmt, args); - } - } -} +using System; +using System.IO; +using System.Collections.Generic; +using System.Reflection; + +namespace QuickJS.Binding +{ + public partial class BindingManager + { + public void Info(string message) + { + _logWriter?.AppendLine(message); + } + + public void Info(string fmt, object arg1) + { + _logWriter?.AppendLine(fmt, arg1); + } + + public void Info(string fmt, object arg1, string arg2) + { + _logWriter?.AppendLine(fmt, arg1, arg2); + } + + public void Info(string fmt, params object[] args) + { + _logWriter?.AppendLine(fmt, args); + } + + public void Error(Exception exception) + { + var str = string.Format("{0}\n{1}", exception.Message, exception.StackTrace); + if (exception.InnerException != null) + { + str += string.Format("=== Inner Exception ===\n{0}\n{1}", exception.InnerException.Message, exception.InnerException.StackTrace); + } + Error(str); + } + + public void Error(string message) + { + _bindingLogger?.LogError(message); + _logWriter?.AppendLine(message); + } + + public void Error(string fmt, object arg1) + { + _bindingLogger?.LogError(string.Format(fmt, arg1)); + _logWriter?.AppendLine(fmt, arg1); + } + + public void Error(string fmt, object arg1, string arg2) + { + _bindingLogger?.LogError(string.Format(fmt, arg1, arg2)); + _logWriter?.AppendLine(fmt, arg1, arg2); + } + + public void Error(string fmt, params object[] args) + { + _bindingLogger?.LogError(string.Format(fmt, args)); + _logWriter?.AppendLine(fmt, args); + } + + public void Warn(string message) + { + _bindingLogger?.LogWarning(message); + _logWriter?.AppendLine(message); + } + + public void Warn(string fmt, object arg1) + { + _bindingLogger?.LogWarning(string.Format(fmt, arg1)); + _logWriter?.AppendLine(fmt, arg1); + } + + public void Warn(string fmt, object arg1, string arg2) + { + _bindingLogger?.LogWarning(string.Format(fmt, arg1, arg2)); + _logWriter?.AppendLine(fmt, arg1, arg2); + } + + public void Warn(string fmt, params object[] args) + { + _bindingLogger?.LogWarning(string.Format(fmt, args)); + _logWriter?.AppendLine(fmt, args); + } + } +} diff --git a/Assets/jsb/Source/Binding/Editor/Codegen/CodeGenHelper_DelegateInvoke.cs b/Assets/jsb/Source/Binding/Editor/Codegen/CodeGenHelper_DelegateInvoke.cs index 4d087a24..59c824a0 100644 --- a/Assets/jsb/Source/Binding/Editor/Codegen/CodeGenHelper_DelegateInvoke.cs +++ b/Assets/jsb/Source/Binding/Editor/Codegen/CodeGenHelper_DelegateInvoke.cs @@ -1,209 +1,233 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.IO; -using System.Linq; -using System.Reflection; - -namespace QuickJS.Binding -{ - public class DelegateCodeGen : IDisposable - { - protected CodeGenerator cg; - protected DelegateBridgeBindingInfo delegateBindingInfo; - - private ParameterInfo[] GetInputParameters(ParameterInfo[] parameters) - { - // return parameters.Where(p => !p.IsOut).ToArray(); - return parameters; - } - - public DelegateCodeGen(CodeGenerator cg, DelegateBridgeBindingInfo delegateBindingInfo, int index) - { - this.cg = cg; - this.delegateBindingInfo = delegateBindingInfo; - var inputParameters = GetInputParameters(delegateBindingInfo.parameters); - var nargs = inputParameters.Length; - var retName = this.cg.bindingManager.GetUniqueName(delegateBindingInfo.parameters, "ret"); - var firstArgument = typeof(ScriptDelegate) + " fn"; - var returnTypeName = this.cg.bindingManager.GetCSTypeFullName(delegateBindingInfo.returnType); - var delegateName = CodeGenerator.NameOfDelegates + index; - var arglist = this.cg.bindingManager.GetCSArglistDecl(delegateBindingInfo.parameters); - - foreach (var target in delegateBindingInfo.types) - { - this.cg.cs.AppendLine("[{0}(typeof({1}))]", - this.cg.bindingManager.GetCSTypeFullName(typeof(JSDelegateAttribute)), - this.cg.bindingManager.GetCSTypeFullName(target)); - this.cg.bindingManager.Info("emitting delegate decl: {0}", target); - } - if (!string.IsNullOrEmpty(arglist)) - { - arglist = ", " + arglist; - } - this.cg.cs.AppendLine($"public static unsafe {returnTypeName} {delegateName}({firstArgument}{arglist})"); - this.cg.cs.AppendLine("{"); - this.cg.cs.AddTabLevel(); - this.cg.cs.AppendLine("var ctx = fn.ctx;"); - - if (nargs > 0) - { - var getContext = false; - this.cg.cs.AppendLine("var argv = stackalloc JSValue[{0}];", nargs); - for (var i = 0; i < nargs; i++) - { - var parameter = inputParameters[i]; - if (parameter.ParameterType.IsByRef) - { - if (parameter.IsOut) - { - var pusher = "JSApi.JS_NewObject(ctx)"; - this.cg.cs.AppendLine("argv[{0}] = {1};", i, pusher); - CheckParameterException(i); - } - else - { - var pusher = "JSApi.JS_NewObject(ctx)"; - var value_pusher = this.cg.AppendValuePusher(parameter.ParameterType, parameter.Name); - this.cg.cs.AppendLine("argv[{0}] = {1};", i, pusher); - CheckParameterException(i); - if (!getContext) - { - getContext = true; - cg.cs.AppendLine("var context = ScriptEngine.GetContext(ctx);"); - } - cg.cs.AppendLine("JSApi.JS_SetProperty(ctx, argv[{0}], context.GetAtom(\"value\"), {1});", i, value_pusher); - } - } - else - { - var pusher = this.cg.AppendValuePusher(parameter.ParameterType, parameter.Name); - this.cg.cs.AppendLine("argv[{0}] = {1};", i, pusher); - CheckParameterException(i); - } - } - this.cg.cs.AppendLine("var rval = fn.Invoke(ctx, {0}, argv);", nargs); - } - else - { - this.cg.cs.AppendLine("var rval = fn.Invoke(ctx);"); - } - - CheckReturnValue(nargs); - _WriteBackParameters(nargs, inputParameters); - - if (delegateBindingInfo.returnType != typeof(void)) - { - this.cg.cs.AppendLine($"{this.cg.bindingManager.GetCSTypeFullName(delegateBindingInfo.returnType)} {retName};"); - var getter = this.cg.bindingManager.GetScriptObjectGetter(delegateBindingInfo.returnType, "ctx", "rval", retName); - - this.cg.cs.AppendLine("var succ = {0};", getter); - FreeRVal(); - FreeArgs(nargs); - - this.cg.cs.AppendLine("if (succ)"); - this.cg.cs.AppendLine("{"); - this.cg.cs.AddTabLevel(); - this.cg.cs.AppendLine($"return {retName};"); - this.cg.cs.DecTabLevel(); - this.cg.cs.AppendLine("}"); - this.cg.cs.AppendLine("else"); - this.cg.cs.AppendLine("{"); - this.cg.cs.AddTabLevel(); - this.cg.cs.AppendLine($"throw new Exception(\"js exception caught\");"); - this.cg.cs.DecTabLevel(); - this.cg.cs.AppendLine("}"); - } - else - { - FreeRVal(); - FreeArgs(nargs); - } - } - - protected void CheckParameterException(int argIndex) - { - this.cg.cs.AppendLine("if (argv[{0}].IsException())", argIndex); - this.cg.cs.AppendLine("{"); - this.cg.cs.AddTabLevel(); - for (var j = 0; j < argIndex; j++) - { - this.cg.cs.AppendLine("JSApi.JS_FreeValue(ctx, argv[{0}]);", j); - } - - this.cg.cs.AppendLine("throw new Exception(ctx.GetExceptionString());"); - this.cg.cs.DecTabLevel(); - this.cg.cs.AppendLine("}"); - } - - // 回填 ref/out 参数 - protected void _WriteBackParameters(int nargs, ParameterInfo[] parameters) - { - for (int pIndex = 0, pCount = parameters.Length; pIndex < pCount; pIndex++) - { - var parameter = parameters[pIndex]; - var pType = parameter.ParameterType; - - if (!pType.IsByRef || Binding.Values.IsContextualType(pType)) - { - continue; - } - - var refValVar = $"refVal{pIndex}"; - this.cg.cs.AppendLine("var {0} = js_read_wrap(ctx, argv[{1}]);", refValVar, pIndex); - - this.cg.cs.AppendLine("if ({0}.IsException())", refValVar); - using (this.cg.cs.CodeBlockScope()) - { - FreeRVal(); - FreeArgs(nargs); - this.cg.cs.AppendLine("throw new Exception(ctx.GetExceptionString());"); - } - - var getter = this.cg.bindingManager.GetScriptObjectGetter(pType, "ctx", refValVar, parameter.Name); - this.cg.cs.AppendLine("if (!{0})", getter); - using (this.cg.cs.CodeBlockScope()) - { - var argTypeStr = this.cg.bindingManager.GetCSTypeFullName(parameter.ParameterType); - - FreeRVal(); - FreeArgs(nargs); - this.cg.cs.AppendLine("JSApi.JS_FreeValue(ctx, {0});", refValVar); - this.cg.WriteParameterException(CodeGenerator.NameOfDelegates, this.delegateBindingInfo.types.ToArray()[0].Name, argTypeStr, pIndex); - } - this.cg.cs.AppendLine("JSApi.JS_FreeValue(ctx, {0});", refValVar); - } - } - - private void CheckReturnValue(int nargs) - { - this.cg.cs.AppendLine("if (rval.IsException())"); - this.cg.cs.AppendLine("{"); - this.cg.cs.AddTabLevel(); - FreeArgs(nargs); - this.cg.cs.AppendLine("throw new Exception(ctx.GetExceptionString());"); - this.cg.cs.DecTabLevel(); - this.cg.cs.AppendLine("}"); - } - - private void FreeRVal() - { - this.cg.cs.AppendLine("JSApi.JS_FreeValue(ctx, rval);"); - } - - private void FreeArgs(int nargs) - { - for (var i = 0; i < nargs; i++) - { - this.cg.cs.AppendLine("JSApi.JS_FreeValue(ctx, argv[{0}]);", i); - // this.cg.cs.AppendLine("argv[{0}] = JSApi.JS_UNDEFINED;", i); - } - } - - public void Dispose() - { - this.cg.cs.DecTabLevel(); - this.cg.cs.AppendLine("}"); - } - } -} +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Linq; +using System.Reflection; + +namespace QuickJS.Binding +{ + public class DelegateCodeGen : IDisposable + { + protected CodeGenerator cg; + + protected string delegateName; + protected Type returnType; + protected ParameterInfo[] parameters; + protected HashSet delegateTypeRefs; + + private ParameterInfo[] GetInputParameters(ParameterInfo[] parameters) + { + // return parameters.Where(p => !p.IsOut).ToArray(); + return parameters; + } + + public DelegateCodeGen(CodeGenerator cg, DelegateBridgeBindingInfo delegateBindingInfo, int index) + { + this.cg = cg; + this.delegateName = delegateBindingInfo.types.FirstOrDefault()?.Name ?? CodeGenerator.NameOfDelegates + index; + this.returnType = delegateBindingInfo.returnType; + this.parameters = delegateBindingInfo.parameters; + this.delegateTypeRefs = delegateBindingInfo.types; + _Emit(); + } + + public DelegateCodeGen(CodeGenerator cg, string delegateName, Type returnType, ParameterInfo[] parameters) + { + this.cg = cg; + this.delegateName = delegateName; + this.returnType = returnType; + this.parameters = parameters; + this.delegateTypeRefs = null; + _Emit(); + } + + protected void _Emit() + { + var inputParameters = GetInputParameters(parameters); + var nargs = inputParameters.Length; + var retName = this.cg.bindingManager.GetUniqueName(parameters, "ret"); + var firstArgument = typeof(ScriptDelegate) + " fn"; + var returnTypeName = this.cg.bindingManager.GetCSTypeFullName(returnType); + var arglist = this.cg.bindingManager.GetCSArglistDecl(parameters); + + if (delegateTypeRefs != null) + { + foreach (var target in delegateTypeRefs) + { + this.cg.cs.AppendLine("[{0}(typeof({1}))]", + this.cg.bindingManager.GetCSTypeFullName(typeof(JSDelegateAttribute)), + this.cg.bindingManager.GetCSTypeFullName(target)); + this.cg.bindingManager.Info("emitting delegate decl: {0}", target); + } + } + if (!string.IsNullOrEmpty(arglist)) + { + arglist = ", " + arglist; + } + this.cg.cs.AppendLine($"public static unsafe {returnTypeName} {delegateName}({firstArgument}{arglist})"); + this.cg.cs.AppendLine("{"); + this.cg.cs.AddTabLevel(); + this.cg.cs.AppendLine("var ctx = fn.ctx;"); + + if (nargs > 0) + { + var getContext = false; + this.cg.cs.AppendLine("var argv = stackalloc JSValue[{0}];", nargs); + for (var i = 0; i < nargs; i++) + { + var parameter = inputParameters[i]; + if (parameter.ParameterType.IsByRef) + { + if (parameter.IsOut) + { + var pusher = "JSApi.JS_NewObject(ctx)"; + this.cg.cs.AppendLine("argv[{0}] = {1};", i, pusher); + CheckParameterException(i); + } + else + { + var pusher = "JSApi.JS_NewObject(ctx)"; + var value_pusher = this.cg.AppendValuePusher(parameter.ParameterType, parameter.Name); + this.cg.cs.AppendLine("argv[{0}] = {1};", i, pusher); + CheckParameterException(i); + if (!getContext) + { + getContext = true; + cg.cs.AppendLine("var context = ScriptEngine.GetContext(ctx);"); + } + cg.cs.AppendLine("JSApi.JS_SetProperty(ctx, argv[{0}], context.GetAtom(\"value\"), {1});", i, value_pusher); + } + } + else + { + var pusher = this.cg.AppendValuePusher(parameter.ParameterType, parameter.Name); + this.cg.cs.AppendLine("argv[{0}] = {1};", i, pusher); + CheckParameterException(i); + } + } + this.cg.cs.AppendLine("var rval = fn.Invoke(ctx, {0}, argv);", nargs); + } + else + { + this.cg.cs.AppendLine("var rval = fn.Invoke(ctx);"); + } + + CheckReturnValue(nargs); + _WriteBackParameters(nargs, inputParameters); + + if (returnType != typeof(void)) + { + this.cg.cs.AppendLine($"{this.cg.bindingManager.GetCSTypeFullName(returnType)} {retName};"); + var getter = this.cg.bindingManager.GetScriptObjectGetter(returnType, "ctx", "rval", retName); + + this.cg.cs.AppendLine("var succ = {0};", getter); + FreeRVal(); + FreeArgs(nargs); + + this.cg.cs.AppendLine("if (succ)"); + this.cg.cs.AppendLine("{"); + this.cg.cs.AddTabLevel(); + this.cg.cs.AppendLine($"return {retName};"); + this.cg.cs.DecTabLevel(); + this.cg.cs.AppendLine("}"); + this.cg.cs.AppendLine("else"); + this.cg.cs.AppendLine("{"); + this.cg.cs.AddTabLevel(); + this.cg.cs.AppendLine($"throw new System.Exception(\"js exception caught\");"); + this.cg.cs.DecTabLevel(); + this.cg.cs.AppendLine("}"); + } + else + { + FreeRVal(); + FreeArgs(nargs); + } + } + + protected void CheckParameterException(int argIndex) + { + this.cg.cs.AppendLine("if (argv[{0}].IsException())", argIndex); + this.cg.cs.AppendLine("{"); + this.cg.cs.AddTabLevel(); + for (var j = 0; j < argIndex; j++) + { + this.cg.cs.AppendLine("JSApi.JS_FreeValue(ctx, argv[{0}]);", j); + } + + this.cg.cs.AppendLine("throw new System.Exception(ctx.GetExceptionString());"); + this.cg.cs.DecTabLevel(); + this.cg.cs.AppendLine("}"); + } + + // 回填 ref/out 参数 + protected void _WriteBackParameters(int nargs, ParameterInfo[] parameters) + { + for (int pIndex = 0, pCount = parameters.Length; pIndex < pCount; pIndex++) + { + var parameter = parameters[pIndex]; + var pType = parameter.ParameterType; + + if (!pType.IsByRef || Binding.Values.IsContextualType(pType)) + { + continue; + } + + var refValVar = $"refVal{pIndex}"; + this.cg.cs.AppendLine("var {0} = Values.js_read_wrap(ctx, argv[{1}]);", refValVar, pIndex); + + this.cg.cs.AppendLine("if ({0}.IsException())", refValVar); + using (this.cg.cs.CodeBlockScope()) + { + FreeRVal(); + FreeArgs(nargs); + this.cg.cs.AppendLine("throw new System.Exception(ctx.GetExceptionString());"); + } + + var getter = this.cg.bindingManager.GetScriptObjectGetter(pType, "ctx", refValVar, parameter.Name); + this.cg.cs.AppendLine("if (!{0})", getter); + using (this.cg.cs.CodeBlockScope()) + { + var argTypeStr = this.cg.bindingManager.GetCSTypeFullName(parameter.ParameterType); + + FreeRVal(); + FreeArgs(nargs); + this.cg.cs.AppendLine("JSApi.JS_FreeValue(ctx, {0});", refValVar); + this.cg.WriteParameterException(CodeGenerator.NameOfDelegates, delegateName, argTypeStr, pIndex); + } + this.cg.cs.AppendLine("JSApi.JS_FreeValue(ctx, {0});", refValVar); + } + } + + private void CheckReturnValue(int nargs) + { + this.cg.cs.AppendLine("if (rval.IsException())"); + this.cg.cs.AppendLine("{"); + this.cg.cs.AddTabLevel(); + FreeArgs(nargs); + this.cg.cs.AppendLine("throw new System.Exception(ctx.GetExceptionString());"); + this.cg.cs.DecTabLevel(); + this.cg.cs.AppendLine("}"); + } + + private void FreeRVal() + { + this.cg.cs.AppendLine("JSApi.JS_FreeValue(ctx, rval);"); + } + + private void FreeArgs(int nargs) + { + for (var i = 0; i < nargs; i++) + { + this.cg.cs.AppendLine("JSApi.JS_FreeValue(ctx, argv[{0}]);", i); + // this.cg.cs.AppendLine("argv[{0}] = JSApi.JS_UNDEFINED;", i); + } + } + + public void Dispose() + { + this.cg.cs.DecTabLevel(); + this.cg.cs.AppendLine("}"); + } + } +} diff --git a/Assets/jsb/Source/Utils/TypeDB.cs b/Assets/jsb/Source/Utils/TypeDB.cs index cf782d10..6925eb8d 100644 --- a/Assets/jsb/Source/Utils/TypeDB.cs +++ b/Assets/jsb/Source/Utils/TypeDB.cs @@ -94,6 +94,11 @@ public DynamicType CreateFreeDynamicType(Type type) // }; // } + public bool ContainsDelegate(Type type) + { + return _delegates.ContainsKey(type); + } + public void AddDelegate(Type type, MethodInfo method) { _delegates[type] = method; diff --git a/Scripts/out/example_delegate.js b/Scripts/out/example_delegate.js index 4fb9b9ac..1fdc15b9 100644 --- a/Scripts/out/example_delegate.js +++ b/Scripts/out/example_delegate.js @@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); const Example_1 = require("Example"); if (module == require.main) { let actions = new Example_1.DelegateTest(); - print("测试: 无参数的委托"); + print("testcase: 无参数的委托"); console.log("********** add"); actions.onAction("add", function () { console.log("js action call"); @@ -13,7 +13,7 @@ if (module == require.main) { actions.onAction("set", null); console.log("********** after clear, call again"); actions.CallAction(); - print("测试: 带参数的委托"); + print("testcase: 带参数的委托"); actions.onActionWithArgs("set", (a, b, c) => { console.log(a, b, c); }); @@ -21,14 +21,14 @@ if (module == require.main) { actions.onFunc("set", v => v * 2); console.log(actions.CallFunc(111)); actions.onFunc("set", undefined); - print("测试: 事件"); + print("testcase: 事件"); actions.onEvent("add", v => print("测试事件1:", v)); function instanceEventHandler(v) { print("测试事件2:", v); } actions.onEvent("add", instanceEventHandler); actions.DipatchEvent(123); actions.onEvent("remove", instanceEventHandler); actions.DipatchEvent(123); - print("测试: 静态事件"); + print("testcase: 静态事件"); Example_1.DelegateTest.onStaticEvent("add", v => print("测试静态事件1:", v)); function staticEventHandler(v) { print("测试静态事件2:", v); } Example_1.DelegateTest.onStaticEvent("add", staticEventHandler); @@ -36,12 +36,15 @@ if (module == require.main) { Example_1.DelegateTest.onStaticEvent("remove", staticEventHandler); Example_1.DelegateTest.DipatchStaticEvent(123); try { - print("测试: 带 ref/out 的委托 (staticbind模式直接支持, reflectbind模式下目前需要手写模板函数)"); + print("testcase: delegate with ref/out parameters"); actions.complexCall("add", (b, a, v) => { a.value += b; v.value = 999; return 789; }); + actions.complexCall2("add", v => { + v.value.Set(v.value.x * 2, v.value.y * 2, v.value.z * 2); + }); actions.TestComplexCall(); } catch (err) { diff --git a/Scripts/out/example_delegate.js.map b/Scripts/out/example_delegate.js.map index 69dcbca9..a066ebda 100644 --- a/Scripts/out/example_delegate.js.map +++ b/Scripts/out/example_delegate.js.map @@ -1 +1 @@ -{"version":3,"file":"example_delegate.js","sourceRoot":"","sources":["../src/example_delegate.ts"],"names":[],"mappings":";;AAAA,qCAAuC;AAGvC,IAAI,MAAM,IAAI,OAAO,CAAC,IAAI,EAAE;IACxB,IAAI,OAAO,GAAG,IAAI,sBAAY,EAAE,CAAC;IAEjC,KAAK,CAAC,YAAY,CAAC,CAAC;IACpB,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC9B,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE;QACpB,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAC/B,OAAO,CAAC,UAAU,EAAE,CAAC;IAErB,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAC9B,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;IAClD,OAAO,CAAC,UAAU,EAAE,CAAC;IAErB,KAAK,CAAC,YAAY,CAAC,CAAC;IACpB,OAAO,CAAC,gBAAgB,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE;QACxC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IACzB,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,kBAAkB,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;IAE/C,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IACnC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IAEjC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAChB,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC;IAChD,SAAS,oBAAoB,CAAC,CAAS,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAA,CAAC,CAAC;IAC/D,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,oBAAoB,CAAC,CAAC;IAC7C,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAC1B,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAC;IAChD,OAAO,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;IAE1B,KAAK,CAAC,UAAU,CAAC,CAAC;IAClB,sBAAY,CAAC,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7D,SAAS,kBAAkB,CAAC,CAAS,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAA,CAAC,CAAC;IAC/D,sBAAY,CAAC,aAAa,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAAC;IACtD,sBAAY,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;IACrC,sBAAY,CAAC,aAAa,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;IACzD,sBAAY,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAC;IAErC,IAAI;QACA,KAAK,CAAC,gEAAgE,CAAC,CAAC;QACxE,OAAO,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE;YACnC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;YACb,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC;YACd,OAAO,GAAG,CAAC;QACf,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,eAAe,EAAE,CAAC;KAC7B;IAAC,OAAO,GAAG,EAAE;QACV,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;KACtB;CACJ"} \ No newline at end of file +{"version":3,"file":"example_delegate.js","sourceRoot":"","sources":["../src/example_delegate.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/Scripts/src/example_delegate.ts b/Scripts/src/example_delegate.ts index 2e3d852c..378f7267 100644 --- a/Scripts/src/example_delegate.ts +++ b/Scripts/src/example_delegate.ts @@ -1,10 +1,9 @@ import { DelegateTest } from "Example"; -import { IsStaticBinding } from "jsb"; if (module == require.main) { let actions = new DelegateTest(); - print("测试: 无参数的委托"); + print("testcase: 无参数的委托"); console.log("********** add"); actions.onAction("add", function () { console.log("js action call"); @@ -17,7 +16,7 @@ if (module == require.main) { console.log("********** after clear, call again"); actions.CallAction(); - print("测试: 带参数的委托"); + print("testcase: 带参数的委托"); actions.onActionWithArgs("set", (a, b, c) => { console.log(a, b, c); }); @@ -27,7 +26,7 @@ if (module == require.main) { console.log(actions.CallFunc(111)); actions.onFunc("set", undefined); - print("测试: 事件"); + print("testcase: 事件"); actions.onEvent("add", v => print("测试事件1:", v)); function instanceEventHandler(v: number) { print("测试事件2:", v) } actions.onEvent("add", instanceEventHandler); @@ -35,7 +34,7 @@ if (module == require.main) { actions.onEvent("remove", instanceEventHandler); actions.DipatchEvent(123); - print("测试: 静态事件"); + print("testcase: 静态事件"); DelegateTest.onStaticEvent("add", v => print("测试静态事件1:", v)); function staticEventHandler(v: number) { print("测试静态事件2:", v) } DelegateTest.onStaticEvent("add", staticEventHandler); @@ -44,12 +43,15 @@ if (module == require.main) { DelegateTest.DipatchStaticEvent(123); try { - print("测试: 带 ref/out 的委托 (staticbind模式直接支持, reflectbind模式下目前需要手写模板函数)"); + print("testcase: delegate with ref/out parameters"); actions.complexCall("add", (b, a, v) => { a.value += b; v.value = 999; return 789; }); + actions.complexCall2("add", v => { + v.value.Set(v.value.x * 2, v.value.y * 2, v.value.z * 2); + }); actions.TestComplexCall(); } catch (err) { console.error(err);