summaryrefslogtreecommitdiffstats
path: root/core/object/class_db.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/object/class_db.cpp')
-rw-r--r--core/object/class_db.cpp116
1 files changed, 89 insertions, 27 deletions
diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp
index 7d58f7a724..5c793a676f 100644
--- a/core/object/class_db.cpp
+++ b/core/object/class_db.cpp
@@ -181,7 +181,7 @@ public:
return 0;
}
- static GDExtensionObjectPtr placeholder_class_create_instance(void *p_class_userdata) {
+ static GDExtensionObjectPtr placeholder_class_create_instance(void *p_class_userdata, bool p_notify_postinitialize) {
ClassDB::ClassInfo *ti = (ClassDB::ClassInfo *)p_class_userdata;
// Find the closest native parent, that isn't a runtime class.
@@ -192,7 +192,7 @@ public:
ERR_FAIL_NULL_V(native_parent->creation_func, nullptr);
// Construct a placeholder.
- Object *obj = native_parent->creation_func();
+ Object *obj = native_parent->creation_func(p_notify_postinitialize);
// ClassDB::set_object_extension_instance() won't be called for placeholders.
// We need need to make sure that all the things it would have done (even if
@@ -525,12 +525,12 @@ StringName ClassDB::get_compatibility_class(const StringName &p_class) {
return StringName();
}
-Object *ClassDB::_instantiate_internal(const StringName &p_class, bool p_require_real_class) {
+Object *ClassDB::_instantiate_internal(const StringName &p_class, bool p_require_real_class, bool p_notify_postinitialize) {
ClassInfo *ti;
{
OBJTYPE_RLOCK;
ti = classes.getptr(p_class);
- if (!ti || ti->disabled || !ti->creation_func || (ti->gdextension && !ti->gdextension->create_instance)) {
+ if (!_can_instantiate(ti)) {
if (compat_classes.has(p_class)) {
ti = classes.getptr(compat_classes[p_class]);
}
@@ -539,36 +539,80 @@ Object *ClassDB::_instantiate_internal(const StringName &p_class, bool p_require
ERR_FAIL_COND_V_MSG(ti->disabled, nullptr, "Class '" + String(p_class) + "' is disabled.");
ERR_FAIL_NULL_V_MSG(ti->creation_func, nullptr, "Class '" + String(p_class) + "' or its base class cannot be instantiated.");
}
+
#ifdef TOOLS_ENABLED
if ((ti->api == API_EDITOR || ti->api == API_EDITOR_EXTENSION) && !Engine::get_singleton()->is_editor_hint()) {
ERR_PRINT("Class '" + String(p_class) + "' can only be instantiated by editor.");
return nullptr;
}
#endif
- if (ti->gdextension && ti->gdextension->create_instance) {
- ObjectGDExtension *extension = ti->gdextension;
-#ifdef TOOLS_ENABLED
- if (!p_require_real_class && ti->is_runtime && Engine::get_singleton()->is_editor_hint()) {
- extension = get_placeholder_extension(ti->name);
- }
-#endif
- return (Object *)extension->create_instance(extension->class_userdata);
- } else {
+
#ifdef TOOLS_ENABLED
- if (!p_require_real_class && ti->is_runtime && Engine::get_singleton()->is_editor_hint()) {
- if (!ti->inherits_ptr || !ti->inherits_ptr->creation_func) {
- ERR_PRINT(vformat("Cannot make a placeholder instance of runtime class %s because its parent cannot be constructed.", ti->name));
- } else {
- ObjectGDExtension *extension = get_placeholder_extension(ti->name);
- return (Object *)extension->create_instance(extension->class_userdata);
+ // Try to create placeholder.
+ if (!p_require_real_class && ti->is_runtime && Engine::get_singleton()->is_editor_hint()) {
+ bool can_create_placeholder = false;
+ if (ti->gdextension) {
+ if (ti->gdextension->create_instance2) {
+ can_create_placeholder = true;
+ }
+#ifndef DISABLE_DEPRECATED
+ else if (ti->gdextension->create_instance) {
+ can_create_placeholder = true;
}
+#endif // DISABLE_DEPRECATED
+ } else if (!ti->inherits_ptr || !ti->inherits_ptr->creation_func) {
+ ERR_PRINT(vformat("Cannot make a placeholder instance of runtime class %s because its parent cannot be constructed.", ti->name));
+ } else {
+ can_create_placeholder = true;
}
-#endif
- return ti->creation_func();
+ if (can_create_placeholder) {
+ ObjectGDExtension *extension = get_placeholder_extension(ti->name);
+ return (Object *)extension->create_instance2(extension->class_userdata, p_notify_postinitialize);
+ }
+ }
+#endif // TOOLS_ENABLED
+
+ if (ti->gdextension && ti->gdextension->create_instance2) {
+ ObjectGDExtension *extension = ti->gdextension;
+ return (Object *)extension->create_instance2(extension->class_userdata, p_notify_postinitialize);
+ }
+#ifndef DISABLE_DEPRECATED
+ else if (ti->gdextension && ti->gdextension->create_instance) {
+ ObjectGDExtension *extension = ti->gdextension;
+ return (Object *)extension->create_instance(extension->class_userdata);
+ }
+#endif // DISABLE_DEPRECATED
+ else {
+ return ti->creation_func(p_notify_postinitialize);
}
}
+bool ClassDB::_can_instantiate(ClassInfo *p_class_info) {
+ if (!p_class_info) {
+ return false;
+ }
+
+ if (p_class_info->disabled || !p_class_info->creation_func) {
+ return false;
+ }
+
+ if (!p_class_info->gdextension) {
+ return true;
+ }
+
+ if (p_class_info->gdextension->create_instance2) {
+ return true;
+ }
+
+#ifndef DISABLE_DEPRECATED
+ if (p_class_info->gdextension->create_instance) {
+ return true;
+ }
+#endif // DISABLE_DEPRECATED
+ return false;
+}
+
Object *ClassDB::instantiate(const StringName &p_class) {
return _instantiate_internal(p_class);
}
@@ -577,6 +621,10 @@ Object *ClassDB::instantiate_no_placeholders(const StringName &p_class) {
return _instantiate_internal(p_class, true);
}
+Object *ClassDB::instantiate_without_postinitialization(const StringName &p_class) {
+ return _instantiate_internal(p_class, true, false);
+}
+
#ifdef TOOLS_ENABLED
ObjectGDExtension *ClassDB::get_placeholder_extension(const StringName &p_class) {
ObjectGDExtension *placeholder_extension = placeholder_extensions.getptr(p_class);
@@ -588,7 +636,7 @@ ObjectGDExtension *ClassDB::get_placeholder_extension(const StringName &p_class)
{
OBJTYPE_RLOCK;
ti = classes.getptr(p_class);
- if (!ti || ti->disabled || !ti->creation_func || (ti->gdextension && !ti->gdextension->create_instance)) {
+ if (!_can_instantiate(ti)) {
if (compat_classes.has(p_class)) {
ti = classes.getptr(compat_classes[p_class]);
}
@@ -649,7 +697,10 @@ ObjectGDExtension *ClassDB::get_placeholder_extension(const StringName &p_class)
placeholder_extension->get_rid = &PlaceholderExtensionInstance::placeholder_instance_get_rid;
placeholder_extension->class_userdata = ti;
- placeholder_extension->create_instance = &PlaceholderExtensionInstance::placeholder_class_create_instance;
+#ifndef DISABLE_DEPRECATED
+ placeholder_extension->create_instance = nullptr;
+#endif // DISABLE_DEPRECATED
+ placeholder_extension->create_instance2 = &PlaceholderExtensionInstance::placeholder_class_create_instance;
placeholder_extension->free_instance = &PlaceholderExtensionInstance::placeholder_class_free_instance;
placeholder_extension->get_virtual = &PlaceholderExtensionInstance::placeholder_class_get_virtual;
placeholder_extension->get_virtual_call_data = nullptr;
@@ -666,7 +717,7 @@ 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->gdextension && !ti->gdextension->create_instance)) {
+ if (!_can_instantiate(ti)) {
if (compat_classes.has(p_class)) {
ti = classes.getptr(compat_classes[p_class]);
}
@@ -703,7 +754,7 @@ bool ClassDB::can_instantiate(const StringName &p_class) {
return false;
}
#endif
- return (!ti->disabled && ti->creation_func != nullptr && !(ti->gdextension && !ti->gdextension->create_instance));
+ return _can_instantiate(ti);
}
bool ClassDB::is_abstract(const StringName &p_class) {
@@ -718,7 +769,18 @@ bool ClassDB::is_abstract(const StringName &p_class) {
Ref<Script> scr = ResourceLoader::load(path);
return scr.is_valid() && scr->is_valid() && scr->is_abstract();
}
- return ti->creation_func == nullptr && (!ti->gdextension || ti->gdextension->create_instance == nullptr);
+
+ if (ti->creation_func != nullptr) {
+ return false;
+ }
+ if (!ti->gdextension) {
+ return true;
+ }
+#ifndef DISABLE_DEPRECATED
+ return ti->gdextension->create_instance2 == nullptr && ti->gdextension->create_instance == nullptr;
+#else
+ return ti->gdextension->create_instance2 == nullptr;
+#endif // DISABLE_DEPRECATED
}
bool ClassDB::is_virtual(const StringName &p_class) {
@@ -738,7 +800,7 @@ bool ClassDB::is_virtual(const StringName &p_class) {
return false;
}
#endif
- return (!ti->disabled && ti->creation_func != nullptr && !(ti->gdextension && !ti->gdextension->create_instance) && ti->is_virtual);
+ return (_can_instantiate(ti) && ti->is_virtual);
}
void ClassDB::_add_class2(const StringName &p_class, const StringName &p_inherits) {