diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/config/project_settings.cpp | 23 | ||||
-rw-r--r-- | core/config/project_settings.h | 1 | ||||
-rw-r--r-- | core/io/resource_uid.cpp | 6 | ||||
-rw-r--r-- | core/io/resource_uid.h | 2 | ||||
-rw-r--r-- | core/object/script_language.cpp | 24 | ||||
-rw-r--r-- | core/variant/callable.cpp | 29 |
6 files changed, 72 insertions, 13 deletions
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index f5baf1a27e..ce7fa1074b 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -38,6 +38,8 @@ #include "core/io/file_access.h" #include "core/io/file_access_pack.h" #include "core/io/marshalls.h" +#include "core/io/resource_uid.h" +#include "core/object/script_language.h" #include "core/os/keyboard.h" #include "core/templates/rb_set.h" #include "core/variant/typed_array.h" @@ -478,6 +480,14 @@ bool ProjectSettings::_load_resource_pack(const String &p_pack, bool p_replace_f return false; } + if (project_loaded) { + // This pack may have declared new global classes (make sure they are picked up). + refresh_global_class_list(); + + // This pack may have defined new UIDs, make sure they are cached. + ResourceUID::get_singleton()->load_from_cache(false); + } + //if data.pck is found, all directory access will be from here DirAccess::make_default<DirAccessPack>(DirAccess::ACCESS_RESOURCES); using_datapack = true; @@ -1189,6 +1199,19 @@ Variant ProjectSettings::get_setting(const String &p_setting, const Variant &p_d } } +void ProjectSettings::refresh_global_class_list() { + // This is called after mounting a new PCK file to pick up class changes. + is_global_class_list_loaded = false; // Make sure we read from the freshly mounted PCK. + Array script_classes = get_global_class_list(); + for (int i = 0; i < script_classes.size(); i++) { + Dictionary c = script_classes[i]; + if (!c.has("class") || !c.has("language") || !c.has("path") || !c.has("base")) { + continue; + } + ScriptServer::add_global_class(c["class"], c["base"], c["language"], c["path"]); + } +} + TypedArray<Dictionary> ProjectSettings::get_global_class_list() { if (is_global_class_list_loaded) { return global_class_list; diff --git a/core/config/project_settings.h b/core/config/project_settings.h index 252b10bd3a..1bad76acb1 100644 --- a/core/config/project_settings.h +++ b/core/config/project_settings.h @@ -154,6 +154,7 @@ public: void set_setting(const String &p_setting, const Variant &p_value); Variant get_setting(const String &p_setting, const Variant &p_default_value = Variant()) const; TypedArray<Dictionary> get_global_class_list(); + void refresh_global_class_list(); void store_global_class_list(const Array &p_classes); String get_global_class_list_path() const; diff --git a/core/io/resource_uid.cpp b/core/io/resource_uid.cpp index edff3e1f14..c14121a53b 100644 --- a/core/io/resource_uid.cpp +++ b/core/io/resource_uid.cpp @@ -169,14 +169,16 @@ Error ResourceUID::save_to_cache() { return OK; } -Error ResourceUID::load_from_cache() { +Error ResourceUID::load_from_cache(bool p_reset) { Ref<FileAccess> f = FileAccess::open(get_cache_file(), FileAccess::READ); if (f.is_null()) { return ERR_CANT_OPEN; } MutexLock l(mutex); - unique_ids.clear(); + if (p_reset) { + unique_ids.clear(); + } uint32_t entry_count = f->get_32(); for (uint32_t i = 0; i < entry_count; i++) { diff --git a/core/io/resource_uid.h b/core/io/resource_uid.h index 22561c5c03..e56b89f603 100644 --- a/core/io/resource_uid.h +++ b/core/io/resource_uid.h @@ -73,7 +73,7 @@ public: String get_id_path(ID p_id) const; void remove_id(ID p_id); - Error load_from_cache(); + Error load_from_cache(bool p_reset); Error save_to_cache(); Error update_cache(); diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp index 693c6819d4..14894e1710 100644 --- a/core/object/script_language.cpp +++ b/core/object/script_language.cpp @@ -325,12 +325,24 @@ void ScriptServer::global_classes_clear() { void ScriptServer::add_global_class(const StringName &p_class, const StringName &p_base, const StringName &p_language, const String &p_path) { ERR_FAIL_COND_MSG(p_class == p_base || (global_classes.has(p_base) && get_global_class_native_base(p_base) == p_class), "Cyclic inheritance in script class."); - GlobalScriptClass g; - g.language = p_language; - g.path = p_path; - g.base = p_base; - global_classes[p_class] = g; - inheriters_cache_dirty = true; + GlobalScriptClass *existing = global_classes.getptr(p_class); + if (existing) { + // Update an existing class (only set dirty if something changed). + if (existing->base != p_base || existing->path != p_path || existing->language != p_language) { + existing->base = p_base; + existing->path = p_path; + existing->language = p_language; + inheriters_cache_dirty = true; + } + } else { + // Add new class. + GlobalScriptClass g; + g.language = p_language; + g.path = p_path; + g.base = p_base; + global_classes[p_class] = g; + inheriters_cache_dirty = true; + } } void ScriptServer::remove_global_class(const StringName &p_class) { diff --git a/core/variant/callable.cpp b/core/variant/callable.cpp index 6bad6f5a5b..47271118a0 100644 --- a/core/variant/callable.cpp +++ b/core/variant/callable.cpp @@ -92,10 +92,31 @@ Error Callable::rpcp(int p_id, const Variant **p_arguments, int p_argcount, Call r_call_error.expected = 0; return ERR_UNCONFIGURED; } else if (!is_custom()) { - r_call_error.error = CallError::CALL_ERROR_INVALID_METHOD; - r_call_error.argument = 0; - r_call_error.expected = 0; - return ERR_UNCONFIGURED; + Object *obj = ObjectDB::get_instance(ObjectID(object)); +#ifdef DEBUG_ENABLED + if (!obj || !obj->is_class("Node")) { + r_call_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL; + r_call_error.argument = 0; + r_call_error.expected = 0; + return ERR_UNCONFIGURED; + } +#endif + + int argcount = p_argcount + 2; + const Variant **argptrs = (const Variant **)alloca(sizeof(Variant *) * argcount); + const Variant args[2] = { p_id, method }; + + argptrs[0] = &args[0]; + argptrs[1] = &args[1]; + for (int i = 0; i < p_argcount; ++i) { + argptrs[i + 2] = p_arguments[i]; + } + + CallError tmp; + Error err = (Error)obj->callp(SNAME("rpc_id"), argptrs, argcount, tmp).operator int64_t(); + + r_call_error.error = Callable::CallError::CALL_OK; + return err; } else { return custom->rpc(p_id, p_arguments, p_argcount, r_call_error); } |