diff options
Diffstat (limited to 'core/object')
-rw-r--r-- | core/object/class_db.cpp | 11 | ||||
-rw-r--r-- | core/object/make_virtuals.py | 12 | ||||
-rw-r--r-- | core/object/method_bind.cpp | 4 | ||||
-rw-r--r-- | core/object/method_bind.h | 56 | ||||
-rw-r--r-- | core/object/object.cpp | 44 | ||||
-rw-r--r-- | core/object/object.h | 26 | ||||
-rw-r--r-- | core/object/ref_counted.cpp | 3 | ||||
-rw-r--r-- | core/object/ref_counted.h | 2 | ||||
-rw-r--r-- | core/object/script_language.cpp | 13 | ||||
-rw-r--r-- | core/object/script_language_extension.h | 7 | ||||
-rw-r--r-- | core/object/worker_thread_pool.cpp | 2 |
11 files changed, 86 insertions, 94 deletions
diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index 99b20560da..41585943b3 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -1528,7 +1528,10 @@ void ClassDB::register_extension_class(ObjectNativeExtension *p_extension) { c.api = p_extension->editor_class ? API_EDITOR_EXTENSION : API_EXTENSION; c.native_extension = p_extension; c.name = p_extension->class_name; - c.creation_func = parent->creation_func; + c.is_virtual = p_extension->is_virtual; + if (!p_extension->is_abstract) { + c.creation_func = parent->creation_func; + } c.inherits = parent->name; c.class_ptr = parent->class_ptr; c.inherits_ptr = parent; @@ -1538,7 +1541,11 @@ void ClassDB::register_extension_class(ObjectNativeExtension *p_extension) { } void ClassDB::unregister_extension_class(const StringName &p_class) { - ERR_FAIL_COND(!classes.has(p_class)); + ClassInfo *c = classes.getptr(p_class); + ERR_FAIL_COND_MSG(!c, "Class " + p_class + "does not exist"); + for (KeyValue<StringName, MethodBind *> &F : c->method_map) { + memdelete(F.value); + } classes.erase(p_class); } diff --git a/core/object/make_virtuals.py b/core/object/make_virtuals.py index c18d70d9f6..326a9277ff 100644 --- a/core/object/make_virtuals.py +++ b/core/object/make_virtuals.py @@ -5,11 +5,11 @@ mutable bool _gdvirtual_##m_name##_initialized = false;\\ mutable GDNativeExtensionClassCallVirtual _gdvirtual_##m_name = nullptr;\\ template<bool required>\\ _FORCE_INLINE_ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST { \\ - ScriptInstance *script_instance = ((Object*)(this))->get_script_instance();\\ - if (script_instance) {\\ + ScriptInstance *_script_instance = ((Object*)(this))->get_script_instance();\\ + if (_script_instance) {\\ Callable::CallError ce; \\ $CALLSIARGS\\ - $CALLSIBEGINscript_instance->callp(_gdvirtual_##m_name##_sn, $CALLSIARGPASS, ce);\\ + $CALLSIBEGIN_script_instance->callp(_gdvirtual_##m_name##_sn, $CALLSIARGPASS, ce);\\ if (ce.error == Callable::CallError::CALL_OK) {\\ $CALLSIRET\\ return true;\\ @@ -35,9 +35,9 @@ _FORCE_INLINE_ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST { \\ return false;\\ }\\ _FORCE_INLINE_ bool _gdvirtual_##m_name##_overridden() const { \\ - ScriptInstance *script_instance = ((Object*)(this))->get_script_instance();\\ - if (script_instance) {\\ - return script_instance->has_method(_gdvirtual_##m_name##_sn);\\ + ScriptInstance *_script_instance = ((Object*)(this))->get_script_instance();\\ + if (_script_instance) {\\ + return _script_instance->has_method(_gdvirtual_##m_name##_sn);\\ }\\ if (unlikely(_get_extension() && !_gdvirtual_##m_name##_initialized)) {\\ _gdvirtual_##m_name = (_get_extension() && _get_extension()->get_virtual) ? _get_extension()->get_virtual(_get_extension()->class_userdata, #m_name) : (GDNativeExtensionClassCallVirtual) nullptr;\\ diff --git a/core/object/method_bind.cpp b/core/object/method_bind.cpp index 0edc7a90c2..5381c596ce 100644 --- a/core/object/method_bind.cpp +++ b/core/object/method_bind.cpp @@ -63,7 +63,9 @@ PropertyInfo MethodBind::get_argument_info(int p_argument) const { PropertyInfo info = _gen_argument_type_info(p_argument); #ifdef DEBUG_METHODS_ENABLED - info.name = p_argument < arg_names.size() ? String(arg_names[p_argument]) : String("_unnamed_arg" + itos(p_argument)); + if (info.name.is_empty()) { + info.name = p_argument < arg_names.size() ? String(arg_names[p_argument]) : String("_unnamed_arg" + itos(p_argument)); + } #endif return info; } diff --git a/core/object/method_bind.h b/core/object/method_bind.h index d60550c899..598e8a224d 100644 --- a/core/object/method_bind.h +++ b/core/object/method_bind.h @@ -241,9 +241,17 @@ class MethodBindVarArgTR : public MethodBindVarArgBase<MethodBindVarArgTR<T, R>, friend class MethodBindVarArgBase<MethodBindVarArgTR<T, R>, T, R, true>; public: +#if defined(SANITIZERS_ENABLED) && defined(__GNUC__) && !defined(__clang__) + // Workaround GH-66343 raised only with UBSAN, seems to be a false positive. +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmaybe-uninitialized" +#endif virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) override { return (static_cast<T *>(p_object)->*MethodBindVarArgBase<MethodBindVarArgTR<T, R>, T, R, true>::method)(p_args, p_arg_count, r_error); } +#if defined(SANITIZERS_ENABLED) && defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif MethodBindVarArgTR( R (T::*p_method)(const Variant **, int, Callable::CallError &), @@ -284,11 +292,6 @@ class MethodBindT : public MethodBind { void (MB_T::*method)(P...); protected: -// GCC raises warnings in the case P = {} as the comparison is always false... -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wlogical-op" -#endif virtual Variant::Type _gen_argument_type(int p_arg) const override { if (p_arg >= 0 && p_arg < (int)sizeof...(P)) { return call_get_argument_type<P...>(p_arg); @@ -296,9 +299,6 @@ protected: return Variant::NIL; } } -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif virtual PropertyInfo _gen_argument_type_info(int p_arg) const override { PropertyInfo pi; @@ -359,11 +359,6 @@ class MethodBindTC : public MethodBind { void (MB_T::*method)(P...) const; protected: -// GCC raises warnings in the case P = {} as the comparison is always false... -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wlogical-op" -#endif virtual Variant::Type _gen_argument_type(int p_arg) const override { if (p_arg >= 0 && p_arg < (int)sizeof...(P)) { return call_get_argument_type<P...>(p_arg); @@ -371,9 +366,6 @@ protected: return Variant::NIL; } } -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif virtual PropertyInfo _gen_argument_type_info(int p_arg) const override { PropertyInfo pi; @@ -436,11 +428,6 @@ class MethodBindTR : public MethodBind { (P...); protected: -// GCC raises warnings in the case P = {} as the comparison is always false... -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wlogical-op" -#endif virtual Variant::Type _gen_argument_type(int p_arg) const override { if (p_arg >= 0 && p_arg < (int)sizeof...(P)) { return call_get_argument_type<P...>(p_arg); @@ -458,9 +445,6 @@ protected: return GetTypeInfo<R>::get_class_info(); } } -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif public: #ifdef DEBUG_METHODS_ENABLED @@ -523,11 +507,6 @@ class MethodBindTRC : public MethodBind { (P...) const; protected: -// GCC raises warnings in the case P = {} as the comparison is always false... -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wlogical-op" -#endif virtual Variant::Type _gen_argument_type(int p_arg) const override { if (p_arg >= 0 && p_arg < (int)sizeof...(P)) { return call_get_argument_type<P...>(p_arg); @@ -545,9 +524,6 @@ protected: return GetTypeInfo<R>::get_class_info(); } } -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif public: #ifdef DEBUG_METHODS_ENABLED @@ -607,11 +583,6 @@ class MethodBindTS : public MethodBind { void (*function)(P...); protected: -// GCC raises warnings in the case P = {} as the comparison is always false... -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wlogical-op" -#endif virtual Variant::Type _gen_argument_type(int p_arg) const override { if (p_arg >= 0 && p_arg < (int)sizeof...(P)) { return call_get_argument_type<P...>(p_arg); @@ -619,9 +590,6 @@ protected: return Variant::NIL; } } -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif virtual PropertyInfo _gen_argument_type_info(int p_arg) const override { PropertyInfo pi; @@ -670,11 +638,6 @@ class MethodBindTRS : public MethodBind { (P...); protected: -// GCC raises warnings in the case P = {} as the comparison is always false... -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wlogical-op" -#endif virtual Variant::Type _gen_argument_type(int p_arg) const override { if (p_arg >= 0 && p_arg < (int)sizeof...(P)) { return call_get_argument_type<P...>(p_arg); @@ -682,9 +645,6 @@ protected: return GetTypeInfo<R>::VARIANT_TYPE; } } -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic pop -#endif virtual PropertyInfo _gen_argument_type_info(int p_arg) const override { if (p_arg >= 0 && p_arg < (int)sizeof...(P)) { diff --git a/core/object/object.cpp b/core/object/object.cpp index c275164b14..540b9a8f19 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -1468,8 +1468,8 @@ void Object::_bind_methods() { ClassDB::bind_method(D_METHOD("is_class", "class"), &Object::is_class); ClassDB::bind_method(D_METHOD("set", "property", "value"), &Object::_set_bind); ClassDB::bind_method(D_METHOD("get", "property"), &Object::_get_bind); - ClassDB::bind_method(D_METHOD("set_indexed", "property", "value"), &Object::_set_indexed_bind); - ClassDB::bind_method(D_METHOD("get_indexed", "property"), &Object::_get_indexed_bind); + ClassDB::bind_method(D_METHOD("set_indexed", "property_path", "value"), &Object::_set_indexed_bind); + ClassDB::bind_method(D_METHOD("get_indexed", "property_path"), &Object::_get_indexed_bind); ClassDB::bind_method(D_METHOD("get_property_list"), &Object::_get_property_list_bind); ClassDB::bind_method(D_METHOD("get_method_list"), &Object::_get_method_list_bind); ClassDB::bind_method(D_METHOD("notification", "what", "reversed"), &Object::notification, DEFVAL(false)); @@ -1856,6 +1856,46 @@ void ObjectDB::debug_objects(DebugFunc p_func) { } void Object::get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const { + if (p_idx == 0) { + if (p_function == "connect" || p_function == "is_connected" || p_function == "disconnect" || p_function == "emit_signal" || p_function == "has_signal") { + List<MethodInfo> signals; + get_signal_list(&signals); + for (const MethodInfo &E : signals) { + r_options->push_back(E.name.quote()); + } + } else if (p_function == "call" || p_function == "call_deferred" || p_function == "callv" || p_function == "has_method") { + List<MethodInfo> methods; + get_method_list(&methods); + for (const MethodInfo &E : methods) { + if (E.name.begins_with("_") && !(E.flags & METHOD_FLAG_VIRTUAL)) { + continue; + } + r_options->push_back(E.name.quote()); + } + } else if (p_function == "set" || p_function == "set_deferred" || p_function == "get") { + List<PropertyInfo> properties; + get_property_list(&properties); + for (const PropertyInfo &E : properties) { + if (E.usage & PROPERTY_USAGE_DEFAULT && !(E.usage & PROPERTY_USAGE_INTERNAL)) { + r_options->push_back(E.name.quote()); + } + } + } else if (p_function == "set_meta" || p_function == "get_meta" || p_function == "has_meta" || p_function == "remove_meta") { + for (const KeyValue<StringName, Variant> &K : metadata) { + r_options->push_back(String(K.key).quote()); + } + } + } else if (p_idx == 2) { + if (p_function == "connect") { + // Ideally, the constants should be inferred by the parameter. + // But a parameter's PropertyInfo does not store the enum they come from, so this will do for now. + List<StringName> constants; + ClassDB::get_enum_constants("Object", "ConnectFlags", &constants); + for (const StringName &E : constants) { + r_options->push_back(String(E)); + } + } + } } SpinLock ObjectDB::spin_lock; diff --git a/core/object/object.h b/core/object/object.h index 8ade5a204a..359ab0f211 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -50,7 +50,7 @@ class TypedArray; enum PropertyHint { PROPERTY_HINT_NONE, ///< no hint provided. - PROPERTY_HINT_RANGE, ///< hint_text = "min,max[,step][,or_greater][,or_less][,no_slider][,radians][,degrees][,exp][,suffix:<keyword>] range. + PROPERTY_HINT_RANGE, ///< hint_text = "min,max[,step][,or_greater][,or_less][,hide_slider][,radians][,degrees][,exp][,suffix:<keyword>] range. PROPERTY_HINT_ENUM, ///< hint_text= "val1,val2,val3,etc" PROPERTY_HINT_ENUM_SUGGESTION, ///< hint_text= "val1,val2,val3,etc" PROPERTY_HINT_EXP_EASING, /// exponential easing function (Math::ease) use "attenuation" hint string to revert (flip h), "positive_only" to exclude in-out and out-in. (ie: "attenuation,positive_only") @@ -295,6 +295,8 @@ struct ObjectNativeExtension { StringName parent_class_name; StringName class_name; bool editor_class = false; + bool is_virtual = false; + bool is_abstract = false; GDNativeExtensionClassSet set; GDNativeExtensionClassGet get; GDNativeExtensionClassGetPropertyList get_property_list; @@ -733,34 +735,12 @@ public: template <class T> static T *cast_to(Object *p_object) { -#ifndef NO_SAFE_CAST return dynamic_cast<T *>(p_object); -#else - if (!p_object) { - return nullptr; - } - if (p_object->is_class_ptr(T::get_class_ptr_static())) { - return static_cast<T *>(p_object); - } else { - return nullptr; - } -#endif } template <class T> static const T *cast_to(const Object *p_object) { -#ifndef NO_SAFE_CAST return dynamic_cast<const T *>(p_object); -#else - if (!p_object) { - return nullptr; - } - if (p_object->is_class_ptr(T::get_class_ptr_static())) { - return static_cast<const T *>(p_object); - } else { - return nullptr; - } -#endif } enum { diff --git a/core/object/ref_counted.cpp b/core/object/ref_counted.cpp index cac2400744..50467d795d 100644 --- a/core/object/ref_counted.cpp +++ b/core/object/ref_counted.cpp @@ -48,9 +48,10 @@ void RefCounted::_bind_methods() { ClassDB::bind_method(D_METHOD("init_ref"), &RefCounted::init_ref); ClassDB::bind_method(D_METHOD("reference"), &RefCounted::reference); ClassDB::bind_method(D_METHOD("unreference"), &RefCounted::unreference); + ClassDB::bind_method(D_METHOD("get_reference_count"), &RefCounted::get_reference_count); } -int RefCounted::reference_get_count() const { +int RefCounted::get_reference_count() const { return refcount.get(); } diff --git a/core/object/ref_counted.h b/core/object/ref_counted.h index bd06a84bd8..71790fb825 100644 --- a/core/object/ref_counted.h +++ b/core/object/ref_counted.h @@ -47,7 +47,7 @@ public: bool init_ref(); bool reference(); // returns false if refcount is at zero and didn't get increased bool unreference(); - int reference_get_count() const; + int get_reference_count() const; RefCounted(); ~RefCounted() {} diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp index e56d2e80b9..9e26289e66 100644 --- a/core/object/script_language.cpp +++ b/core/object/script_language.cpp @@ -106,23 +106,23 @@ Dictionary Script::_get_script_constant_map() { PropertyInfo Script::get_class_category() const { String path = get_path(); - String name; + String scr_name; if (is_built_in()) { if (get_name().is_empty()) { - name = TTR("Built-in script"); + scr_name = TTR("Built-in script"); } else { - name = vformat("%s (%s)", get_name(), TTR("Built-in")); + scr_name = vformat("%s (%s)", get_name(), TTR("Built-in")); } } else { if (get_name().is_empty()) { - name = path.get_file(); + scr_name = path.get_file(); } else { - name = get_name(); + scr_name = get_name(); } } - return PropertyInfo(Variant::NIL, name, PROPERTY_HINT_NONE, path, PROPERTY_USAGE_CATEGORY); + return PropertyInfo(Variant::NIL, scr_name, PROPERTY_HINT_NONE, path, PROPERTY_USAGE_CATEGORY); } #endif // TOOLS_ENABLED @@ -166,6 +166,7 @@ ScriptLanguage *ScriptServer::get_language(int p_idx) { } void ScriptServer::register_language(ScriptLanguage *p_language) { + ERR_FAIL_NULL(p_language); ERR_FAIL_COND(_language_count >= MAX_LANGUAGES); _languages[_language_count++] = p_language; } diff --git a/core/object/script_language_extension.h b/core/object/script_language_extension.h index 7e74f6a2be..c32fb9d85b 100644 --- a/core/object/script_language_extension.h +++ b/core/object/script_language_extension.h @@ -82,9 +82,10 @@ public: GDVIRTUAL_REQUIRED_CALL(_get_documentation, doc); Vector<DocData::ClassDoc> class_doc; -#ifndef _MSC_VER -#warning missing conversion from documentation to ClassDoc -#endif + for (int i = 0; i < doc.size(); i++) { + class_doc.append(DocData::ClassDoc::from_dict(doc[i])); + } + return class_doc; } #endif // TOOLS_ENABLED diff --git a/core/object/worker_thread_pool.cpp b/core/object/worker_thread_pool.cpp index c770515b9e..9b3dc6833e 100644 --- a/core/object/worker_thread_pool.cpp +++ b/core/object/worker_thread_pool.cpp @@ -395,7 +395,7 @@ void WorkerThreadPool::wait_for_group_task_completion(GroupID p_group) { uint32_t finished_users = group->finished.increment(); // fetch happens before inc, so increment later. if (finished_users == max_users) { - // All tasks using this group are gone (finished before the group), so clear the gorup too. + // All tasks using this group are gone (finished before the group), so clear the group too. task_mutex.lock(); group_allocator.free(group); task_mutex.unlock(); |