diff options
Diffstat (limited to 'core/object/object.h')
-rw-r--r-- | core/object/object.h | 149 |
1 files changed, 73 insertions, 76 deletions
diff --git a/core/object/object.h b/core/object/object.h index 218bc26dec..c3e3c68b59 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,30 +32,20 @@ #define OBJECT_H #include "core/extension/gdnative_interface.h" +#include "core/object/message_queue.h" #include "core/object/object_id.h" #include "core/os/rw_lock.h" #include "core/os/spin_lock.h" #include "core/templates/hash_map.h" #include "core/templates/list.h" #include "core/templates/map.h" +#include "core/templates/ordered_hash_map.h" #include "core/templates/safe_refcount.h" #include "core/templates/set.h" #include "core/templates/vmap.h" #include "core/variant/callable_bind.h" #include "core/variant/variant.h" -#define VARIANT_ARG_LIST const Variant &p_arg1 = Variant(), const Variant &p_arg2 = Variant(), const Variant &p_arg3 = Variant(), const Variant &p_arg4 = Variant(), const Variant &p_arg5 = Variant(), const Variant &p_arg6 = Variant(), const Variant &p_arg7 = Variant(), const Variant &p_arg8 = Variant() -#define VARIANT_ARG_PASS p_arg1, p_arg2, p_arg3, p_arg4, p_arg5, p_arg6, p_arg7, p_arg8 -#define VARIANT_ARG_DECLARE const Variant &p_arg1, const Variant &p_arg2, const Variant &p_arg3, const Variant &p_arg4, const Variant &p_arg5, const Variant &p_arg6, const Variant &p_arg7, const Variant &p_arg8 -#define VARIANT_ARG_MAX 8 -#define VARIANT_ARGPTRS const Variant *argptr[8] = { &p_arg1, &p_arg2, &p_arg3, &p_arg4, &p_arg5, &p_arg6, &p_arg7, &p_arg8 }; -#define VARIANT_ARGPTRS_PASS *argptr[0], *argptr[1], *argptr[2], *argptr[3], *argptr[4], *argptr[5], *argptr[6]], *argptr[7] -#define VARIANT_ARGS_FROM_ARRAY(m_arr) m_arr[0], m_arr[1], m_arr[2], m_arr[3], m_arr[4], m_arr[5], m_arr[6], m_arr[7] - -/** -@author Juan Linietsky <reduzio@gmail.com> -*/ - enum PropertyHint { PROPERTY_HINT_NONE, ///< no hint provided. PROPERTY_HINT_RANGE, ///< hint_text = "min,max[,step][,or_greater][,or_lesser][,noslider][,radians][,degrees][,exp][,suffix:<keyword>] range. @@ -98,6 +88,8 @@ enum PropertyHint { PROPERTY_HINT_INT_IS_OBJECTID, PROPERTY_HINT_ARRAY_TYPE, PROPERTY_HINT_INT_IS_POINTER, + PROPERTY_HINT_LOCALE_ID, + PROPERTY_HINT_LOCALIZABLE_STRING, PROPERTY_HINT_MAX, // When updating PropertyHint, also sync the hardcoded list in VisualScriptEditorVariableEdit }; @@ -145,7 +137,9 @@ enum PropertyUsageFlags { #define ADD_PROPERTYI(m_property, m_setter, m_getter, m_index) ::ClassDB::add_property(get_class_static(), m_property, _scs_create(m_setter), _scs_create(m_getter), m_index) #define ADD_PROPERTY_DEFAULT(m_property, m_default) ::ClassDB::set_property_default_value(get_class_static(), m_property, m_default) #define ADD_GROUP(m_name, m_prefix) ::ClassDB::add_property_group(get_class_static(), m_name, m_prefix) +#define ADD_GROUP_INDENT(m_name, m_prefix, m_depth) ::ClassDB::add_property_group(get_class_static(), m_name, m_prefix, m_depth) #define ADD_SUBGROUP(m_name, m_prefix) ::ClassDB::add_property_subgroup(get_class_static(), m_name, m_prefix) +#define ADD_SUBGROUP_INDENT(m_name, m_prefix, m_depth) ::ClassDB::add_property_subgroup(get_class_static(), m_name, m_prefix, m_depth) #define ADD_LINKED_PROPERTY(m_property, m_linked_property) ::ClassDB::add_linked_property(get_class_static(), m_property, m_linked_property) #define ADD_ARRAY_COUNT(m_label, m_count_property, m_count_property_setter, m_count_property_getter, m_prefix) ClassDB::add_property_array_count(get_class_static(), m_label, m_count_property, _scs_create(m_count_property_setter), _scs_create(m_count_property_getter), m_prefix) @@ -246,13 +240,7 @@ struct MethodInfo { MethodInfo(const PropertyInfo &p_ret, const String &p_name, const PropertyInfo &p_param1, const PropertyInfo &p_param2, const PropertyInfo &p_param3, const PropertyInfo &p_param4, const PropertyInfo &p_param5); }; -// old cast_to -//if ( is_type(T::get_class_static()) ) -//return static_cast<T*>(this); -////else -//return nullptr; - -// API used to extend in GDNative and other C compatible compiled languages +// API used to extend in GDNative and other C compatible compiled languages. class MethodBind; struct ObjectNativeExtension { @@ -269,6 +257,7 @@ struct ObjectNativeExtension { GDNativeExtensionClassToString to_string; GDNativeExtensionClassReference reference; GDNativeExtensionClassReference unreference; + GDNativeExtensionClassGetRID get_rid; _FORCE_INLINE_ bool is_class(const String &p_class) const { const ObjectNativeExtension *e = this; @@ -284,12 +273,15 @@ struct ObjectNativeExtension { GDNativeExtensionClassCreateInstance create_instance; GDNativeExtensionClassFreeInstance free_instance; - GDNativeExtensionClassObjectInstance set_object_instance; GDNativeExtensionClassGetVirtual get_virtual; }; -#define GDVIRTUAL_CALL(m_name, ...) _gdvirtual_##m_name##_call(__VA_ARGS__) -#define GDVIRTUAL_CALL_PTR(m_obj, m_name, ...) m_obj->_gdvirtual_##m_name##_call(__VA_ARGS__) +#define GDVIRTUAL_CALL(m_name, ...) _gdvirtual_##m_name##_call<false>(__VA_ARGS__) +#define GDVIRTUAL_CALL_PTR(m_obj, m_name, ...) m_obj->_gdvirtual_##m_name##_call<false>(__VA_ARGS__) + +#define GDVIRTUAL_REQUIRED_CALL(m_name, ...) _gdvirtual_##m_name##_call<true>(__VA_ARGS__) +#define GDVIRTUAL_REQUIRED_CALL_PTR(m_obj, m_name, ...) m_obj->_gdvirtual_##m_name##_call<true>(__VA_ARGS__) + #ifdef DEBUG_METHODS_ENABLED #define GDVIRTUAL_BIND(m_name, ...) ::ClassDB::add_virtual_method(get_class_static(), _gdvirtual_##m_name##_get_method_info(), true, sarray(__VA_ARGS__)); #else @@ -299,8 +291,10 @@ struct ObjectNativeExtension { #define GDVIRTUAL_IS_OVERRIDDEN_PTR(m_obj, m_name) m_obj->_gdvirtual_##m_name##_overridden() /* - the following is an incomprehensible blob of hacks and workarounds to compensate for many of the fallencies in C++. As a plus, this macro pretty much alone defines the object model. -*/ + * The following is an incomprehensible blob of hacks and workarounds to + * compensate for many of the fallacies in C++. As a plus, this macro pretty + * much alone defines the object model. + */ #define REVERSE_GET_PROPERTY_LIST \ public: \ @@ -350,19 +344,6 @@ public: m_inherits::get_inheritance_list_static(p_inheritance_list); \ p_inheritance_list->push_back(String(#m_class)); \ } \ - static String get_category_static() { \ - String category = m_inherits::get_category_static(); \ - if (_get_category != m_inherits::_get_category) { \ - if (category != "") { \ - category += "/"; \ - } \ - category += _get_category(); \ - } \ - return category; \ - } \ - static String inherits_static() { \ - return String(#m_inherits); \ - } \ virtual bool is_class(const String &p_class) const override { \ if (_get_extension() && _get_extension()->is_class(p_class)) { \ return true; \ @@ -463,12 +444,6 @@ protected: \ private: -#define OBJ_CATEGORY(m_category) \ -protected: \ - _FORCE_INLINE_ static String _get_category() { return m_category; } \ - \ -private: - #define OBJ_SAVE_TYPE(m_class) \ public: \ virtual String get_save_class() const override { return #m_class; } \ @@ -539,14 +514,15 @@ private: Set<String> editor_section_folding; #endif ScriptInstance *script_instance = nullptr; - Variant script; //reference does not yet exist, store it in a - Dictionary metadata; + Variant script; // Reference does not exist yet, store it in a Variant. + OrderedHashMap<StringName, Variant> metadata; + HashMap<StringName, OrderedHashMap<StringName, Variant>::Element> metadata_properties; mutable StringName _class_name; mutable const StringName *_class_ptr = nullptr; void _add_user_signal(const String &p_name, const Array &p_args = Array()); bool _has_user_signal(const StringName &p_name) const; - Variant _emit_signal(const Variant **p_args, int p_argcount, Callable::CallError &r_error); + Error _emit_signal(const Variant **p_args, int p_argcount, Callable::CallError &r_error); Array _get_signal_list() const; Array _get_signal_connection_list(const String &p_signal) const; Array _get_incoming_connections() const; @@ -562,8 +538,8 @@ private: std::mutex _instance_binding_mutex; struct InstanceBinding { - void *binding; - void *token; + void *binding = nullptr; + void *token = nullptr; GDNativeInstanceBindingFreeCallback free_callback = nullptr; GDNativeInstanceBindingReferenceCallback reference_callback = nullptr; }; @@ -588,6 +564,7 @@ protected: } return can_die; } + friend class NativeExtensionMethodBind; _ALWAYS_INLINE_ const ObjectNativeExtension *_get_extension() const { return _extension; } _ALWAYS_INLINE_ GDExtensionClassInstancePtr _get_extension_instance() const { return _extension_instance; } @@ -597,7 +574,6 @@ protected: virtual void _get_property_listv(List<PropertyInfo> *p_list, bool p_reversed) const {}; virtual void _notificationv(int p_notification, bool p_reversed) {} - static String _get_category() { return ""; } static void _bind_methods(); bool _set(const StringName &p_name, const Variant &p_property) { return false; }; bool _get(const StringName &p_name, Variant &r_property) const { return false; }; @@ -622,9 +598,6 @@ protected: static void get_valid_parents_static(List<String> *p_parents); static void _get_valid_parents_static(List<String> *p_parents); - //Variant _call_bind(const StringName& p_name, const Variant& p_arg1 = Variant(), const Variant& p_arg2 = Variant(), const Variant& p_arg3 = Variant(), const Variant& p_arg4 = Variant()); - //void _call_deferred_bind(const StringName& p_name, const Variant& p_arg1 = Variant(), const Variant& p_arg2 = Variant(), const Variant& p_arg3 = Variant(), const Variant& p_arg4 = Variant()); - Variant _call_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); Variant _call_deferred_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error); @@ -646,7 +619,7 @@ protected: void _disconnect(const StringName &p_signal, const Callable &p_callable, bool p_force = false); -public: //should be protected, but bug in clang++ +public: // Should be protected, but bug in clang++. static void initialize_class(); _FORCE_INLINE_ static void register_custom_data_to_otdb() {} @@ -660,6 +633,7 @@ public: bool _is_gpl_reversed() const { return false; } + void detach_from_objectdb(); _FORCE_INLINE_ ObjectID get_instance_id() const { return _instance_id; } template <class T> @@ -704,11 +678,11 @@ public: static String get_class_static() { return "Object"; } static String get_parent_class_static() { return String(); } - static String get_category_static() { return String(); } virtual String get_class() const { - if (_extension) + if (_extension) { return _extension->class_name.operator String(); + } return "Object"; } virtual String get_save_class() const { return get_class(); } //class stored when saving @@ -733,8 +707,6 @@ public: } /* IAPI */ - //void set(const String& p_name, const Variant& p_value); - //Variant get(const String& p_name) const; void set(const StringName &p_name, const Variant &p_value, bool *r_valid = nullptr); Variant get(const StringName &p_name, bool *r_valid = nullptr) const; @@ -746,13 +718,23 @@ public: bool has_method(const StringName &p_method) const; void get_method_list(List<MethodInfo> *p_list) const; Variant callv(const StringName &p_method, const Array &p_args); - virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); - Variant call(const StringName &p_name, VARIANT_ARG_LIST); // C++ helper + virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); + + template <typename... VarArgs> + Variant call(const StringName &p_method, VarArgs... p_args) { + Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported. + const Variant *argptrs[sizeof...(p_args) + 1]; + for (uint32_t i = 0; i < sizeof...(p_args); i++) { + argptrs[i] = &args[i]; + } + Callable::CallError cerr; + return callp(p_method, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args), cerr); + } void notification(int p_notification, bool p_reversed = false); virtual String to_string(); - //used mainly by script, get and set all INCLUDING string + // Used mainly by script, get and set all INCLUDING string. virtual Variant getvar(const Variant &p_key, bool *r_valid = nullptr) const; virtual void setvar(const Variant &p_key, const Variant &p_value, bool *r_valid = nullptr); @@ -761,28 +743,38 @@ public: void set_script(const Variant &p_script); Variant get_script() const; - /* SCRIPT */ - bool has_meta(const StringName &p_name) const; void set_meta(const StringName &p_name, const Variant &p_value); void remove_meta(const StringName &p_name); - Variant get_meta(const StringName &p_name) const; + Variant get_meta(const StringName &p_name, const Variant &p_default = Variant()) const; void get_meta_list(List<StringName> *p_list) const; #ifdef TOOLS_ENABLED void set_edited(bool p_edited); bool is_edited() const; - uint32_t get_edited_version() const; //this function is used to check when something changed beyond a point, it's used mainly for generating previews + // This function is used to check when something changed beyond a point, it's used mainly for generating previews. + uint32_t get_edited_version() const; #endif void set_script_instance(ScriptInstance *p_instance); _FORCE_INLINE_ ScriptInstance *get_script_instance() const { return script_instance; } - void set_script_and_instance(const Variant &p_script, ScriptInstance *p_instance); //some script languages can't control instance creation, so this function eases the process + // Some script languages can't control instance creation, so this function eases the process. + void set_script_and_instance(const Variant &p_script, ScriptInstance *p_instance); void add_user_signal(const MethodInfo &p_signal); - Error emit_signal(const StringName &p_name, VARIANT_ARG_LIST); - Error emit_signal(const StringName &p_name, const Variant **p_args, int p_argcount); + + template <typename... VarArgs> + Error emit_signal(const StringName &p_name, VarArgs... p_args) { + Variant args[sizeof...(p_args) + 1] = { p_args..., Variant() }; // +1 makes sure zero sized arrays are also supported. + const Variant *argptrs[sizeof...(p_args) + 1]; + for (uint32_t i = 0; i < sizeof...(p_args); i++) { + argptrs[i] = &args[i]; + } + return emit_signalp(p_name, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args)); + } + + Error emit_signalp(const StringName &p_name, const Variant **p_args, int p_argcount); bool has_signal(const StringName &p_name) const; void get_signal_list(List<MethodInfo> *p_signals) const; void get_signal_connection_list(const StringName &p_signal, List<Connection> *p_connections) const; @@ -794,7 +786,11 @@ public: void disconnect(const StringName &p_signal, const Callable &p_callable); bool is_connected(const StringName &p_signal, const Callable &p_callable) const; - void call_deferred(const StringName &p_method, VARIANT_ARG_LIST); + template <typename... VarArgs> + void call_deferred(const StringName &p_name, VarArgs... p_args) { + MessageQueue::get_singleton()->push_call(this, p_name, p_args...); + } + void set_deferred(const StringName &p_property, const Variant &p_value); void set_block_signals(bool p_block); @@ -807,10 +803,11 @@ public: virtual void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const; - String tr(const StringName &p_message, const StringName &p_context = "") const; // translate message (internationalization) + // Translate message (internationalization). + String tr(const StringName &p_message, const StringName &p_context = "") const; String tr_n(const StringName &p_message, const StringName &p_message_plural, int p_n, const StringName &p_context = "") const; - bool _is_queued_for_deletion = false; // set to true by SceneTree::queue_delete() + bool _is_queued_for_deletion = false; // Set to true by SceneTree::queue_delete(). bool is_queued_for_deletion() const; _FORCE_INLINE_ void set_message_translation(bool p_enable) { _can_translate = p_enable; } @@ -842,18 +839,18 @@ bool predelete_handler(Object *p_object); void postinitialize_handler(Object *p_object); class ObjectDB { -//this needs to add up to 63, 1 bit is for reference +// This needs to add up to 63, 1 bit is for reference. #define OBJECTDB_VALIDATOR_BITS 39 #define OBJECTDB_VALIDATOR_MASK ((uint64_t(1) << OBJECTDB_VALIDATOR_BITS) - 1) #define OBJECTDB_SLOT_MAX_COUNT_BITS 24 #define OBJECTDB_SLOT_MAX_COUNT_MASK ((uint64_t(1) << OBJECTDB_SLOT_MAX_COUNT_BITS) - 1) #define OBJECTDB_REFERENCE_BIT (uint64_t(1) << (OBJECTDB_SLOT_MAX_COUNT_BITS + OBJECTDB_VALIDATOR_BITS)) - struct ObjectSlot { //128 bits per slot + struct ObjectSlot { // 128 bits per slot. uint64_t validator : OBJECTDB_VALIDATOR_BITS; uint64_t next_free : OBJECTDB_SLOT_MAX_COUNT_BITS; uint64_t is_ref_counted : 1; - Object *object; + Object *object = nullptr; }; static SpinLock spin_lock; @@ -879,7 +876,7 @@ public: uint64_t id = p_instance_id; uint32_t slot = id & OBJECTDB_SLOT_MAX_COUNT_MASK; - ERR_FAIL_COND_V(slot >= slot_max, nullptr); //this should never happen unless RID is corrupted + ERR_FAIL_COND_V(slot >= slot_max, nullptr); // This should never happen unless RID is corrupted. spin_lock.lock(); |