summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/config/project_settings.cpp23
-rw-r--r--core/config/project_settings.h1
-rw-r--r--core/io/resource_uid.cpp6
-rw-r--r--core/io/resource_uid.h2
-rw-r--r--core/object/script_language.cpp24
-rw-r--r--core/variant/callable.cpp29
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);
}