diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index 943e340dfca..c09303eaddf 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -533,19 +533,21 @@ StringName ClassDB::get_compatibility_class(const StringName &p_class) { return StringName(); } -Object *ClassDB::_instantiate_internal(const StringName &p_class, bool p_require_real_class, bool p_notify_postinitialize) { +Object *ClassDB::_instantiate_internal(const StringName &p_class, bool p_require_real_class, bool p_notify_postinitialize, bool p_exposed_only) { ClassInfo *ti; { Locker::Lock lock(Locker::STATE_READ); ti = classes.getptr(p_class); - if (!_can_instantiate(ti)) { + if (!_can_instantiate(ti, p_exposed_only)) { if (compat_classes.has(p_class)) { ti = classes.getptr(compat_classes[p_class]); } } ERR_FAIL_NULL_V_MSG(ti, nullptr, vformat("Cannot get class '%s'.", String(p_class))); ERR_FAIL_COND_V_MSG(ti->disabled, nullptr, vformat("Class '%s' is disabled.", String(p_class))); - ERR_FAIL_COND_V_MSG(!ti->exposed, nullptr, vformat("Class '%s' isn't exposed.", String(p_class))); + if (p_exposed_only) { + ERR_FAIL_COND_V_MSG(!ti->exposed, nullptr, vformat("Class '%s' isn't exposed.", String(p_class))); + } ERR_FAIL_NULL_V_MSG(ti->creation_func, nullptr, vformat("Class '%s' or its base class cannot be instantiated.", String(p_class))); } @@ -597,12 +599,16 @@ Object *ClassDB::_instantiate_internal(const StringName &p_class, bool p_require } } -bool ClassDB::_can_instantiate(ClassInfo *p_class_info) { +bool ClassDB::_can_instantiate(ClassInfo *p_class_info, bool p_exposed_only) { if (!p_class_info) { return false; } - if (p_class_info->disabled || !p_class_info->exposed || !p_class_info->creation_func) { + if (p_exposed_only && !p_class_info->exposed) { + return false; + } + + if (p_class_info->disabled || !p_class_info->creation_func) { return false; } @@ -2337,6 +2343,10 @@ uint64_t ClassDB::get_native_struct_size(const StringName &p_name) { return native_structs[p_name].struct_size; } +Object *ClassDB::_instantiate_allow_unexposed(const StringName &p_class) { + return _instantiate_internal(p_class, false, true, false); +} + void ClassDB::cleanup_defaults() { default_values.clear(); default_values_cached.clear(); diff --git a/core/object/class_db.h b/core/object/class_db.h index ffd5c53c2c6..1ce62226eff 100644 --- a/core/object/class_db.h +++ b/core/object/class_db.h @@ -216,9 +216,9 @@ private: static MethodBind *_bind_vararg_method(MethodBind *p_bind, const StringName &p_name, const Vector &p_default_args, bool p_compatibility); static void _bind_method_custom(const StringName &p_class, MethodBind *p_method, bool p_compatibility); - static Object *_instantiate_internal(const StringName &p_class, bool p_require_real_class = false, bool p_notify_postinitialize = true); + static Object *_instantiate_internal(const StringName &p_class, bool p_require_real_class = false, bool p_notify_postinitialize = true, bool p_exposed_only = true); - static bool _can_instantiate(ClassInfo *p_class_info); + static bool _can_instantiate(ClassInfo *p_class_info, bool p_exposed_only = true); public: // DO NOT USE THIS!!!!!! NEEDS TO BE PUBLIC BUT DO NOT USE NO MATTER WHAT!!! @@ -520,6 +520,8 @@ public: static void get_native_struct_list(List *r_names); static String get_native_struct_code(const StringName &p_name); static uint64_t get_native_struct_size(const StringName &p_name); // Used for asserting + + static Object *_instantiate_allow_unexposed(const StringName &p_class); // Used to create unexposed classes from GDExtension, typically for unexposed EditorPlugin. }; #define BIND_ENUM_CONSTANT(m_constant) \ diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 05765e98ae7..6e2789f559a 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -3786,7 +3786,7 @@ void EditorNode::add_extension_editor_plugin(const StringName &p_class_name) { ERR_FAIL_COND_MSG(!ClassDB::is_parent_class(p_class_name, SNAME("EditorPlugin")), vformat("Class is not an editor plugin: %s", p_class_name)); ERR_FAIL_COND_MSG(singleton->editor_data.has_extension_editor_plugin(p_class_name), vformat("Editor plugin already added for class: %s", p_class_name)); - EditorPlugin *plugin = Object::cast_to(ClassDB::instantiate(p_class_name)); + EditorPlugin *plugin = Object::cast_to(ClassDB::_instantiate_allow_unexposed(p_class_name)); singleton->editor_data.add_extension_editor_plugin(p_class_name, plugin); add_editor_plugin(plugin); }