From 9ffbe1f8ca14b5a73dbd127abdedb8ccb0a1b417 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 31 Jan 2025 23:36:15 +0100 Subject: [PATCH] Add support in scripting for using interfaces on structures #2679 --- .../Bindings/BindingsGenerator.Cpp.cs | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs index a189c363a..a2c5f6934 100644 --- a/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs +++ b/Source/Tools/Flax.Build/Bindings/BindingsGenerator.Cpp.cs @@ -1932,19 +1932,20 @@ namespace Flax.Build.Bindings contents.Append('}').AppendLine(); } - private static string GenerateCppInterfaceInheritanceTable(BuildData buildData, StringBuilder contents, ModuleInfo moduleInfo, VirtualClassInfo typeInfo, string typeNameNative) + private static string GenerateCppInterfaceInheritanceTable(BuildData buildData, StringBuilder contents, ModuleInfo moduleInfo, ClassStructInfo typeInfo, string typeNameNative, string typeNameInternal) { var interfacesPtr = "nullptr"; var interfaces = typeInfo.Interfaces; if (interfaces != null) { - interfacesPtr = typeNameNative + "_Interfaces"; + var virtualTypeInfo = typeInfo as VirtualClassInfo; + interfacesPtr = typeNameInternal + "_Interfaces"; contents.Append("static const ScriptingType::InterfaceImplementation ").Append(interfacesPtr).AppendLine("[] = {"); for (int i = 0; i < interfaces.Count; i++) { var interfaceInfo = interfaces[i]; - var scriptVTableOffset = typeInfo.GetScriptVTableOffset(interfaceInfo); - contents.AppendLine($" {{ &{interfaceInfo.NativeName}::TypeInitializer, (int16)VTABLE_OFFSET({typeInfo.NativeName}, {interfaceInfo.NativeName}), {scriptVTableOffset}, true }},"); + var scriptVTableOffset = virtualTypeInfo?.GetScriptVTableOffset(interfaceInfo) ?? 0; + contents.AppendLine($" {{ &{interfaceInfo.NativeName}::TypeInitializer, (int16)VTABLE_OFFSET({typeNameNative}, {interfaceInfo.NativeName}), {scriptVTableOffset}, true }},"); } contents.AppendLine(" { nullptr, 0 },"); contents.AppendLine("};"); @@ -2248,7 +2249,7 @@ namespace Flax.Build.Bindings contents.AppendLine(); // Interfaces - var interfacesTable = GenerateCppInterfaceInheritanceTable(buildData, contents, moduleInfo, classInfo, classTypeNameNative); + var interfacesTable = GenerateCppInterfaceInheritanceTable(buildData, contents, moduleInfo, classInfo, classTypeNameNative, classTypeNameInternal); // Type initializer if (GenerateCppIsTemplateInstantiationType(classInfo)) @@ -2263,7 +2264,7 @@ namespace Flax.Build.Bindings contents.Append("&ScriptingType::DefaultSpawn, "); else contents.Append($"(ScriptingType::SpawnHandler)&{classTypeNameNative}::Spawn, "); - if (classInfo.BaseType != null && useScripting) + if (classInfo.BaseType != null) contents.Append($"&{classInfo.BaseType.FullNameNative}::TypeInitializer, "); else contents.Append("nullptr, "); @@ -2280,9 +2281,7 @@ namespace Flax.Build.Bindings else contents.Append("nullptr"); } - contents.Append(", ").Append(interfacesTable); - contents.Append(");"); - contents.AppendLine(); + contents.Append(", ").Append(interfacesTable).Append(");").AppendLine(); // Nested types foreach (var apiTypeInfo in classInfo.Children) @@ -2489,13 +2488,22 @@ namespace Flax.Build.Bindings contents.Append('}').Append(';').AppendLine(); contents.AppendLine(); + // Interfaces + var interfacesTable = GenerateCppInterfaceInheritanceTable(buildData, contents, moduleInfo, structureInfo, structureTypeNameNative, structureTypeNameInternal); + + // Type initializer if (GenerateCppIsTemplateInstantiationType(structureInfo)) contents.Append("template<> "); contents.Append($"ScriptingTypeInitializer {structureTypeNameNative}::TypeInitializer((BinaryModule*)GetBinaryModule{moduleInfo.Name}(), "); contents.Append($"StringAnsiView(\"{structureTypeNameManaged}\", {structureTypeNameManaged.Length}), "); contents.Append($"sizeof({structureTypeNameNative}), "); contents.Append($"&{structureTypeNameInternal}Internal::InitRuntime, "); - contents.Append($"&{structureTypeNameInternal}Internal::Ctor, &{structureTypeNameInternal}Internal::Dtor, &{structureTypeNameInternal}Internal::Copy, &{structureTypeNameInternal}Internal::Box, &{structureTypeNameInternal}Internal::Unbox, &{structureTypeNameInternal}Internal::GetField, &{structureTypeNameInternal}Internal::SetField);").AppendLine(); + contents.Append($"&{structureTypeNameInternal}Internal::Ctor, &{structureTypeNameInternal}Internal::Dtor, &{structureTypeNameInternal}Internal::Copy, &{structureTypeNameInternal}Internal::Box, &{structureTypeNameInternal}Internal::Unbox, &{structureTypeNameInternal}Internal::GetField, &{structureTypeNameInternal}Internal::SetField, "); + if (structureInfo.BaseType != null) + contents.Append($"&{structureInfo.BaseType.FullNameNative}::TypeInitializer"); + else + contents.Append("nullptr"); + contents.Append(", ").Append(interfacesTable).Append(");").AppendLine(); // Nested types foreach (var apiTypeInfo in structureInfo.Children)