From d4d8d61e4f94e26f7c7aaa50e698e2c291aa4fcc Mon Sep 17 00:00:00 2001 From: Jeff Ward Date: Sun, 22 Dec 2024 17:20:21 -0500 Subject: [PATCH] feat: Remove requirement for 'bindingToken' . This is a giant refactor that completely removes the need for 'bindingTokens'. This should, eventually, allow me to get ride of `.cast` except to be used as an actual dynamic cast instead of a necessity over Dart `is` / `as`. This still needs to be tested with a more complex project to see if it actually works. --- example/2d_tutorial/.gitignore | 1 + .../fonts/Xolonium-Regular.ttf.import | 2 + .../2d_tutorial/godot_dart.gdextension.uid | 1 + example/2d_tutorial/main.tscn | 2 +- example/2d_tutorial/project.godot | 8 +- .../src/godot_dart_scripts.g.dart.uid | 1 + .../2d_tutorial/src/lib/game_logic.dart.uid | 1 + .../2d_tutorial/src/lib/game_logic.g.dart.uid | 1 + example/2d_tutorial/src/lib/hud.dart.uid | 1 + example/2d_tutorial/src/lib/hud.g.dart.uid | 1 + example/2d_tutorial/src/lib/mob.dart.uid | 1 + example/2d_tutorial/src/lib/mob.g.dart.uid | 1 + example/2d_tutorial/src/lib/player.dart | 2 +- example/2d_tutorial/src/lib/player.dart.uid | 1 + example/2d_tutorial/src/lib/player.g.dart.uid | 1 + example/2d_tutorial/src/main.dart.uid | 1 + src/cpp/dart_bindings.cpp | 84 +++++++------- src/cpp/dart_bindings.h | 2 + src/cpp/dart_instance_binding.cpp | 51 ++++++--- src/cpp/dart_instance_binding.h | 6 +- src/cpp/gde_dart_converters.h | 1 - src/cpp/script/dart_resource_format.h | 22 ++-- src/cpp/script/dart_script.h | 2 +- src/cpp/script/dart_script_language.h | 2 +- src/dart/godot_dart/lib/godot_dart.dart | 11 +- .../lib/src/annotations/godot_script.dart | 3 +- .../godot_dart/lib/src/core/gdextension.dart | 25 ++--- .../src/core/godot_dart_native_bindings.dart | 16 ++- .../godot_dart/lib/src/core/type_info.dart | 16 +-- .../godot_dart/lib/src/variant/variant.dart | 40 +++---- .../godot_dart/lib/src/variant/vector2.dart | 1 - .../godot_dart/lib/src/variant/vector3.dart | 1 - .../lib/src/godot_script_generator.dart | 6 +- .../lib/binding_generator.dart | 8 +- .../lib/src/common_helpers.dart | 103 ++++-------------- .../generators/builtin_type_generator.dart | 47 +++++--- .../src/generators/engine_type_generator.dart | 59 ++++++---- .../native_structures_generator.dart | 43 +++----- tools/fetch_dart/bin/fetch_dart.dart | 16 +-- 39 files changed, 272 insertions(+), 319 deletions(-) create mode 100644 example/2d_tutorial/godot_dart.gdextension.uid create mode 100644 example/2d_tutorial/src/godot_dart_scripts.g.dart.uid create mode 100644 example/2d_tutorial/src/lib/game_logic.dart.uid create mode 100644 example/2d_tutorial/src/lib/game_logic.g.dart.uid create mode 100644 example/2d_tutorial/src/lib/hud.dart.uid create mode 100644 example/2d_tutorial/src/lib/hud.g.dart.uid create mode 100644 example/2d_tutorial/src/lib/mob.dart.uid create mode 100644 example/2d_tutorial/src/lib/mob.g.dart.uid create mode 100644 example/2d_tutorial/src/lib/player.dart.uid create mode 100644 example/2d_tutorial/src/lib/player.g.dart.uid create mode 100644 example/2d_tutorial/src/main.dart.uid diff --git a/example/2d_tutorial/.gitignore b/example/2d_tutorial/.gitignore index 1959770..f9ee659 100644 --- a/example/2d_tutorial/.gitignore +++ b/example/2d_tutorial/.gitignore @@ -7,3 +7,4 @@ *.dylib *.pdb *.exp +*.so \ No newline at end of file diff --git a/example/2d_tutorial/fonts/Xolonium-Regular.ttf.import b/example/2d_tutorial/fonts/Xolonium-Regular.ttf.import index 8eec7d0..1105a6e 100644 --- a/example/2d_tutorial/fonts/Xolonium-Regular.ttf.import +++ b/example/2d_tutorial/fonts/Xolonium-Regular.ttf.import @@ -15,6 +15,7 @@ dest_files=["res://.godot/imported/Xolonium-Regular.ttf-bc2981e3069cff4c34dd7c8e Rendering=null antialiasing=1 generate_mipmaps=false +disable_embedded_bitmaps=true multichannel_signed_distance_field=false msdf_pixel_range=8 msdf_size=48 @@ -22,6 +23,7 @@ allow_system_fallback=true force_autohinter=false hinting=1 subpixel_positioning=1 +keep_rounding_remainders=true oversampling=0.0 Fallbacks=null fallbacks=[] diff --git a/example/2d_tutorial/godot_dart.gdextension.uid b/example/2d_tutorial/godot_dart.gdextension.uid new file mode 100644 index 0000000..b859461 --- /dev/null +++ b/example/2d_tutorial/godot_dart.gdextension.uid @@ -0,0 +1 @@ +uid://b6chiggk1agbi diff --git a/example/2d_tutorial/main.tscn b/example/2d_tutorial/main.tscn index acb4264..88416d5 100644 --- a/example/2d_tutorial/main.tscn +++ b/example/2d_tutorial/main.tscn @@ -1,6 +1,6 @@ [gd_scene load_steps=9 format=4 uid="uid://tnm416ggiork"] -[ext_resource type="Script" path="res://src/lib/game_logic.dart" id="1_724d8"] +[ext_resource type="Script" uid="uid://wy5n7q67gfpi" path="res://src/lib/game_logic.dart" id="1_724d8"] [ext_resource type="PackedScene" uid="uid://j6e8fjrrm1xp" path="res://mob.tscn" id="2_7ma3k"] [ext_resource type="PackedScene" uid="uid://ylcs4f06tfbg" path="res://player.tscn" id="2_eccq4"] [ext_resource type="PackedScene" uid="uid://6a3aidlclhn4" path="res://hud.tscn" id="4_abxjl"] diff --git a/example/2d_tutorial/project.godot b/example/2d_tutorial/project.godot index 159d947..70c92c5 100644 --- a/example/2d_tutorial/project.godot +++ b/example/2d_tutorial/project.godot @@ -25,21 +25,21 @@ window/stretch/mode="canvas_items" move_right={ "deadzone": 0.5, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-3,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } move_left={ "deadzone": 0.5, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-3,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } move_up={ "deadzone": 0.5, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-3,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194320,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194320,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } move_down={ "deadzone": 0.5, -"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-3,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194322,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194322,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null) ] } diff --git a/example/2d_tutorial/src/godot_dart_scripts.g.dart.uid b/example/2d_tutorial/src/godot_dart_scripts.g.dart.uid new file mode 100644 index 0000000..52ef2c0 --- /dev/null +++ b/example/2d_tutorial/src/godot_dart_scripts.g.dart.uid @@ -0,0 +1 @@ +uid://ccw2wbfog3u58 diff --git a/example/2d_tutorial/src/lib/game_logic.dart.uid b/example/2d_tutorial/src/lib/game_logic.dart.uid new file mode 100644 index 0000000..cc33373 --- /dev/null +++ b/example/2d_tutorial/src/lib/game_logic.dart.uid @@ -0,0 +1 @@ +uid://wy5n7q67gfpi diff --git a/example/2d_tutorial/src/lib/game_logic.g.dart.uid b/example/2d_tutorial/src/lib/game_logic.g.dart.uid new file mode 100644 index 0000000..65bfb8f --- /dev/null +++ b/example/2d_tutorial/src/lib/game_logic.g.dart.uid @@ -0,0 +1 @@ +uid://bxs73svhcgluv diff --git a/example/2d_tutorial/src/lib/hud.dart.uid b/example/2d_tutorial/src/lib/hud.dart.uid new file mode 100644 index 0000000..d70404c --- /dev/null +++ b/example/2d_tutorial/src/lib/hud.dart.uid @@ -0,0 +1 @@ +uid://cj0mstcs30fnk diff --git a/example/2d_tutorial/src/lib/hud.g.dart.uid b/example/2d_tutorial/src/lib/hud.g.dart.uid new file mode 100644 index 0000000..9353068 --- /dev/null +++ b/example/2d_tutorial/src/lib/hud.g.dart.uid @@ -0,0 +1 @@ +uid://8n72sq862ktq diff --git a/example/2d_tutorial/src/lib/mob.dart.uid b/example/2d_tutorial/src/lib/mob.dart.uid new file mode 100644 index 0000000..f2db23e --- /dev/null +++ b/example/2d_tutorial/src/lib/mob.dart.uid @@ -0,0 +1 @@ +uid://cjjhbkgdf1t1e diff --git a/example/2d_tutorial/src/lib/mob.g.dart.uid b/example/2d_tutorial/src/lib/mob.g.dart.uid new file mode 100644 index 0000000..506191e --- /dev/null +++ b/example/2d_tutorial/src/lib/mob.g.dart.uid @@ -0,0 +1 @@ +uid://dh20pv8eus6ui diff --git a/example/2d_tutorial/src/lib/player.dart b/example/2d_tutorial/src/lib/player.dart index 77e2ec2..638351e 100644 --- a/example/2d_tutorial/src/lib/player.dart +++ b/example/2d_tutorial/src/lib/player.dart @@ -62,7 +62,7 @@ class Player extends Area2D { animatedSprite?.setFlipV(velocity.y > 0); } } else { - getNodeT()?.stop(); + animatedSprite?.stop(); } var position = getPosition(); diff --git a/example/2d_tutorial/src/lib/player.dart.uid b/example/2d_tutorial/src/lib/player.dart.uid new file mode 100644 index 0000000..3709c3a --- /dev/null +++ b/example/2d_tutorial/src/lib/player.dart.uid @@ -0,0 +1 @@ +uid://doy5q8n0id6u6 diff --git a/example/2d_tutorial/src/lib/player.g.dart.uid b/example/2d_tutorial/src/lib/player.g.dart.uid new file mode 100644 index 0000000..dd4a78c --- /dev/null +++ b/example/2d_tutorial/src/lib/player.g.dart.uid @@ -0,0 +1 @@ +uid://bm6hxkpovixtq diff --git a/example/2d_tutorial/src/main.dart.uid b/example/2d_tutorial/src/main.dart.uid new file mode 100644 index 0000000..1f9b761 --- /dev/null +++ b/example/2d_tutorial/src/main.dart.uid @@ -0,0 +1 @@ +uid://d0jqb13n3xw3w diff --git a/src/cpp/dart_bindings.cpp b/src/cpp/dart_bindings.cpp index eef80fa..b1138fe 100644 --- a/src/cpp/dart_bindings.cpp +++ b/src/cpp/dart_bindings.cpp @@ -64,13 +64,19 @@ bool GodotDartBindings::initialize(const char *script_path, const char *package_ Dart_SetMessageNotifyCallback(dart_message_notify_callback); Dart_Handle godot_dart_package_name = Dart_NewStringFromCString("package:godot_dart/godot_dart.dart"); - Dart_Handle godot_dart_library = Dart_LookupLibrary(godot_dart_package_name); - if (Dart_IsError(godot_dart_library)) { - GD_PRINT_ERROR("GodotDart: Initialization Error (Could not find the `godot_dart` " + DART_CHECK_RET(godot_dart_library, Dart_LookupLibrary(godot_dart_package_name), false, + "GodotDart: Initialization Error (Could not find the `godot_dart` " + "package)"); + _godot_dart_library = Dart_NewPersistentHandle(godot_dart_library); + + // Find the Engine classes library. This is needed to lookup engine types + { + Dart_Handle engine_classes_package_name = + Dart_NewStringFromCString("package:godot_dart/src/gen/engine_classes.dart"); + DART_CHECK_RET(engine_classes_library, Dart_LookupLibrary(engine_classes_package_name), false, + "GodotDart: Initialization Error (Could not find the `engine_classes.dart` " "package)"); - return false; - } else { - _godot_dart_library = Dart_NewPersistentHandle(godot_dart_library); + _engine_classes_library = Dart_NewPersistentHandle(engine_classes_library); } // Find the DartBindings "library" (just the file) and set us as the native callback handler @@ -83,11 +89,10 @@ bool GodotDartBindings::initialize(const char *script_path, const char *package_ Dart_SetNativeResolver(library, native_resolver, nullptr); } - // Find the DartBindings "library" (just the file) and set us as the native callback handler + // Find the CoreTypes "library" (just the file) and set us as the native callback handler { - Dart_Handle native_bindings_library_name = - Dart_NewStringFromCString("package:godot_dart/src/core/core_types.dart"); - DART_CHECK_RET(library, Dart_LookupLibrary(native_bindings_library_name), false, "Error finding core_types.dart"); + Dart_Handle core_bindings_library_name = Dart_NewStringFromCString("package:godot_dart/src/core/core_types.dart"); + DART_CHECK_RET(library, Dart_LookupLibrary(core_bindings_library_name), false, "Error finding core_types.dart"); Dart_SetNativeResolver(library, native_resolver, nullptr); } @@ -151,7 +156,7 @@ bool GodotDartBindings::initialize(const char *script_path, const char *package_ { GDEWrapper *wrapper = GDEWrapper::instance(); Dart_Handle args[] = { - Dart_NewInteger((int64_t)wrapper->get_library_ptr()), + Dart_NewInteger((int64_t)this), Dart_NewInteger(((int64_t)&DartGodotInstanceBinding::engine_binding_callbacks)), }; DART_CHECK_RET(result, Dart_Invoke(godot_dart_library, Dart_NewStringFromCString("_registerGodot"), 2, args), @@ -389,6 +394,25 @@ void GodotDartBindings::bind_method(const TypeInfo &bind_type, const char *metho delete[] arg_meta_info; } +Dart_Handle GodotDartBindings::find_dart_type(Dart_Handle type_name) { + DartBlockScope scope; + + uint8_t* c_type_name = nullptr; + intptr_t length = 0; + Dart_StringToUTF8(type_name, &c_type_name, &length); + if (0 == strncmp(reinterpret_cast(c_type_name), "Object", length)) { + type_name = Dart_NewStringFromCString("GodotObject"); + } + + DART_CHECK_RET(engine_classes_library, Dart_HandleFromPersistent(_engine_classes_library), Dart_Null(), + "Error getting class class library.") + + DART_CHECK_RET(type, Dart_GetNonNullableType(engine_classes_library, type_name, 0, nullptr), Dart_Null(), + "Could not find type in the engine_classes_library."); + + return type; +} + void GodotDartBindings::add_property(const TypeInfo &bind_type, Dart_Handle dart_prop_info) { GDExtensionPropertyInfo prop_info = {}; @@ -791,25 +815,9 @@ void gd_object_to_dart_object(Dart_NativeArguments args) { } GDEWrapper *gde = GDEWrapper::instance(); - - // Default for non-engine classes - void *token = gde->get_library_ptr(); - - Dart_Handle bindings_token = Dart_GetNativeArgument(args, 2); - if (!Dart_IsNull(bindings_token)) { - address = Dart_GetField(bindings_token, Dart_NewStringFromCString("address")); - if (Dart_IsError(address)) { - GD_PRINT_ERROR(Dart_GetError(address)); - Dart_ThrowException(Dart_NewStringFromCString(Dart_GetError(address))); - return; - } - uint64_t token_int = 0; - Dart_IntegerToUint64(address, &token_int); - token = (void *)token_int; - } DartGodotInstanceBinding *binding = (DartGodotInstanceBinding *)gde_object_get_instance_binding( - reinterpret_cast(object_ptr), token, &DartGodotInstanceBinding::engine_binding_callbacks); + reinterpret_cast(object_ptr), bindings, &DartGodotInstanceBinding::engine_binding_callbacks); if (binding == nullptr) { Dart_SetReturnValue(args, Dart_Null()); } else { @@ -897,8 +905,7 @@ void type_info_from_dart(TypeInfo *type_info, Dart_Handle dart_type_info) { Dart_Handle class_name = Dart_GetField(dart_type_info, Dart_NewStringFromCString("className")); Dart_Handle parent_type = Dart_GetField(dart_type_info, Dart_NewStringFromCString("parentType")); - Dart_Handle variant_type = Dart_GetField(dart_type_info, Dart_NewStringFromCString("variantType")); - Dart_Handle binding_token = Dart_GetField(dart_type_info, Dart_NewStringFromCString("bindingToken")); + Dart_Handle variant_type = Dart_GetField(dart_type_info, Dart_NewStringFromCString("variantType")); type_info->type_name = get_object_address(class_name); type_info->parent_type = parent_type; @@ -906,18 +913,7 @@ void type_info_from_dart(TypeInfo *type_info, Dart_Handle dart_type_info) { int64_t temp; Dart_IntegerToInt64(variant_type, &temp); type_info->variant_type = static_cast(temp); - if (Dart_IsNull(binding_token)) { - type_info->binding_token = nullptr; - type_info->binding_callbacks = nullptr; - } else { - Dart_Handle dart_address = Dart_GetField(binding_token, Dart_NewStringFromCString("address")); - - uint64_t address = 0; - Dart_IntegerToUint64(dart_address, &address); - - type_info->binding_token = (void *)address; - type_info->binding_callbacks = &DartGodotInstanceBinding::engine_binding_callbacks; - } + type_info->binding_callbacks = &DartGodotInstanceBinding::engine_binding_callbacks; Dart_ExitScope(); } @@ -928,6 +924,7 @@ extern "C" { GDE_EXPORT void tie_dart_to_native(Dart_Handle dart_object, GDExtensionObjectPtr godot_object, bool is_refcounted, bool is_godot_defined) { + GodotDartBindings *bindings = GodotDartBindings::instance(); DartBlockScope scope; Dart_Handle d_class_type_info = Dart_GetField(dart_object, Dart_NewStringFromCString("typeInfo")); @@ -942,7 +939,7 @@ GDE_EXPORT void tie_dart_to_native(Dart_Handle dart_object, GDExtensionObjectPtr const GDExtensionInstanceBindingCallbacks *callbacks = &DartGodotInstanceBinding::engine_binding_callbacks; DartGodotInstanceBinding *binding = (DartGodotInstanceBinding *)gde_object_get_instance_binding( - godot_object, class_type_info.binding_token, callbacks); + godot_object, bindings, callbacks); if (!binding->is_initialized()) { binding->initialize(dart_object, is_refcounted); } @@ -1033,5 +1030,4 @@ GDE_EXPORT void *safe_new_persistent_handle(Dart_Handle handle) { return (void *)result; } - } \ No newline at end of file diff --git a/src/cpp/dart_bindings.h b/src/cpp/dart_bindings.h index a38262f..d715c9b 100644 --- a/src/cpp/dart_bindings.h +++ b/src/cpp/dart_bindings.h @@ -44,6 +44,7 @@ class GodotDartBindings { void bind_method(const TypeInfo &bind_type, const char *method_name, const TypeInfo &ret_type_info, Dart_Handle args_list, MethodFlags method_flags); + Dart_Handle find_dart_type(Dart_Handle type_name); void add_property(const TypeInfo &bind_type, Dart_Handle dart_prop_info); void execute_on_dart_thread(std::function work); Dart_Handle new_dart_void_pointer(void *ptr); @@ -82,6 +83,7 @@ class GodotDartBindings { std::set _pending_ref_changes; Dart_PersistentHandle _godot_dart_library; + Dart_PersistentHandle _engine_classes_library; Dart_PersistentHandle _native_library; // Some things we need often diff --git a/src/cpp/dart_instance_binding.cpp b/src/cpp/dart_instance_binding.cpp index 5c45c43..e88202c 100644 --- a/src/cpp/dart_instance_binding.cpp +++ b/src/cpp/dart_instance_binding.cpp @@ -1,11 +1,13 @@ #include "dart_instance_binding.h" #include +#include -#include "dart_helpers.h" #include "dart_bindings.h" +#include "dart_helpers.h" #include "gde_c_interface.h" #include "ref_counted_wrapper.h" +#include "godot_string_wrappers.h" void gde_weak_finalizer(void *isolate_callback_data, void *peer) { if (peer == nullptr) { @@ -22,7 +24,7 @@ void gde_weak_finalizer(void *isolate_callback_data, void *peer) { } } -std::map DartGodotInstanceBinding::s_instanceMap; +std::map DartGodotInstanceBinding::s_instanceMap; DartGodotInstanceBinding::~DartGodotInstanceBinding() { GodotDartBindings *bindings = GodotDartBindings::instance(); @@ -38,12 +40,10 @@ DartGodotInstanceBinding::~DartGodotInstanceBinding() { // Don't attempt to execute on the Dart isolate if this is the case // (it might be already doing things) Dart_IsolateGroup current_isolate_group = Dart_CurrentIsolateGroup(); - if(current_isolate_group) { + if (current_isolate_group) { delete_dart_handle(); } else { - GodotDartBindings::instance()->execute_on_dart_thread([&]{ - delete_dart_handle(); - }); + GodotDartBindings::instance()->execute_on_dart_thread([&] { delete_dart_handle(); }); } bindings->remove_pending_ref_change(this); } @@ -136,7 +136,7 @@ void DartGodotInstanceBinding::create_dart_object() { } bindings->execute_on_dart_thread([&] { - Dart_PersistentHandle persistent_type = reinterpret_cast(_token); + Dart_PersistentHandle persistent_type = reinterpret_cast(_dart_type); Dart_Handle dart_type = Dart_HandleFromPersistent(persistent_type); Dart_Handle dart_pointer = bindings->new_dart_void_pointer(_godot_object); @@ -152,7 +152,26 @@ void DartGodotInstanceBinding::create_dart_object() { /* Binding callbacks used for Engine types implemented in Godot and wrapped in Dart */ static void *__engine_binding_create_callback(void *p_token, void *p_instance) { - DartGodotInstanceBinding *binding = new DartGodotInstanceBinding(p_token, p_instance); + GodotDartBindings *bindings = GodotDartBindings::instance(); + godot::StringName class_name; + + DartGodotInstanceBinding *binding = nullptr; + if (godot::internal::gdextension_interface_object_get_class_name( + p_instance, p_token, reinterpret_cast(class_name._native_ptr()))) { + bindings->execute_on_dart_thread([&] { + Dart_EnterScope(); + + Dart_Handle type_name = to_dart_string(class_name); + DART_CHECK(type, bindings->find_dart_type(type_name), "Error finding Dart type"); + if (!Dart_IsNull(type)) { + Dart_PersistentHandle persistent_type = Dart_NewPersistentHandle(type); + binding = new DartGodotInstanceBinding(persistent_type, p_instance); + } + + Dart_ExitScope(); + }); + } + return binding; } @@ -164,10 +183,10 @@ static void __engine_binding_free_callback(void *p_token, void *p_instance, void delete binding; return; } - + if (binding->is_weak() || bindings->_is_stopping) { - // If the binding is weak or we're shutting down, there's a possibility Dart is asking us - // to kill this in a way that does not allow us to call back into any other Dart code other + // If the binding is weak or we're shutting down, there's a possibility Dart is asking us + // to kill this in a way that does not allow us to call back into any other Dart code other // than deleting the reference. So just do that and be done with it. delete binding; return; @@ -222,9 +241,7 @@ static GDExtensionBool __engine_binding_reference_callback(void *p_token, void * // Refcount incremented, change our reference to strong to prevent Dart from finalizing if (refcount > 1 && engine_binding->is_weak()) { if (!is_finalizer) { - bindings->execute_on_dart_thread([&] { - engine_binding->convert_to_strong(); - }); + bindings->execute_on_dart_thread([&] { engine_binding->convert_to_strong(); }); } else { bindings->add_pending_ref_change(engine_binding); } @@ -234,13 +251,11 @@ static GDExtensionBool __engine_binding_reference_callback(void *p_token, void * } else { if (refcount == 1 && !engine_binding->is_weak()) { if (!is_finalizer) { - bindings->execute_on_dart_thread([&] { - engine_binding->convert_to_weak(); - }); + bindings->execute_on_dart_thread([&] { engine_binding->convert_to_weak(); }); } else { bindings->add_pending_ref_change(engine_binding); } - + is_dieing = false; } } diff --git a/src/cpp/dart_instance_binding.h b/src/cpp/dart_instance_binding.h index 7ec2429..78d358d 100644 --- a/src/cpp/dart_instance_binding.h +++ b/src/cpp/dart_instance_binding.h @@ -9,8 +9,8 @@ // persitent handles, encapsulate that into a custom GC handle class DartGodotInstanceBinding { public: - DartGodotInstanceBinding(void *token, GDExtensionObjectPtr godot_object) - : _is_refcounted(false), _is_weak(false), _persistent_handle(nullptr), _godot_object(godot_object), _token(token) { + DartGodotInstanceBinding(Dart_PersistentHandle dart_type, GDExtensionObjectPtr godot_object) + : _is_refcounted(false), _is_weak(false), _persistent_handle(nullptr), _godot_object(godot_object), _dart_type(dart_type) { } ~DartGodotInstanceBinding(); @@ -46,7 +46,7 @@ class DartGodotInstanceBinding { bool _is_weak; void *_persistent_handle; GDExtensionObjectPtr _godot_object; - void *_token; + Dart_PersistentHandle _dart_type; }; void gde_weak_finalizer(void *isolate_callback_data, void *peer); \ No newline at end of file diff --git a/src/cpp/gde_dart_converters.h b/src/cpp/gde_dart_converters.h index f8b3203..d5081d7 100644 --- a/src/cpp/gde_dart_converters.h +++ b/src/cpp/gde_dart_converters.h @@ -9,7 +9,6 @@ struct TypeInfo { // Can be null Dart_Handle parent_type = nullptr; GDExtensionVariantType variant_type = GDEXTENSION_VARIANT_TYPE_NIL; - void *binding_token = nullptr; // Can be null const GDExtensionInstanceBindingCallbacks *binding_callbacks = nullptr; }; diff --git a/src/cpp/script/dart_resource_format.h b/src/cpp/script/dart_resource_format.h index 85d7c55..a400a5f 100644 --- a/src/cpp/script/dart_resource_format.h +++ b/src/cpp/script/dart_resource_format.h @@ -11,13 +11,13 @@ class DartResourceFormatLoader : public godot::ResourceFormatLoader { public: DartResourceFormatLoader(); - virtual bool _handles_type(const godot::StringName& type) const override; - virtual godot::PackedStringArray _get_recognized_extensions() const override; - virtual bool _recognize_path(const godot::String &path, const godot::StringName &type) const override; - virtual godot::String _get_resource_type(const godot::String &path) const override; - virtual godot::String _get_resource_script_class(const godot::String &path) const override; - virtual bool _exists(const godot::String &path) const override; - virtual godot::Variant _load(const godot::String &path, const godot::String &original_path, bool use_sub_threads, + bool _handles_type(const godot::StringName& type) const override; + godot::PackedStringArray _get_recognized_extensions() const override; + bool _recognize_path(const godot::String &path, const godot::StringName &type) const override; + godot::String _get_resource_type(const godot::String &path) const override; + godot::String _get_resource_script_class(const godot::String &path) const override; + bool _exists(const godot::String &path) const override; + godot::Variant _load(const godot::String &path, const godot::String &original_path, bool use_sub_threads, int32_t cache_mode) const override; protected: @@ -30,10 +30,10 @@ class DartResourceFormatSaver : public godot::ResourceFormatSaver { GDCLASS(DartResourceFormatSaver, ResourceFormatSaver) public: - virtual godot::Error _save(const godot::Ref &resource, const godot::String &path, uint32_t flags); - virtual bool _recognize(const godot::Ref &resource) const override; - virtual bool _recognize_path(const godot::Ref &resource, const godot::String &path) const override; - virtual godot::PackedStringArray _get_recognized_extensions(const godot::Ref &resource) const; + godot::Error _save(const godot::Ref &resource, const godot::String &path, uint32_t flags) override; + bool _recognize(const godot::Ref &resource) const override; + bool _recognize_path(const godot::Ref &resource, const godot::String &path) const override; + godot::PackedStringArray _get_recognized_extensions(const godot::Ref &resource) const override; protected: static void _bind_methods(); diff --git a/src/cpp/script/dart_script.h b/src/cpp/script/dart_script.h index eeaeede..cb450ad 100644 --- a/src/cpp/script/dart_script.h +++ b/src/cpp/script/dart_script.h @@ -21,7 +21,7 @@ class DartScript : public godot::ScriptExtension { } godot::Ref