Skip to content

Commit

Permalink
Add basic implementation of generated ctor for CreateManagedForGodotO…
Browse files Browse the repository at this point in the history
…bjectBinding
  • Loading branch information
Delsin-Yu committed Sep 12, 2024
1 parent 9e8b6e2 commit b277322
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 12 deletions.
53 changes: 51 additions & 2 deletions modules/mono/editor/bindings_generator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1737,6 +1737,51 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir) {
compile_items.push_back(output_file);
}

// Generate source file for builtin type constructor dictionary

StringBuilder cs_builtin_ctors_content;

cs_builtin_ctors_content.append("namespace " BINDINGS_NAMESPACE ";\n\n");
cs_builtin_ctors_content.append("using System;\n"
"using System.Collections.Generic;\n"
"\n");
cs_builtin_ctors_content.append("internal static class " BINDINGS_CLASS_CONSTRUCTOR "\n{");

cs_builtin_ctors_content.append(MEMBER_BEGIN "private static readonly Dictionary<string, Func<IntPtr, GodotObject>> BuiltinMethodConstructors;\n");

cs_builtin_ctors_content.append(MEMBER_BEGIN "public static GodotObject Invoke(string nativeTypeNameStr, IntPtr nativeObjectPtr)\n");
cs_builtin_ctors_content.append(INDENT1 OPEN_BLOCK);
cs_builtin_ctors_content.append(INDENT2 "if (!BuiltinMethodConstructors.TryGetValue(nativeTypeNameStr, out var constructor))\n");
cs_builtin_ctors_content.append(INDENT3 "throw new InvalidOperationException(\"Wrapper class not found for type: \" + nativeTypeNameStr);\n");
cs_builtin_ctors_content.append(INDENT2 "return constructor(nativeObjectPtr);\n");
cs_builtin_ctors_content.append(INDENT1 CLOSE_BLOCK);

cs_builtin_ctors_content.append(MEMBER_BEGIN "static GodotObjectConstructors()\n");
cs_builtin_ctors_content.append(INDENT1 OPEN_BLOCK);
cs_builtin_ctors_content.append(INDENT2 "BuiltinMethodConstructors = new();\n");

for (const KeyValue<StringName, TypeInterface> &E : obj_types) {
const TypeInterface &itype = E.value;

if (!itype.is_instantiable) {
continue;
}

cs_builtin_ctors_content.append(INDENT2 "BuiltinMethodConstructors.Add(\"");
cs_builtin_ctors_content.append(itype.name);
cs_builtin_ctors_content.append("\", " CS_PARAM_INSTANCE " => new ");
cs_builtin_ctors_content.append(itype.proxy_name);
cs_builtin_ctors_content.append("(" CS_PARAM_INSTANCE "));\n");
}

cs_builtin_ctors_content.append(INDENT1 CLOSE_BLOCK);

cs_builtin_ctors_content.append(CLOSE_BLOCK);

String constructors_file = path::join(base_gen_dir, BINDINGS_CLASS_CONSTRUCTOR ".cs");
Error err = _save_file(constructors_file, cs_builtin_ctors_content);
compile_items.push_back(constructors_file);

// Generate native calls

StringBuilder cs_icalls_content;
Expand All @@ -1762,7 +1807,7 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir) {
if (icall.editor_only) {
continue;
}
Error err = _generate_cs_native_calls(icall, cs_icalls_content);
err = _generate_cs_native_calls(icall, cs_icalls_content);
if (err != OK) {
return err;
}
Expand All @@ -1772,7 +1817,7 @@ Error BindingsGenerator::generate_cs_core_project(const String &p_proj_dir) {

String internal_methods_file = path::join(base_gen_dir, BINDINGS_CLASS_NATIVECALLS ".cs");

Error err = _save_file(internal_methods_file, cs_icalls_content);
err = _save_file(internal_methods_file, cs_icalls_content);
if (err != OK) {
return err;
}
Expand Down Expand Up @@ -2214,6 +2259,10 @@ Error BindingsGenerator::_generate_cs_type(const TypeInterface &itype, const Str
output.append(MEMBER_BEGIN "internal ");
output.append(itype.proxy_name);
output.append("(bool " CS_PARAM_MEMORYOWN ") : base(" CS_PARAM_MEMORYOWN ") { }\n");

output.append(MEMBER_BEGIN "internal ");
output.append(itype.proxy_name);
output.append("(IntPtr " CS_PARAM_INSTANCE ") : base(" CS_PARAM_INSTANCE ") { }\n");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,19 +101,15 @@ internal static unsafe IntPtr CreateManagedForGodotObjectBinding(godot_string_na
NativeFuncs.godotsharp_string_name_new_copy(CustomUnsafe.AsRef(nativeTypeName)));
string nativeTypeNameStr = stringName.ToString();

Type nativeType = TypeGetProxyClass(nativeTypeNameStr) ?? throw new InvalidOperationException(
"Wrapper class not found for type: " + nativeTypeNameStr);
var obj = (GodotObject)FormatterServices.GetUninitializedObject(nativeType);
Console.WriteLine($"CreateManaged: {nativeTypeNameStr}");

var ctor = nativeType.GetConstructor(
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,
null, Type.EmptyTypes, null);
// TODO: Singleton Types
// TODO: Editor Types
// TODO: NativeTypeNameStr that starts with Godot.

obj.NativePtr = godotObject;

_ = ctor!.Invoke(obj, null);
var instance = GodotObjectConstructors.Invoke(nativeTypeNameStr, godotObject);

return GCHandle.ToIntPtr(CustomGCHandle.AllocStrong(obj));
return GCHandle.ToIntPtr(CustomGCHandle.AllocStrong(instance));
}
catch (Exception e)
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// using System;
// using System.Collections.Generic;
//
// namespace Godot;
//
// // Generated
// internal static partial class GodotObjectConstructors
// {
// private static readonly Dictionary<string, Func<IntPtr, GodotObject>> BuiltinMethodConstructors;
//
// static GodotObjectConstructors()
// {
// BuiltinMethodConstructors = new();
// BuiltinMethodConstructors.Add("", ptr => new GodotObject(ptr));
// }
//
// public static partial GodotObject Invoke(string nativeTypeNameStr, IntPtr nativeObjectPtr)
// }
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public GodotObject() : this(false)
}
}

internal GodotObject(IntPtr nativePtr) : this() => NativePtr = nativePtr;

internal unsafe void ConstructAndInitialize(
delegate* unmanaged<godot_bool, IntPtr> nativeCtor,
StringName nativeName,
Expand Down
1 change: 1 addition & 0 deletions modules/mono/godotsharp_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#define EDITOR_API_ASSEMBLY_NAME "GodotSharpEditor"
#define TOOLS_ASM_NAME "GodotTools"

#define BINDINGS_CLASS_CONSTRUCTOR "GodotObjectConstructors"
#define BINDINGS_CLASS_NATIVECALLS "NativeCalls"
#define BINDINGS_CLASS_NATIVECALLS_EDITOR "EditorNativeCalls"

Expand Down

0 comments on commit b277322

Please sign in to comment.