From 33f9de16e414ad091fb6d4a6326f5cc435016ef9 Mon Sep 17 00:00:00 2001 From: sheepandshepherd Date: Mon, 21 Oct 2019 18:08:03 +0200 Subject: [PATCH] Use godot_object_cast_to instead of TagDB to cast engine types --- binding_generator.py | 12 ++++++++++++ include/core/Godot.hpp | 33 +++++++++++++++++++-------------- 2 files changed, 31 insertions(+), 14 deletions(-) diff --git a/binding_generator.py b/binding_generator.py index 13505dbe..2f175920 100644 --- a/binding_generator.py +++ b/binding_generator.py @@ -146,10 +146,14 @@ def generate_class_header(used_classes, c): source.append("\t};") source.append("\tstatic ___method_bindings ___mb;") + source.append("\tstatic void *_detail_class_tag;") source.append("") source.append("public:") source.append("\tstatic void ___init_method_bindings();") + # class id from core engine for casting + source.append("\tinline static size_t ___get_id() { return (size_t)_detail_class_tag; }") + source.append("") @@ -355,11 +359,19 @@ def generate_class_implementation(icalls, used_classes, c): source.append(class_name + "::___method_bindings " + class_name + "::___mb = {};") source.append("") + source.append("void *" + class_name + "::_detail_class_tag = nullptr;") + source.append("") + source.append("void " + class_name + "::___init_method_bindings() {") for method in c["methods"]: source.append("\t___mb.mb_" + method["name"] + " = godot::api->godot_method_bind_get_method(\"" + c["name"] + "\", \"" + method["name"] + "\");") + source.append("\tgodot_string_name class_name;") + source.append("\tgodot::api->godot_string_name_new_data(&class_name, \"" + c["name"] + "\");") + source.append("\t_detail_class_tag = godot::core_1_2_api->godot_get_class_tag(&class_name);") + source.append("\tgodot::api->godot_string_name_destroy(&class_name);") + source.append("}") source.append("") diff --git a/include/core/Godot.hpp b/include/core/Godot.hpp index ddf1e3e0..9d17a2b9 100644 --- a/include/core/Godot.hpp +++ b/include/core/Godot.hpp @@ -100,7 +100,7 @@ public: return godot::detail::create_custom_class_instance(); \ } \ inline static size_t ___get_id() { return typeid(Name).hash_code(); } \ - inline static size_t ___get_base_id() { return typeid(Base).hash_code(); } \ + inline static size_t ___get_base_id() { return Base::___get_id(); } \ inline static const char *___get_base_type_name() { return Base::___get_class_name(); } \ inline static godot::Object *___get_from_variant(godot::Variant a) { \ return (godot::Object *)godot::detail::get_custom_class_instance( \ @@ -513,23 +513,28 @@ T *Object::cast_to(const Object *obj) { if (!obj) return nullptr; - size_t have_tag = (size_t)godot::nativescript_1_1_api->godot_nativescript_get_type_tag(obj->_owner); + if (T::___CLASS_IS_SCRIPT) { + size_t have_tag = (size_t)godot::nativescript_1_1_api->godot_nativescript_get_type_tag(obj->_owner); + if (have_tag) { + if (!godot::_TagDB::is_type_known((size_t)have_tag)) { + have_tag = 0; + } + } - if (have_tag) { - if (!godot::_TagDB::is_type_known((size_t)have_tag)) { - have_tag = 0; + if (!have_tag) { + have_tag = obj->_type_tag; + } + + if (godot::_TagDB::is_type_compatible(T::___get_id(), have_tag)) { + return detail::get_custom_class_instance(obj); + } + } else { + if (godot::core_1_2_api->godot_object_cast_to(obj->_owner, (void *)T::___get_id())) { + return (T *)obj; } } - if (!have_tag) { - have_tag = obj->_type_tag; - } - - if (godot::_TagDB::is_type_compatible(typeid(T).hash_code(), have_tag)) { - return (T::___CLASS_IS_SCRIPT) ? detail::get_custom_class_instance(obj) : (T *)obj; - } else { - return nullptr; - } + return nullptr; } #endif