diff options
Diffstat (limited to 'core/object/class_db.cpp')
-rw-r--r-- | core/object/class_db.cpp | 101 |
1 files changed, 92 insertions, 9 deletions
diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index 6a6043e42d..c594f4a9b4 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -31,6 +31,7 @@ #include "class_db.h" #include "core/config/engine.h" +#include "core/io/resource_loader.h" #include "core/object/script_language.h" #include "core/os/mutex.h" #include "core/version.h" @@ -348,7 +349,13 @@ Object *ClassDB::instantiate(const StringName &p_class) { } #endif if (ti->gdextension && ti->gdextension->create_instance) { - return (Object *)ti->gdextension->create_instance(ti->gdextension->class_userdata); + Object *obj = (Object *)ti->gdextension->create_instance(ti->gdextension->class_userdata); +#ifdef TOOLS_ENABLED + if (ti->gdextension->track_instance) { + ti->gdextension->track_instance(ti->gdextension->tracking_userdata, obj); + } +#endif + return obj; } else { return ti->creation_func(); } @@ -378,7 +385,14 @@ bool ClassDB::can_instantiate(const StringName &p_class) { OBJTYPE_RLOCK; ClassInfo *ti = classes.getptr(p_class); - ERR_FAIL_NULL_V_MSG(ti, false, "Cannot get class '" + String(p_class) + "'."); + if (!ti) { + if (!ScriptServer::is_global_class(p_class)) { + ERR_FAIL_V_MSG(false, "Cannot get class '" + String(p_class) + "'."); + } + String path = ScriptServer::get_global_class_path(p_class); + Ref<Script> scr = ResourceLoader::load(path); + return scr.is_valid() && scr->is_valid() && !scr->is_abstract(); + } #ifdef TOOLS_ENABLED if (ti->api == API_EDITOR && !Engine::get_singleton()->is_editor_hint()) { return false; @@ -395,7 +409,9 @@ bool ClassDB::is_virtual(const StringName &p_class) { if (!ScriptServer::is_global_class(p_class)) { ERR_FAIL_V_MSG(false, "Cannot get class '" + String(p_class) + "'."); } - return false; + String path = ScriptServer::get_global_class_path(p_class); + Ref<Script> scr = ResourceLoader::load(path); + return scr.is_valid() && scr->is_valid() && scr->is_abstract(); } #ifdef TOOLS_ENABLED if (ti->api == API_EDITOR && !Engine::get_singleton()->is_editor_hint()) { @@ -464,7 +480,6 @@ void ClassDB::get_method_list(const StringName &p_class, List<MethodInfo> *p_met } #ifdef DEBUG_METHODS_ENABLED - for (const MethodInfo &E : type->virtual_methods) { p_methods->push_back(E); } @@ -479,17 +494,74 @@ void ClassDB::get_method_list(const StringName &p_class, List<MethodInfo> *p_met p_methods->push_back(minfo); } - #else - for (KeyValue<StringName, MethodBind *> &E : type->method_map) { MethodBind *m = E.value; MethodInfo minfo = info_from_bind(m); p_methods->push_back(minfo); } +#endif + + if (p_no_inheritance) { + break; + } + + type = type->inherits_ptr; + } +} + +void ClassDB::get_method_list_with_compatibility(const StringName &p_class, List<Pair<MethodInfo, uint32_t>> *p_methods, bool p_no_inheritance, bool p_exclude_from_properties) { + OBJTYPE_RLOCK; + + ClassInfo *type = classes.getptr(p_class); + + while (type) { + if (type->disabled) { + if (p_no_inheritance) { + break; + } + + type = type->inherits_ptr; + continue; + } +#ifdef DEBUG_METHODS_ENABLED + for (const MethodInfo &E : type->virtual_methods) { + Pair<MethodInfo, uint32_t> pair(E, 0); + p_methods->push_back(pair); + } + + for (const StringName &E : type->method_order) { + if (p_exclude_from_properties && type->methods_in_properties.has(E)) { + continue; + } + + MethodBind *method = type->method_map.get(E); + MethodInfo minfo = info_from_bind(method); + + Pair<MethodInfo, uint32_t> pair(minfo, method->get_hash()); + p_methods->push_back(pair); + } +#else + for (KeyValue<StringName, MethodBind *> &E : type->method_map) { + MethodBind *method = E.value; + MethodInfo minfo = info_from_bind(method); + + Pair<MethodInfo, uint32_t> pair(minfo, method->get_hash()); + p_methods->push_back(pair); + } #endif + for (const KeyValue<StringName, LocalVector<MethodBind *, unsigned int, false, false>> &E : type->method_map_compatibility) { + LocalVector<MethodBind *> compat = E.value; + for (MethodBind *method : compat) { + MethodInfo minfo = info_from_bind(method); + + Pair<MethodInfo, uint32_t> pair(minfo, method->get_hash()); + p_methods->push_back(pair); + } + } + if (p_no_inheritance) { break; } @@ -1545,6 +1617,14 @@ bool ClassDB::is_class_exposed(const StringName &p_class) { return ti->exposed; } +bool ClassDB::is_class_reloadable(const StringName &p_class) { + OBJTYPE_RLOCK; + + ClassInfo *ti = classes.getptr(p_class); + ERR_FAIL_NULL_V_MSG(ti, false, "Cannot get class '" + String(p_class) + "'."); + return ti->reloadable; +} + void ClassDB::add_resource_base_extension(const StringName &p_extension, const StringName &p_class) { if (resource_base_extensions.has(p_extension)) { return; @@ -1683,15 +1763,18 @@ void ClassDB::register_extension_class(ObjectGDExtension *p_extension) { parent = classes.getptr(parent->name); } } + c.reloadable = p_extension->reloadable; classes[p_extension->class_name] = c; } -void ClassDB::unregister_extension_class(const StringName &p_class) { +void ClassDB::unregister_extension_class(const StringName &p_class, bool p_free_method_binds) { ClassInfo *c = classes.getptr(p_class); ERR_FAIL_NULL_MSG(c, "Class '" + String(p_class) + "' does not exist."); - for (KeyValue<StringName, MethodBind *> &F : c->method_map) { - memdelete(F.value); + if (p_free_method_binds) { + for (KeyValue<StringName, MethodBind *> &F : c->method_map) { + memdelete(F.value); + } } classes.erase(p_class); } |