From 051ef479c93c0c830b60059e3dabed6fc381cdd6 Mon Sep 17 00:00:00 2001 From: TechnoPorg Date: Tue, 25 Jan 2022 08:37:41 -0700 Subject: [PATCH] Allow method binds to take Object subclasses as arguments This commit adds a condition to VariantCaster that casts Variants of type OBJECT to any type T, if T is derived from Object. This change enables a fair bit of code cleanup. First, the Variant implicit cast operators for Node and Control can be removed, which allows for some invalid includes to be removed. Second, helper methods in Tree whose sole purpose was to cast arguments to TreeItem * are no longer necessary. A few small changes also had to be made to other files, due to the changes cascading down all the includes. --- core/io/resource.h | 2 + core/variant/binder_common.h | 50 +++++++++++-------- core/variant/variant.cpp | 20 +------- core/variant/variant.h | 4 -- doc/classes/Tree.xml | 8 +-- editor/editor_properties.cpp | 2 +- editor/plugins/canvas_item_editor_plugin.cpp | 2 +- editor/plugins/node_3d_editor_plugin.cpp | 4 +- editor/plugins/script_editor_plugin.cpp | 4 +- editor/rename_dialog.cpp | 2 +- .../language_server/gdscript_workspace.cpp | 2 +- scene/debugger/scene_debugger.h | 1 + scene/gui/tree.cpp | 8 +-- scene/gui/tree.h | 17 ------- tests/core/object/test_method_bind.h | 16 ++++++ 15 files changed, 64 insertions(+), 78 deletions(-) diff --git a/core/io/resource.h b/core/io/resource.h index a0800c57cba..dea21606161 100644 --- a/core/io/resource.h +++ b/core/io/resource.h @@ -37,6 +37,8 @@ #include "core/templates/safe_refcount.h" #include "core/templates/self_list.h" +class Node; + #define RES_BASE_EXTENSION(m_ext) \ public: \ static void register_custom_data_to_otdb() { ClassDB::add_resource_base_extension(m_ext, get_class_static()); } \ diff --git a/core/variant/binder_common.h b/core/variant/binder_common.h index 14f49d530cf..b6fdb4d9020 100644 --- a/core/variant/binder_common.h +++ b/core/variant/binder_common.h @@ -44,24 +44,42 @@ #include +// Variant cannot define an implicit cast operator for every Object subclass, so the +// casting is done here, to allow binding methods with parameters more specific than Object * + template struct VariantCaster { static _FORCE_INLINE_ T cast(const Variant &p_variant) { - return p_variant; + using TStripped = std::remove_pointer_t; + if constexpr (std::is_base_of::value) { + return Object::cast_to(p_variant); + } else { + return p_variant; + } } }; template struct VariantCaster { static _FORCE_INLINE_ T cast(const Variant &p_variant) { - return p_variant; + using TStripped = std::remove_pointer_t; + if constexpr (std::is_base_of::value) { + return Object::cast_to(p_variant); + } else { + return p_variant; + } } }; template struct VariantCaster { static _FORCE_INLINE_ T cast(const Variant &p_variant) { - return p_variant; + using TStripped = std::remove_pointer_t; + if constexpr (std::is_base_of::value) { + return Object::cast_to(p_variant); + } else { + return p_variant; + } } }; @@ -135,7 +153,13 @@ struct PtrToArg { template struct VariantObjectClassChecker { static _FORCE_INLINE_ bool check(const Variant &p_variant) { - return true; + using TStripped = std::remove_pointer_t; + if constexpr (std::is_base_of::value) { + Object *obj = p_variant; + return Object::cast_to(p_variant) || !obj; + } else { + return true; + } } }; @@ -151,24 +175,6 @@ struct VariantObjectClassChecker &> { } }; -template <> -struct VariantObjectClassChecker { - static _FORCE_INLINE_ bool check(const Variant &p_variant) { - Object *obj = p_variant; - Node *node = p_variant; - return node || !obj; - } -}; - -template <> -struct VariantObjectClassChecker { - static _FORCE_INLINE_ bool check(const Variant &p_variant) { - Object *obj = p_variant; - Control *control = p_variant; - return control || !obj; - } -}; - #ifdef DEBUG_METHODS_ENABLED template diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index db198da54a6..b85d7641f04 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -38,8 +38,6 @@ #include "core/math/math_funcs.h" #include "core/string/print_string.h" #include "core/variant/variant_parser.h" -#include "scene/gui/control.h" -#include "scene/main/node.h" String Variant::get_type_name(Variant::Type p_type) { switch (p_type) { @@ -2006,22 +2004,6 @@ Object *Variant::get_validated_object() const { } } -Variant::operator Node *() const { - if (type == OBJECT) { - return Object::cast_to(_get_obj().obj); - } else { - return nullptr; - } -} - -Variant::operator Control *() const { - if (type == OBJECT) { - return Object::cast_to(_get_obj().obj); - } else { - return nullptr; - } -} - Variant::operator Dictionary() const { if (type == DICTIONARY) { return *reinterpret_cast(_data._mem); @@ -3416,7 +3398,7 @@ String Variant::get_call_error_text(Object *p_base, const StringName &p_method, } String class_name = p_base->get_class(); - Ref