diff options
Diffstat (limited to 'core/object')
-rw-r--r-- | core/object/class_db.cpp | 22 | ||||
-rw-r--r-- | core/object/class_db.h | 4 | ||||
-rw-r--r-- | core/object/make_virtuals.py | 12 | ||||
-rw-r--r-- | core/object/method_bind.h | 34 | ||||
-rw-r--r-- | core/object/object.cpp | 21 | ||||
-rw-r--r-- | core/object/object.h | 114 | ||||
-rw-r--r-- | core/object/ref_counted.h | 3 | ||||
-rw-r--r-- | core/object/script_language.cpp | 6 | ||||
-rw-r--r-- | core/object/script_language_extension.h | 80 | ||||
-rw-r--r-- | core/object/undo_redo.cpp | 4 | ||||
-rw-r--r-- | core/object/undo_redo.h | 1 | ||||
-rw-r--r-- | core/object/worker_thread_pool.cpp | 4 |
12 files changed, 163 insertions, 142 deletions
diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index afde6863a3..529d99ec9a 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -318,7 +318,7 @@ Object *ClassDB::instantiate(const StringName &p_class) { { OBJTYPE_RLOCK; ti = classes.getptr(p_class); - if (!ti || ti->disabled || !ti->creation_func || (ti->native_extension && !ti->native_extension->create_instance)) { + if (!ti || ti->disabled || !ti->creation_func || (ti->gdextension && !ti->gdextension->create_instance)) { if (compat_classes.has(p_class)) { ti = classes.getptr(compat_classes[p_class]); } @@ -333,8 +333,8 @@ Object *ClassDB::instantiate(const StringName &p_class) { return nullptr; } #endif - if (ti->native_extension && ti->native_extension->create_instance) { - return (Object *)ti->native_extension->create_instance(ti->native_extension->class_userdata); + if (ti->gdextension && ti->gdextension->create_instance) { + return (Object *)ti->gdextension->create_instance(ti->gdextension->class_userdata); } else { return ti->creation_func(); } @@ -346,17 +346,17 @@ void ClassDB::set_object_extension_instance(Object *p_object, const StringName & { OBJTYPE_RLOCK; ti = classes.getptr(p_class); - if (!ti || ti->disabled || !ti->creation_func || (ti->native_extension && !ti->native_extension->create_instance)) { + if (!ti || ti->disabled || !ti->creation_func || (ti->gdextension && !ti->gdextension->create_instance)) { if (compat_classes.has(p_class)) { ti = classes.getptr(compat_classes[p_class]); } } ERR_FAIL_COND_MSG(!ti, "Cannot get class '" + String(p_class) + "'."); ERR_FAIL_COND_MSG(ti->disabled, "Class '" + String(p_class) + "' is disabled."); - ERR_FAIL_COND_MSG(!ti->native_extension, "Class '" + String(p_class) + "' has no native extension."); + ERR_FAIL_COND_MSG(!ti->gdextension, "Class '" + String(p_class) + "' has no native extension."); } - p_object->_extension = ti->native_extension; + p_object->_extension = ti->gdextension; p_object->_extension_instance = p_instance; } @@ -370,7 +370,7 @@ bool ClassDB::can_instantiate(const StringName &p_class) { return false; } #endif - return (!ti->disabled && ti->creation_func != nullptr && !(ti->native_extension && !ti->native_extension->create_instance)); + return (!ti->disabled && ti->creation_func != nullptr && !(ti->gdextension && !ti->gdextension->create_instance)); } bool ClassDB::is_virtual(const StringName &p_class) { @@ -388,7 +388,7 @@ bool ClassDB::is_virtual(const StringName &p_class) { return false; } #endif - return (!ti->disabled && ti->creation_func != nullptr && !(ti->native_extension && !ti->native_extension->create_instance) && ti->is_virtual); + return (!ti->disabled && ti->creation_func != nullptr && !(ti->gdextension && !ti->gdextension->create_instance) && ti->is_virtual); } void ClassDB::_add_class2(const StringName &p_class, const StringName &p_inherits) { @@ -1460,7 +1460,7 @@ Variant ClassDB::class_get_default_property_value(const StringName &p_class, con if (Engine::get_singleton()->has_singleton(p_class)) { c = Engine::get_singleton()->get_singleton_object(p_class); cleanup_c = false; - } else if (ClassDB::can_instantiate(p_class)) { // Keep this condition in sync with doc_tools.cpp get_documentation_default_value. + } else if (ClassDB::can_instantiate(p_class) && !ClassDB::is_virtual(p_class)) { // Keep this condition in sync with doc_tools.cpp get_documentation_default_value. c = ClassDB::instantiate(p_class); cleanup_c = true; } @@ -1522,7 +1522,7 @@ Variant ClassDB::class_get_default_property_value(const StringName &p_class, con return var; } -void ClassDB::register_extension_class(ObjectNativeExtension *p_extension) { +void ClassDB::register_extension_class(ObjectGDExtension *p_extension) { GLOBAL_LOCK_FUNCTION; ERR_FAIL_COND_MSG(classes.has(p_extension->class_name), "Class already registered: " + String(p_extension->class_name)); @@ -1532,7 +1532,7 @@ void ClassDB::register_extension_class(ObjectNativeExtension *p_extension) { ClassInfo c; c.api = p_extension->editor_class ? API_EDITOR_EXTENSION : API_EXTENSION; - c.native_extension = p_extension; + c.gdextension = p_extension; c.name = p_extension->class_name; c.is_virtual = p_extension->is_virtual; if (!p_extension->is_abstract) { diff --git a/core/object/class_db.h b/core/object/class_db.h index 5fba52e23e..4b60079298 100644 --- a/core/object/class_db.h +++ b/core/object/class_db.h @@ -100,7 +100,7 @@ public: ClassInfo *inherits_ptr = nullptr; void *class_ptr = nullptr; - ObjectNativeExtension *native_extension = nullptr; + ObjectGDExtension *gdextension = nullptr; HashMap<StringName, MethodBind *> method_map; HashMap<StringName, int64_t> constant_map; @@ -203,7 +203,7 @@ public: //nothing } - static void register_extension_class(ObjectNativeExtension *p_extension); + static void register_extension_class(ObjectGDExtension *p_extension); static void unregister_extension_class(const StringName &p_class); template <class T> diff --git a/core/object/make_virtuals.py b/core/object/make_virtuals.py index 326a9277ff..0ee95835a6 100644 --- a/core/object/make_virtuals.py +++ b/core/object/make_virtuals.py @@ -2,7 +2,7 @@ proto = """ #define GDVIRTUAL$VER($RET m_name $ARG) \\ StringName _gdvirtual_##m_name##_sn = #m_name;\\ mutable bool _gdvirtual_##m_name##_initialized = false;\\ -mutable GDNativeExtensionClassCallVirtual _gdvirtual_##m_name = nullptr;\\ +mutable GDExtensionClassCallVirtual _gdvirtual_##m_name = nullptr;\\ template<bool required>\\ _FORCE_INLINE_ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST { \\ ScriptInstance *_script_instance = ((Object*)(this))->get_script_instance();\\ @@ -16,7 +16,8 @@ _FORCE_INLINE_ bool _gdvirtual_##m_name##_call($CALLARGS) $CONST { \\ } \\ }\\ 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;\\ + /* TODO: C-style cast because GDExtensionStringNamePtr's const qualifier is broken (see https://github.com/godotengine/godot/pull/67751) */\\ + _gdvirtual_##m_name = (_get_extension() && _get_extension()->get_virtual) ? _get_extension()->get_virtual(_get_extension()->class_userdata, (GDExtensionStringNamePtr)&_gdvirtual_##m_name##_sn) : (GDExtensionClassCallVirtual) nullptr;\\ _gdvirtual_##m_name##_initialized = true;\\ }\\ if (_gdvirtual_##m_name) {\\ @@ -40,7 +41,8 @@ _FORCE_INLINE_ bool _gdvirtual_##m_name##_overridden() const { \\ 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;\\ + /* TODO: C-style cast because GDExtensionStringNamePtr's const qualifier is broken (see https://github.com/godotengine/godot/pull/67751) */\\ + _gdvirtual_##m_name = (_get_extension() && _get_extension()->get_virtual) ? _get_extension()->get_virtual(_get_extension()->class_userdata, (GDExtensionStringNamePtr)&_gdvirtual_##m_name##_sn) : (GDExtensionClassCallVirtual) nullptr;\\ _gdvirtual_##m_name##_initialized = true;\\ }\\ if (_gdvirtual_##m_name) {\\ @@ -92,7 +94,7 @@ def generate_version(argcount, const=False, returns=False): argtext += ", " callsiargs = "Variant vargs[" + str(argcount) + "]={" callsiargptrs = "\t\tconst Variant *vargptrs[" + str(argcount) + "]={" - callptrargsptr = "\t\tconst GDNativeTypePtr argptrs[" + str(argcount) + "]={" + callptrargsptr = "\t\tGDExtensionConstTypePtr argptrs[" + str(argcount) + "]={" callptrargs = "" for i in range(argcount): if i > 0: @@ -119,7 +121,7 @@ def generate_version(argcount, const=False, returns=False): s = s.replace("$CALLSIARGPASS", "(const Variant **)vargptrs," + str(argcount)) callptrargsptr += "};\\\n" s = s.replace("$CALLPTRARGS", callptrargs + callptrargsptr) - s = s.replace("$CALLPTRARGPASS", "(const GDNativeTypePtr*)argptrs") + s = s.replace("$CALLPTRARGPASS", "reinterpret_cast<GDExtensionConstTypePtr*>(argptrs)") else: s = s.replace("$CALLSIARGS", "") s = s.replace("$CALLSIARGPASS", "nullptr, 0") diff --git a/core/object/method_bind.h b/core/object/method_bind.h index 598e8a224d..0f1366aefd 100644 --- a/core/object/method_bind.h +++ b/core/object/method_bind.h @@ -110,8 +110,8 @@ public: _FORCE_INLINE_ int get_argument_count() const { return argument_count; }; - virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) = 0; - virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) = 0; + virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const = 0; + virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const = 0; StringName get_name() const; void set_name(const StringName &p_name); @@ -158,7 +158,7 @@ public: } #endif - virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) override { + virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override { ERR_FAIL(); // Can't call. } @@ -210,7 +210,7 @@ class MethodBindVarArgT : public MethodBindVarArgBase<MethodBindVarArgT<T>, T, v friend class MethodBindVarArgBase<MethodBindVarArgT<T>, T, void, false>; public: - virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) override { + virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override { (static_cast<T *>(p_object)->*MethodBindVarArgBase<MethodBindVarArgT<T>, T, void, false>::method)(p_args, p_arg_count, r_error); return {}; } @@ -246,7 +246,7 @@ public: #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 { + virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const 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__) @@ -313,7 +313,7 @@ public: } #endif - virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) override { + virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override { #ifdef TYPED_METHOD_BIND call_with_variant_args_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, r_error, get_default_arguments()); #else @@ -322,7 +322,7 @@ public: return Variant(); } - virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) override { + virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override { #ifdef TYPED_METHOD_BIND call_with_ptr_args<T, P...>(static_cast<T *>(p_object), method, p_args); #else @@ -380,7 +380,7 @@ public: } #endif - virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) override { + virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override { #ifdef TYPED_METHOD_BIND call_with_variant_argsc_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, r_error, get_default_arguments()); #else @@ -389,7 +389,7 @@ public: return Variant(); } - virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) override { + virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override { #ifdef TYPED_METHOD_BIND call_with_ptr_argsc<T, P...>(static_cast<T *>(p_object), method, p_args); #else @@ -457,7 +457,7 @@ public: } #endif - virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) override { + virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override { Variant ret; #ifdef TYPED_METHOD_BIND call_with_variant_args_ret_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, ret, r_error, get_default_arguments()); @@ -467,7 +467,7 @@ public: return ret; } - virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) override { + virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override { #ifdef TYPED_METHOD_BIND call_with_ptr_args_ret<T, R, P...>(static_cast<T *>(p_object), method, p_args, r_ret); #else @@ -536,7 +536,7 @@ public: } #endif - virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) override { + virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override { Variant ret; #ifdef TYPED_METHOD_BIND call_with_variant_args_retc_dv(static_cast<T *>(p_object), method, p_args, p_arg_count, ret, r_error, get_default_arguments()); @@ -546,7 +546,7 @@ public: return ret; } - virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) override { + virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override { #ifdef TYPED_METHOD_BIND call_with_ptr_args_retc<T, R, P...>(static_cast<T *>(p_object), method, p_args, r_ret); #else @@ -604,13 +604,13 @@ public: } #endif - virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) override { + virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override { (void)p_object; // unused call_with_variant_args_static_dv(function, p_args, p_arg_count, r_error, get_default_arguments()); return Variant(); } - virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) override { + virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override { (void)p_object; (void)r_ret; call_with_ptr_args_static_method(function, p_args); @@ -667,13 +667,13 @@ public: } #endif - virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) override { + virtual Variant call(Object *p_object, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) const override { Variant ret; call_with_variant_args_static_ret_dv(function, p_args, p_arg_count, ret, r_error, get_default_arguments()); return ret; } - virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) override { + virtual void ptrcall(Object *p_object, const void **p_args, void *r_ret) const override { (void)p_object; call_with_ptr_args_static_method_ret(function, p_args, r_ret); } diff --git a/core/object/object.cpp b/core/object/object.cpp index 540b9a8f19..cfac36127c 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -233,7 +233,7 @@ void Object::set(const StringName &p_name, const Variant &p_value, bool *r_valid #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wignored-qualifiers" #endif - if (_extension->set(_extension_instance, (const GDNativeStringNamePtr)&p_name, (const GDNativeVariantPtr)&p_value)) { + if (_extension->set(_extension_instance, (const GDExtensionStringNamePtr)&p_name, (const GDExtensionVariantPtr)&p_value)) { if (r_valid) { *r_valid = true; } @@ -321,7 +321,7 @@ Variant Object::get(const StringName &p_name, bool *r_valid) const { #pragma GCC diagnostic ignored "-Wignored-qualifiers" #endif - if (_extension->get(_extension_instance, (const GDNativeStringNamePtr)&p_name, (GDNativeVariantPtr)&ret)) { + if (_extension->get(_extension_instance, (const GDExtensionStringNamePtr)&p_name, (GDExtensionVariantPtr)&ret)) { if (r_valid) { *r_valid = true; } @@ -477,7 +477,7 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons } if (_extension) { - const ObjectNativeExtension *current_extension = _extension; + const ObjectGDExtension *current_extension = _extension; while (current_extension) { p_list->push_back(PropertyInfo(Variant::NIL, current_extension->class_name, PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_CATEGORY)); ClassDB::get_property_list(current_extension->class_name, p_list, true, this); @@ -487,7 +487,7 @@ void Object::get_property_list(List<PropertyInfo> *p_list, bool p_reversed) cons if (_extension && _extension->get_property_list) { uint32_t pcount; - const GDNativePropertyInfo *pinfo = _extension->get_property_list(_extension_instance, &pcount); + const GDExtensionPropertyInfo *pinfo = _extension->get_property_list(_extension_instance, &pcount); for (uint32_t i = 0; i < pcount; i++) { p_list->push_back(PropertyInfo(pinfo[i])); } @@ -533,7 +533,7 @@ bool Object::property_can_revert(const StringName &p_name) const { #pragma GCC diagnostic ignored "-Wignored-qualifiers" #endif if (_extension && _extension->property_can_revert) { - if (_extension->property_can_revert(_extension_instance, (const GDNativeStringNamePtr)&p_name)) { + if (_extension->property_can_revert(_extension_instance, (const GDExtensionStringNamePtr)&p_name)) { return true; } } @@ -559,7 +559,7 @@ Variant Object::property_get_revert(const StringName &p_name) const { #pragma GCC diagnostic ignored "-Wignored-qualifiers" #endif if (_extension && _extension->property_get_revert) { - if (_extension->property_get_revert(_extension_instance, (const GDNativeStringNamePtr)&p_name, (GDNativeVariantPtr)&ret)) { + if (_extension->property_get_revert(_extension_instance, (const GDExtensionStringNamePtr)&p_name, (GDExtensionVariantPtr)&ret)) { return ret; } } @@ -808,7 +808,8 @@ String Object::to_string() { } if (_extension && _extension->to_string) { String ret; - _extension->to_string(_extension_instance, &ret); + GDExtensionBool is_valid; + _extension->to_string(_extension_instance, &is_valid, &ret); return ret; } return "<" + get_class() + "#" + itos(get_instance_id()) + ">"; @@ -1472,6 +1473,8 @@ void Object::_bind_methods() { 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("property_can_revert", "property"), &Object::property_can_revert); + ClassDB::bind_method(D_METHOD("property_get_revert", "property"), &Object::property_get_revert); ClassDB::bind_method(D_METHOD("notification", "what", "reversed"), &Object::notification, DEFVAL(false)); ClassDB::bind_method(D_METHOD("to_string"), &Object::to_string); ClassDB::bind_method(D_METHOD("get_instance_id"), &Object::get_instance_id); @@ -1698,7 +1701,7 @@ uint32_t Object::get_edited_version() const { } #endif -void Object::set_instance_binding(void *p_token, void *p_binding, const GDNativeInstanceBindingCallbacks *p_callbacks) { +void Object::set_instance_binding(void *p_token, void *p_binding, const GDExtensionInstanceBindingCallbacks *p_callbacks) { // This is only meant to be used on creation by the binder. ERR_FAIL_COND(_instance_bindings != nullptr); _instance_bindings = (InstanceBinding *)memalloc(sizeof(InstanceBinding)); @@ -1709,7 +1712,7 @@ void Object::set_instance_binding(void *p_token, void *p_binding, const GDNative _instance_binding_count = 1; } -void *Object::get_instance_binding(void *p_token, const GDNativeInstanceBindingCallbacks *p_callbacks) { +void *Object::get_instance_binding(void *p_token, const GDExtensionInstanceBindingCallbacks *p_callbacks) { void *binding = nullptr; _instance_binding_mutex.lock(); for (uint32_t i = 0; i < _instance_binding_count; i++) { diff --git a/core/object/object.h b/core/object/object.h index 8c647cda40..d52cf7d62e 100644 --- a/core/object/object.h +++ b/core/object/object.h @@ -31,7 +31,7 @@ #ifndef OBJECT_H #define OBJECT_H -#include "core/extension/gdnative_interface.h" +#include "core/extension/gdextension_interface.h" #include "core/object/message_queue.h" #include "core/object/object_id.h" #include "core/os/rw_lock.h" @@ -71,8 +71,6 @@ enum PropertyHint { PROPERTY_HINT_EXPRESSION, ///< used for string properties that can contain multiple lines PROPERTY_HINT_PLACEHOLDER_TEXT, ///< used to set a placeholder text for string properties PROPERTY_HINT_COLOR_NO_ALPHA, ///< used for ignoring alpha component when editing a color - PROPERTY_HINT_IMAGE_COMPRESS_LOSSY, - PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS, PROPERTY_HINT_OBJECT_ID, PROPERTY_HINT_TYPE_STRING, ///< a type string, the hint is the base type to choose PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE, ///< so something else can provide this (used in scripts) @@ -115,22 +113,21 @@ enum PropertyUsageFlags { PROPERTY_USAGE_RESTART_IF_CHANGED = 1 << 11, PROPERTY_USAGE_SCRIPT_VARIABLE = 1 << 12, PROPERTY_USAGE_STORE_IF_NULL = 1 << 13, - PROPERTY_USAGE_ANIMATE_AS_TRIGGER = 1 << 14, - PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED = 1 << 15, - PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE = 1 << 16, - PROPERTY_USAGE_CLASS_IS_ENUM = 1 << 17, - PROPERTY_USAGE_NIL_IS_VARIANT = 1 << 18, - PROPERTY_USAGE_INTERNAL = 1 << 19, - PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE = 1 << 20, // If the object is duplicated also this property will be duplicated. - PROPERTY_USAGE_HIGH_END_GFX = 1 << 21, - PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT = 1 << 22, - PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT = 1 << 23, - PROPERTY_USAGE_KEYING_INCREMENTS = 1 << 24, // Used in inspector to increment property when keyed in animation player. - PROPERTY_USAGE_DEFERRED_SET_RESOURCE = 1 << 25, // when loading, the resource for this property can be set at the end of loading. - PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT = 1 << 26, // For Object properties, instantiate them when creating in editor. - PROPERTY_USAGE_EDITOR_BASIC_SETTING = 1 << 27, //for project or editor settings, show when basic settings are selected. - PROPERTY_USAGE_READ_ONLY = 1 << 28, // Mark a property as read-only in the inspector. - PROPERTY_USAGE_ARRAY = 1 << 29, // Used in the inspector to group properties as elements of an array. + PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED = 1 << 14, + PROPERTY_USAGE_SCRIPT_DEFAULT_VALUE = 1 << 15, + PROPERTY_USAGE_CLASS_IS_ENUM = 1 << 16, + PROPERTY_USAGE_NIL_IS_VARIANT = 1 << 17, + PROPERTY_USAGE_INTERNAL = 1 << 18, + PROPERTY_USAGE_DO_NOT_SHARE_ON_DUPLICATE = 1 << 19, // If the object is duplicated also this property will be duplicated. + PROPERTY_USAGE_HIGH_END_GFX = 1 << 20, + PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT = 1 << 21, + PROPERTY_USAGE_RESOURCE_NOT_PERSISTENT = 1 << 22, + PROPERTY_USAGE_KEYING_INCREMENTS = 1 << 23, // Used in inspector to increment property when keyed in animation player. + PROPERTY_USAGE_DEFERRED_SET_RESOURCE = 1 << 24, // when loading, the resource for this property can be set at the end of loading. + PROPERTY_USAGE_EDITOR_INSTANTIATE_OBJECT = 1 << 25, // For Object properties, instantiate them when creating in editor. + PROPERTY_USAGE_EDITOR_BASIC_SETTING = 1 << 26, //for project or editor settings, show when basic settings are selected. + PROPERTY_USAGE_READ_ONLY = 1 << 27, // Mark a property as read-only in the inspector. + PROPERTY_USAGE_ARRAY = 1 << 28, // Used in the inspector to group properties as elements of an array. PROPERTY_USAGE_DEFAULT = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR, PROPERTY_USAGE_DEFAULT_INTL = PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNATIONALIZED, @@ -151,6 +148,10 @@ enum PropertyUsageFlags { #define ADD_ARRAY_COUNT_WITH_USAGE_FLAGS(m_label, m_count_property, m_count_property_setter, m_count_property_getter, m_prefix, m_property_usage_flags) 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, m_property_usage_flags) #define ADD_ARRAY(m_array_path, m_prefix) ClassDB::add_property_array(get_class_static(), m_array_path, m_prefix) +// Helper macro to use with PROPERTY_HINT_ARRAY_TYPE for arrays of specific resources: +// PropertyInfo(Variant::ARRAY, "fallbacks", PROPERTY_HINT_ARRAY_TYPE, MAKE_RESOURCE_TYPE_HINT("Font") +#define MAKE_RESOURCE_TYPE_HINT(m_type) vformat("%s/%s:%s", Variant::OBJECT, PROPERTY_HINT_RESOURCE_TYPE, m_type) + struct PropertyInfo { Variant::Type type = Variant::NIL; String name; @@ -190,12 +191,12 @@ struct PropertyInfo { type(Variant::OBJECT), class_name(p_class_name) {} - explicit PropertyInfo(const GDNativePropertyInfo &pinfo) : + explicit PropertyInfo(const GDExtensionPropertyInfo &pinfo) : type((Variant::Type)pinfo.type), - name(pinfo.name), - class_name(pinfo.class_name), // can be null + name(*reinterpret_cast<StringName *>(pinfo.name)), + class_name(*reinterpret_cast<StringName *>(pinfo.class_name)), hint((PropertyHint)pinfo.hint), - hint_string(pinfo.hint_string), // can be null + hint_string(*reinterpret_cast<String *>(pinfo.hint_string)), usage(pinfo.usage) {} bool operator==(const PropertyInfo &p_info) const { @@ -242,6 +243,20 @@ struct MethodInfo { MethodInfo() {} + explicit MethodInfo(const GDExtensionMethodInfo &pinfo) : + name(*reinterpret_cast<StringName *>(pinfo.name)), + return_val(PropertyInfo(pinfo.return_value)), + flags(pinfo.flags), + id(pinfo.id) { + for (uint32_t j = 0; j < pinfo.argument_count; j++) { + arguments.push_back(PropertyInfo(pinfo.arguments[j])); + } + const Variant *def_values = (const Variant *)pinfo.default_arguments; + for (uint32_t j = 0; j < pinfo.default_argument_count; j++) { + default_arguments.push_back(def_values[j]); + } + } + void _push_params(const PropertyInfo &p_param) { arguments.push_back(p_param); } @@ -286,31 +301,31 @@ struct MethodInfo { } }; -// API used to extend in GDNative and other C compatible compiled languages. +// API used to extend in GDExtension and other C compatible compiled languages. class MethodBind; -struct ObjectNativeExtension { - ObjectNativeExtension *parent = nullptr; - List<ObjectNativeExtension *> children; +struct ObjectGDExtension { + ObjectGDExtension *parent = nullptr; + List<ObjectGDExtension *> children; 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; - GDNativeExtensionClassFreePropertyList free_property_list; - GDNativeExtensionClassPropertyCanRevert property_can_revert; - GDNativeExtensionClassPropertyGetRevert property_get_revert; - GDNativeExtensionClassNotification notification; - GDNativeExtensionClassToString to_string; - GDNativeExtensionClassReference reference; - GDNativeExtensionClassReference unreference; - GDNativeExtensionClassGetRID get_rid; + GDExtensionClassSet set; + GDExtensionClassGet get; + GDExtensionClassGetPropertyList get_property_list; + GDExtensionClassFreePropertyList free_property_list; + GDExtensionClassPropertyCanRevert property_can_revert; + GDExtensionClassPropertyGetRevert property_get_revert; + GDExtensionClassNotification notification; + GDExtensionClassToString to_string; + GDExtensionClassReference reference; + GDExtensionClassReference unreference; + GDExtensionClassGetRID get_rid; _FORCE_INLINE_ bool is_class(const String &p_class) const { - const ObjectNativeExtension *e = this; + const ObjectGDExtension *e = this; while (e) { if (p_class == e->class_name.operator String()) { return true; @@ -321,9 +336,9 @@ struct ObjectNativeExtension { } void *class_userdata = nullptr; - GDNativeExtensionClassCreateInstance create_instance; - GDNativeExtensionClassFreeInstance free_instance; - GDNativeExtensionClassGetVirtual get_virtual; + GDExtensionClassCreateInstance create_instance; + GDExtensionClassFreeInstance free_instance; + GDExtensionClassGetVirtual get_virtual; }; #define GDVIRTUAL_CALL(m_name, ...) _gdvirtual_##m_name##_call<false>(__VA_ARGS__) @@ -541,6 +556,7 @@ public: CONNECT_PERSIST = 2, // hint for scene to save this connection CONNECT_ONE_SHOT = 4, CONNECT_REFERENCE_COUNTED = 8, + CONNECT_INHERITED = 16, // Used in editor builds. }; struct Connection { @@ -563,7 +579,7 @@ private: friend bool predelete_handler(Object *); friend void postinitialize_handler(Object *); - ObjectNativeExtension *_extension = nullptr; + ObjectGDExtension *_extension = nullptr; GDExtensionClassInstancePtr _extension_instance = nullptr; struct SignalData { @@ -621,8 +637,8 @@ private: struct InstanceBinding { void *binding = nullptr; void *token = nullptr; - GDNativeInstanceBindingFreeCallback free_callback = nullptr; - GDNativeInstanceBindingReferenceCallback reference_callback = nullptr; + GDExtensionInstanceBindingFreeCallback free_callback = nullptr; + GDExtensionInstanceBindingReferenceCallback reference_callback = nullptr; }; InstanceBinding *_instance_bindings = nullptr; uint32_t _instance_binding_count = 0; @@ -646,8 +662,8 @@ protected: return can_die; } - friend class NativeExtensionMethodBind; - _ALWAYS_INLINE_ const ObjectNativeExtension *_get_extension() const { return _extension; } + friend class GDExtensionMethodBind; + _ALWAYS_INLINE_ const ObjectGDExtension *_get_extension() const { return _extension; } _ALWAYS_INLINE_ GDExtensionClassInstancePtr _get_extension_instance() const { return _extension_instance; } virtual void _initialize_classv() { initialize_class(); } virtual bool _setv(const StringName &p_name, const Variant &p_property) { return false; }; @@ -901,9 +917,9 @@ public: #endif // Used by script languages to store binding data. - void *get_instance_binding(void *p_token, const GDNativeInstanceBindingCallbacks *p_callbacks); + void *get_instance_binding(void *p_token, const GDExtensionInstanceBindingCallbacks *p_callbacks); // Used on creation by binding only. - void set_instance_binding(void *p_token, void *p_binding, const GDNativeInstanceBindingCallbacks *p_callbacks); + void set_instance_binding(void *p_token, void *p_binding, const GDExtensionInstanceBindingCallbacks *p_callbacks); bool has_instance_binding(void *p_token); void clear_internal_resource_paths(); diff --git a/core/object/ref_counted.h b/core/object/ref_counted.h index 71790fb825..411c589739 100644 --- a/core/object/ref_counted.h +++ b/core/object/ref_counted.h @@ -253,12 +253,14 @@ public: template <class T> struct PtrToArg<Ref<T>> { _FORCE_INLINE_ static Ref<T> convert(const void *p_ptr) { + // p_ptr points to a RefCounted object return Ref<T>(const_cast<T *>(reinterpret_cast<const T *>(p_ptr))); } typedef Ref<T> EncodeT; _FORCE_INLINE_ static void encode(Ref<T> p_val, const void *p_ptr) { + // p_ptr points to an EncodeT object which is a Ref<T> object. *(const_cast<Ref<RefCounted> *>(reinterpret_cast<const Ref<RefCounted> *>(p_ptr))) = p_val; } }; @@ -268,6 +270,7 @@ struct PtrToArg<const Ref<T> &> { typedef Ref<T> EncodeT; _FORCE_INLINE_ static Ref<T> convert(const void *p_ptr) { + // p_ptr points to a RefCounted object return Ref<T>((T *)p_ptr); } }; diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp index 056c57a5f1..36a0d03aaf 100644 --- a/core/object/script_language.cpp +++ b/core/object/script_language.cpp @@ -409,7 +409,9 @@ bool PlaceHolderScriptInstance::set(const StringName &p_name, const Variant &p_v if (values.has(p_name)) { Variant defval; if (script->get_property_default_value(p_name, defval)) { - if (defval == p_value) { + // The evaluate function ensures that a NIL variant is equal to e.g. an empty Resource. + // Simply doing defval == p_value does not do this. + if (Variant::evaluate(Variant::OP_EQUAL, defval, p_value)) { values.erase(p_name); return true; } @@ -419,7 +421,7 @@ bool PlaceHolderScriptInstance::set(const StringName &p_name, const Variant &p_v } else { Variant defval; if (script->get_property_default_value(p_name, defval)) { - if (defval != p_value) { + if (Variant::evaluate(Variant::OP_NOT_EQUAL, defval, p_value)) { values[p_name] = p_value; } return true; diff --git a/core/object/script_language_extension.h b/core/object/script_language_extension.h index c32fb9d85b..0ecd98152a 100644 --- a/core/object/script_language_extension.h +++ b/core/object/script_language_extension.h @@ -43,7 +43,7 @@ class ScriptExtension : public Script { protected: EXBIND0R(bool, editor_can_reload_from_file) - GDVIRTUAL1(_placeholder_erased, GDNativePtr<void>) + GDVIRTUAL1(_placeholder_erased, GDExtensionPtr<void>) virtual void _placeholder_erased(PlaceHolderScriptInstance *p_placeholder) override { GDVIRTUAL_CALL(_placeholder_erased, p_placeholder); } @@ -56,15 +56,15 @@ public: EXBIND1RC(bool, inherits_script, const Ref<Script> &) EXBIND0RC(StringName, get_instance_base_type) - GDVIRTUAL1RC(GDNativePtr<void>, _instance_create, Object *) + GDVIRTUAL1RC(GDExtensionPtr<void>, _instance_create, Object *) virtual ScriptInstance *instance_create(Object *p_this) override { - GDNativePtr<void> ret = nullptr; + GDExtensionPtr<void> ret = nullptr; GDVIRTUAL_REQUIRED_CALL(_instance_create, p_this, ret); return reinterpret_cast<ScriptInstance *>(ret.operator void *()); } - GDVIRTUAL1RC(GDNativePtr<void>, _placeholder_instance_create, Object *) + GDVIRTUAL1RC(GDExtensionPtr<void>, _placeholder_instance_create, Object *) PlaceHolderScriptInstance *placeholder_instance_create(Object *p_this) override { - GDNativePtr<void> ret = nullptr; + GDExtensionPtr<void> ret = nullptr; GDVIRTUAL_REQUIRED_CALL(_placeholder_instance_create, p_this, ret); return reinterpret_cast<PlaceHolderScriptInstance *>(ret.operator void *()); } @@ -482,10 +482,10 @@ public: } } } - GDVIRTUAL1R(GDNativePtr<void>, _debug_get_stack_level_instance, int) + GDVIRTUAL1R(GDExtensionPtr<void>, _debug_get_stack_level_instance, int) virtual ScriptInstance *debug_get_stack_level_instance(int p_level) override { - GDNativePtr<void> ret = nullptr; + GDExtensionPtr<void> ret = nullptr; GDVIRTUAL_REQUIRED_CALL(_debug_get_stack_level_instance, p_level, ret); return reinterpret_cast<ScriptInstance *>(ret.operator void *()); } @@ -578,7 +578,7 @@ public: EXBIND0(profiling_start) EXBIND0(profiling_stop) - GDVIRTUAL2R(int, _profiling_get_accumulated_data, GDNativePtr<ScriptLanguageExtensionProfilingInfo>, int) + GDVIRTUAL2R(int, _profiling_get_accumulated_data, GDExtensionPtr<ScriptLanguageExtensionProfilingInfo>, int) virtual int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max) override { int ret = 0; @@ -586,7 +586,7 @@ public: return ret; } - GDVIRTUAL2R(int, _profiling_get_frame_data, GDNativePtr<ScriptLanguageExtensionProfilingInfo>, int) + GDVIRTUAL2R(int, _profiling_get_frame_data, GDExtensionPtr<ScriptLanguageExtensionProfilingInfo>, int) virtual int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max) override { int ret = 0; @@ -594,15 +594,15 @@ public: return ret; } - GDVIRTUAL1R(GDNativePtr<void>, _alloc_instance_binding_data, Object *) + GDVIRTUAL1R(GDExtensionPtr<void>, _alloc_instance_binding_data, Object *) virtual void *alloc_instance_binding_data(Object *p_object) override { - GDNativePtr<void> ret = nullptr; + GDExtensionPtr<void> ret = nullptr; GDVIRTUAL_REQUIRED_CALL(_alloc_instance_binding_data, p_object, ret); return ret.operator void *(); } - GDVIRTUAL1(_free_instance_binding_data, GDNativePtr<void>) + GDVIRTUAL1(_free_instance_binding_data, GDExtensionPtr<void>) virtual void free_instance_binding_data(void *p_data) override { GDVIRTUAL_REQUIRED_CALL(_free_instance_binding_data, p_data); @@ -639,8 +639,8 @@ VARIANT_ENUM_CAST(ScriptLanguageExtension::CodeCompletionLocation) class ScriptInstanceExtension : public ScriptInstance { public: - const GDNativeExtensionScriptInstanceInfo *native_info; - GDNativeExtensionScriptInstanceDataPtr instance = nullptr; + const GDExtensionScriptInstanceInfo *native_info; + GDExtensionScriptInstanceDataPtr instance = nullptr; // There should not be warnings on explicit casts. #if defined(__GNUC__) && !defined(__clang__) @@ -650,20 +650,20 @@ public: virtual bool set(const StringName &p_name, const Variant &p_value) override { if (native_info->set_func) { - return native_info->set_func(instance, (const GDNativeStringNamePtr)&p_name, (const GDNativeVariantPtr)&p_value); + return native_info->set_func(instance, (GDExtensionConstStringNamePtr)&p_name, (GDExtensionConstVariantPtr)&p_value); } return false; } virtual bool get(const StringName &p_name, Variant &r_ret) const override { if (native_info->get_func) { - return native_info->get_func(instance, (const GDNativeStringNamePtr)&p_name, (GDNativeVariantPtr)&r_ret); + return native_info->get_func(instance, (GDExtensionConstStringNamePtr)&p_name, (GDExtensionVariantPtr)&r_ret); } return false; } virtual void get_property_list(List<PropertyInfo> *p_list) const override { if (native_info->get_property_list_func) { uint32_t pcount; - const GDNativePropertyInfo *pinfo = native_info->get_property_list_func(instance, &pcount); + const GDExtensionPropertyInfo *pinfo = native_info->get_property_list_func(instance, &pcount); #ifdef TOOLS_ENABLED Ref<Script> script = get_script(); @@ -682,12 +682,11 @@ public: } virtual Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid = nullptr) const override { if (native_info->get_property_type_func) { - GDNativeBool is_valid = 0; - GDNativeVariantType type = native_info->get_property_type_func(instance, (const GDNativeStringNamePtr)&p_name, &is_valid); + GDExtensionBool is_valid = 0; + GDExtensionVariantType type = native_info->get_property_type_func(instance, (GDExtensionConstStringNamePtr)&p_name, &is_valid); if (r_is_valid) { *r_is_valid = is_valid != 0; } - return Variant::Type(type); } return Variant::NIL; @@ -695,13 +694,13 @@ public: virtual bool property_can_revert(const StringName &p_name) const override { if (native_info->property_can_revert_func) { - return native_info->property_can_revert_func(instance, (const GDNativeStringNamePtr)&p_name); + return native_info->property_can_revert_func(instance, (GDExtensionConstStringNamePtr)&p_name); } return false; } virtual bool property_get_revert(const StringName &p_name, Variant &r_ret) const override { if (native_info->property_get_revert_func) { - return native_info->property_get_revert_func(instance, (const GDNativeStringNamePtr)&p_name, (GDNativeVariantPtr)&r_ret); + return native_info->property_get_revert_func(instance, (GDExtensionConstStringNamePtr)&p_name, (GDExtensionVariantPtr)&r_ret); } return false; } @@ -712,7 +711,7 @@ public: } return nullptr; } - static void _add_property_with_state(const GDNativeStringNamePtr p_name, const GDNativeVariantPtr p_value, void *p_userdata) { + static void _add_property_with_state(GDExtensionConstStringNamePtr p_name, GDExtensionConstVariantPtr p_value, void *p_userdata) { List<Pair<StringName, Variant>> *state = (List<Pair<StringName, Variant>> *)p_userdata; state->push_back(Pair<StringName, Variant>(*(const StringName *)p_name, *(const Variant *)p_value)); } @@ -725,21 +724,9 @@ public: virtual void get_method_list(List<MethodInfo> *p_list) const override { if (native_info->get_method_list_func) { uint32_t mcount; - const GDNativeMethodInfo *minfo = native_info->get_method_list_func(instance, &mcount); + const GDExtensionMethodInfo *minfo = native_info->get_method_list_func(instance, &mcount); for (uint32_t i = 0; i < mcount; i++) { - MethodInfo m; - m.name = minfo[i].name; - m.flags = minfo[i].flags; - m.id = minfo[i].id; - m.return_val = PropertyInfo(minfo[i].return_value); - for (uint32_t j = 0; j < minfo[i].argument_count; j++) { - m.arguments.push_back(PropertyInfo(minfo[i].arguments[j])); - } - const Variant *def_values = (const Variant *)minfo[i].default_arguments; - for (uint32_t j = 0; j < minfo[i].default_argument_count; j++) { - m.default_arguments.push_back(def_values[j]); - } - p_list->push_back(m); + p_list->push_back(MethodInfo(minfo[i])); } if (native_info->free_method_list_func) { native_info->free_method_list_func(instance, minfo); @@ -748,7 +735,7 @@ public: } virtual bool has_method(const StringName &p_method) const override { if (native_info->has_method_func) { - return native_info->has_method_func(instance, (GDNativeStringNamePtr)&p_method); + return native_info->has_method_func(instance, (GDExtensionStringNamePtr)&p_method); } return false; } @@ -756,8 +743,8 @@ public: virtual Variant callp(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) override { Variant ret; if (native_info->call_func) { - GDNativeCallError ce; - native_info->call_func(instance, (const GDNativeStringNamePtr)&p_method, (const GDNativeVariantPtr *)p_args, p_argcount, (GDNativeVariantPtr)&ret, &ce); + GDExtensionCallError ce; + native_info->call_func(instance, (GDExtensionConstStringNamePtr)&p_method, (GDExtensionConstVariantPtr *)p_args, p_argcount, (GDExtensionVariantPtr)&ret, &ce); r_error.error = Callable::CallError::Error(ce.error); r_error.argument = ce.argument; r_error.expected = ce.expected; @@ -772,8 +759,9 @@ public: } virtual String to_string(bool *r_valid) override { if (native_info->to_string_func) { - GDNativeBool valid; - String ret = native_info->to_string_func(instance, &valid); + GDExtensionBool valid; + String ret; + native_info->to_string_func(instance, &valid, reinterpret_cast<GDExtensionStringPtr>(&ret)); if (r_valid) { *r_valid = valid != 0; } @@ -796,7 +784,7 @@ public: virtual Ref<Script> get_script() const override { if (native_info->get_script_func) { - GDNativeObjectPtr script = native_info->get_script_func(instance); + GDExtensionObjectPtr script = native_info->get_script_func(instance); return Ref<Script>(reinterpret_cast<Script *>(script)); } return Ref<Script>(); @@ -811,7 +799,7 @@ public: virtual void property_set_fallback(const StringName &p_name, const Variant &p_value, bool *r_valid) override { if (native_info->set_fallback_func) { - bool ret = native_info->set_fallback_func(instance, (const GDNativeStringNamePtr)&p_name, (const GDNativeVariantPtr)&p_value); + bool ret = native_info->set_fallback_func(instance, (GDExtensionConstStringNamePtr)&p_name, (GDExtensionConstVariantPtr)&p_value); if (r_valid) { *r_valid = ret; } @@ -820,7 +808,7 @@ public: virtual Variant property_get_fallback(const StringName &p_name, bool *r_valid) override { Variant ret; if (native_info->get_fallback_func) { - bool valid = native_info->get_fallback_func(instance, (const GDNativeStringNamePtr)&p_name, (GDNativeVariantPtr)&ret); + bool valid = native_info->get_fallback_func(instance, (GDExtensionConstStringNamePtr)&p_name, (GDExtensionVariantPtr)&ret); if (r_valid) { *r_valid = valid; } @@ -830,7 +818,7 @@ public: virtual ScriptLanguage *get_language() override { if (native_info->get_language_func) { - GDNativeExtensionScriptLanguagePtr lang = native_info->get_language_func(instance); + GDExtensionScriptLanguagePtr lang = native_info->get_language_func(instance); return reinterpret_cast<ScriptLanguage *>(lang); } return nullptr; diff --git a/core/object/undo_redo.cpp b/core/object/undo_redo.cpp index aa66e86bc0..9f8a1de697 100644 --- a/core/object/undo_redo.cpp +++ b/core/object/undo_redo.cpp @@ -423,6 +423,10 @@ String UndoRedo::get_current_action_name() const { return actions[current_action].name; } +int UndoRedo::get_action_level() const { + return action_level; +} + bool UndoRedo::has_undo() const { return current_action >= 0; } diff --git a/core/object/undo_redo.h b/core/object/undo_redo.h index c7c58697c3..9c6d2d10ed 100644 --- a/core/object/undo_redo.h +++ b/core/object/undo_redo.h @@ -120,6 +120,7 @@ public: bool redo(); bool undo(); String get_current_action_name() const; + int get_action_level() const; int get_history_count(); int get_current_action(); diff --git a/core/object/worker_thread_pool.cpp b/core/object/worker_thread_pool.cpp index 9b3dc6833e..0218a4c8f6 100644 --- a/core/object/worker_thread_pool.cpp +++ b/core/object/worker_thread_pool.cpp @@ -402,7 +402,9 @@ void WorkerThreadPool::wait_for_group_task_completion(GroupID p_group) { } } - groups.erase(p_group); // Threads do not access this, so safe to erase here. + task_mutex.lock(); // This mutex is needed when Physics 2D and/or 3D is selected to run on a separate thread. + groups.erase(p_group); + task_mutex.unlock(); } void WorkerThreadPool::init(int p_thread_count, bool p_use_native_threads_low_priority, float p_low_priority_task_ratio) { |