diff --git a/Source/Engine/Scripting/InternalCalls/ManagedDictionary.h b/Source/Engine/Scripting/InternalCalls/ManagedDictionary.h index 215a723ce..6b9743709 100644 --- a/Source/Engine/Scripting/InternalCalls/ManagedDictionary.h +++ b/Source/Engine/Scripting/InternalCalls/ManagedDictionary.h @@ -23,15 +23,17 @@ struct FLAXENGINE_API ManagedDictionary } template - static MonoObject* ToManaged(const Dictionary& data, MonoClass* keyType, MonoClass* valueType) + static MonoObject* ToManaged(const Dictionary& data, MonoType* keyType, MonoType* valueType) { MConverter keysConverter; MConverter valueConverter; ManagedDictionary result = New(keyType, valueType); + MonoClass* keyClass = mono_type_get_class(keyType); + MonoClass* valueClass = mono_type_get_class(valueType); for (auto i = data.Begin(); i.IsNotEnd(); ++i) { - MonoObject* keyManaged = keysConverter.Box(i->Key, keyType); - MonoObject* valueManaged = valueConverter.Box(i->Value, valueType); + MonoObject* keyManaged = keysConverter.Box(i->Key, keyClass); + MonoObject* valueManaged = valueConverter.Box(i->Value, valueClass); result.Add(keyManaged, valueManaged); } return result.Instance; @@ -71,10 +73,11 @@ struct FLAXENGINE_API ManagedDictionary return result; } - static ManagedDictionary New(MonoClass* keyType, MonoClass* valueType) + static ManagedDictionary New(MonoType* keyType, MonoType* valueType) { ManagedDictionary result; + auto domain = mono_domain_get(); auto scriptingClass = Scripting::GetStaticClass(); CHECK_RETURN(scriptingClass, result); auto makeGenericMethod = scriptingClass->GetMethod("MakeGenericType", 2); @@ -83,9 +86,9 @@ struct FLAXENGINE_API ManagedDictionary CHECK_RETURN(createMethod, result); auto genericType = MUtils::GetType(StdTypesContainer::Instance()->DictionaryClass->GetNative()); - auto genericArgs = mono_array_new(mono_domain_get(), mono_get_object_class(), 2); - mono_array_set(genericArgs, MonoReflectionType*, 0, MUtils::GetType(keyType)); - mono_array_set(genericArgs, MonoReflectionType*, 1, MUtils::GetType(valueType)); + auto genericArgs = mono_array_new(domain, mono_get_object_class(), 2); + mono_array_set(genericArgs, MonoReflectionType*, 0, mono_type_get_object(domain, keyType)); + mono_array_set(genericArgs, MonoReflectionType*, 1, mono_type_get_object(domain, valueType)); void* params[2]; params[0] = genericType; diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs index 7ef3bc83f..853ed9adb 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs @@ -262,6 +262,66 @@ namespace Flax.Build.Bindings return "Scripting::FindClassNative(\"" + managedType + "\")"; } + private static string GenerateCppGetNativeType(BuildData buildData, TypeInfo typeInfo, ApiTypeInfo caller, FunctionInfo functionInfo) + { + // Optimal path for in-build types + var managedType = GenerateCSharpNativeToManaged(buildData, typeInfo, caller); + switch (managedType) + { + case "bool": + case "sbyte": + case "byte": + case "short": + case "ushort": + case "int": + case "uint": + case "long": + case "ulong": + case "float": + case "double": + case "string": + case "object": + case "void": + case "char": + case "IntPtr": + case "UIntPtr": return "mono_class_get_type(" + GenerateCppGetNativeClass(buildData, typeInfo, caller, null) + ')'; + } + + // Find API type + var apiType = FindApiTypeInfo(buildData, typeInfo, caller); + if (apiType != null) + { + CppReferencesFiles.Add(apiType.File); + if (apiType.IsStruct && !apiType.IsPod && !CppUsedNonPodTypes.Contains(apiType)) + CppUsedNonPodTypes.Add(apiType); + if (!apiType.IsInBuild && !apiType.IsEnum) + { + // Use declared type initializer + return $"mono_class_get_type({apiType.FullNameNative}::TypeInitializer.GetType().ManagedClass->GetNative())"; + } + } + + // Pass it from C# in glue parameter if used inside the wrapper function + if (functionInfo != null) + { + var customParam = new FunctionInfo.ParameterInfo + { + Name = "resultArrayItemType" + functionInfo.Glue.CustomParameters.Count, + DefaultValue = "typeof(" + managedType + ')', + Type = new TypeInfo + { + Type = "MonoReflectionType", + IsPtr = true, + }, + }; + functionInfo.Glue.CustomParameters.Add(customParam); + return "mono_reflection_type_get_type(" + customParam.Name + ')'; + } + + // Convert MonoClass* into MonoType* + return "mono_class_get_type" + GenerateCppGetNativeClass(buildData, typeInfo, caller, null) + ')'; + } + private static string GenerateCppWrapperNativeToManaged(BuildData buildData, TypeInfo typeInfo, ApiTypeInfo caller, out string type, FunctionInfo functionInfo) { // Use dynamic array as wrapper container for fixed-size native arrays @@ -371,8 +431,8 @@ namespace Flax.Build.Bindings { CppIncludeFiles.Add("Engine/Scripting/InternalCalls/ManagedDictionary.h"); type = "MonoObject*"; - var keyClass = GenerateCppGetNativeClass(buildData, typeInfo.GenericArgs[0], caller, functionInfo); - var valueClass = GenerateCppGetNativeClass(buildData, typeInfo.GenericArgs[1], caller, functionInfo); + var keyClass = GenerateCppGetNativeType(buildData, typeInfo.GenericArgs[0], caller, functionInfo); + var valueClass = GenerateCppGetNativeType(buildData, typeInfo.GenericArgs[1], caller, functionInfo); return "ManagedDictionary::ToManaged({0}, " + keyClass + ", " + valueClass + ")"; }