diff --git a/unity/Assets/core/upm/Runtime/Src/Default/JsEnv.cs b/unity/Assets/core/upm/Runtime/Src/Default/JsEnv.cs index 5c6d9b41fc..a51c654744 100644 --- a/unity/Assets/core/upm/Runtime/Src/Default/JsEnv.cs +++ b/unity/Assets/core/upm/Runtime/Src/Default/JsEnv.cs @@ -11,6 +11,7 @@ using System.Linq; using System.Collections.Generic; using Puerts.TypeMapping; +using System.Reflection; #if CSHARP_7_3_OR_NEWER using System.Threading.Tasks; #endif @@ -165,6 +166,7 @@ public JsEnv(ILoader loader, int debugPort, BackendType backend, IntPtr external // 把JSEnv的id和Callback的id拼成一个long存起来,并将StaticCallbacks.JsEnvCallbackWrap注册给V8。而后通过StaticCallbacks.JsEnvCallbackWrap从long中取出函数和envid并调用。 PuertsDLL.SetGlobalFunction(isolate, "__tgjsRegisterTickHandler", StaticCallbacks.JsEnvCallbackWrap, AddCallback(RegisterTickHandler)); PuertsDLL.SetGlobalFunction(isolate, "__tgjsGetGenericMethod", StaticCallbacks.JsEnvCallbackWrap, AddCallback(GetGenericMethod)); + PuertsDLL.SetGlobalFunction(isolate, "createFunction", StaticCallbacks.JsEnvCallbackWrap, AddCallback(CreateFunction)); PuertsDLL.SetGlobalFunction(isolate, "__tgjsLoadType", StaticCallbacks.JsEnvCallbackWrap, AddCallback(LoadType)); PuertsDLL.SetGlobalFunction(isolate, "__tgjsGetNestedTypes", StaticCallbacks.JsEnvCallbackWrap, AddCallback(GetNestedTypes)); PuertsDLL.SetGlobalFunction(isolate, "__tgjsGetLoader", StaticCallbacks.JsEnvCallbackWrap, AddCallback(GetLoader)); @@ -581,6 +583,40 @@ void GetGenericMethod(IntPtr isolate, IntPtr info, IntPtr self, int paramLen) } } + void CreateFunction(IntPtr isolate, IntPtr info, IntPtr self, int paramLen) + { + try + { + List methodInfos = new List(); + for(int i = 0; i < paramLen; ++i) + { + var arg = PuertsDLL.GetArgumentValue(isolate, info, i); + MethodInfo methodInfo = StaticTranslate.Get(Index, isolate, NativeValueApi.GetValueFromArgument, arg, false); + if (methodInfo == null) + { + PuertsDLL.ThrowException(isolate, "expect a MethodInfo"); + return; + } + methodInfos.Add(methodInfo); + } + + if (methodInfos.Count == 0) + { + PuertsDLL.ThrowException(isolate, "expect atleast one MethodInfo"); + return; + } + + var callbackID = AddCallback(new MethodReflectionWrap(methodInfos[0].Name, + methodInfos.Select(m => new OverloadReflectionWrap(m, this, false)).ToList() + ).Invoke); + PuertsDLL.ReturnCSharpFunctionCallback(isolate, info, StaticCallbacks.JsEnvCallbackWrap, callbackID); + } + catch (Exception e) + { + PuertsDLL.ThrowException(isolate, "CreateFunction throw c# exception:" + e.Message + ",stack:" + e.StackTrace); + } + } + void LoadType(IntPtr isolate, IntPtr info, IntPtr self, int paramLen) { try diff --git a/unity/test/Src/Cases/CrossLang/GenericTest.cs b/unity/test/Src/Cases/CrossLang/GenericTest.cs index b243859668..6fa62619b4 100644 --- a/unity/test/Src/Cases/CrossLang/GenericTest.cs +++ b/unity/test/Src/Cases/CrossLang/GenericTest.cs @@ -197,5 +197,28 @@ public void InstanceGenericMethodTest() jsEnv.Tick(); } + + [Test] + public void CreateFunctionByMethodInfoTest() + { + var jsEnv = UnitTestEnv.GetEnv(); + + string ret = jsEnv.Eval(@" + (function() { + const cls = puer.$typeof(CS.Puerts.UnitTest.GenericTestClass); + const methods = CS.Puerts.Utils.GetMethodAndOverrideMethodByName(cls, 'StaticGenericMethod'); + let overloads = []; + for (let i = 0; i < methods.Length; i++) { + let method = methods.GetValue(i) + overloads.push(method.MakeGenericMethod(puer.$typeof(CS.System.Int32))); + } + const func = createFunction(...overloads); + return func() + func(1024); + })(); + "); + Assert.AreEqual(ret, "Int321024"); + + jsEnv.Tick(); + } } } \ No newline at end of file