summaryrefslogtreecommitdiffstats
path: root/core/object/script_language.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/object/script_language.cpp')
-rw-r--r--core/object/script_language.cpp80
1 files changed, 67 insertions, 13 deletions
diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp
index 693c6819d4..820296e66d 100644
--- a/core/object/script_language.cpp
+++ b/core/object/script_language.cpp
@@ -34,6 +34,7 @@
#include "core/core_string_names.h"
#include "core/debugger/engine_debugger.h"
#include "core/debugger/script_debugger.h"
+#include "core/io/resource_loader.h"
#include <stdint.h>
@@ -50,7 +51,7 @@ void Script::_notification(int p_what) {
switch (p_what) {
case NOTIFICATION_POSTINITIALIZE: {
if (EngineDebugger::is_active()) {
- EngineDebugger::get_script_debugger()->set_break_language(get_language());
+ callable_mp(this, &Script::_set_debugger_break_language).call_deferred();
}
} break;
}
@@ -102,6 +103,28 @@ Dictionary Script::_get_script_constant_map() {
return ret;
}
+void Script::_set_debugger_break_language() {
+ if (EngineDebugger::is_active()) {
+ EngineDebugger::get_script_debugger()->set_break_language(get_language());
+ }
+}
+
+int Script::get_script_method_argument_count(const StringName &p_method, bool *r_is_valid) const {
+ MethodInfo mi = get_method_info(p_method);
+
+ if (mi == MethodInfo()) {
+ if (r_is_valid) {
+ *r_is_valid = false;
+ }
+ return 0;
+ }
+
+ if (r_is_valid) {
+ *r_is_valid = true;
+ }
+ return mi.arguments.size();
+}
+
#ifdef TOOLS_ENABLED
PropertyInfo Script::get_class_category() const {
@@ -154,6 +177,24 @@ void Script::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING, "source_code", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NONE), "set_source_code", "get_source_code");
}
+void Script::reload_from_file() {
+#ifdef TOOLS_ENABLED
+ // Replicates how the ScriptEditor reloads script resources, which generally handles it.
+ // However, when scripts are to be reloaded but aren't open in the internal editor, we go through here instead.
+ const Ref<Script> rel = ResourceLoader::load(ResourceLoader::path_remap(get_path()), get_class(), ResourceFormatLoader::CACHE_MODE_IGNORE);
+ if (rel.is_null()) {
+ return;
+ }
+
+ set_source_code(rel->get_source_code());
+ set_last_modified_time(rel->get_last_modified_time());
+
+ reload();
+#else
+ Resource::reload_from_file();
+#endif
+}
+
void ScriptServer::set_scripting_enabled(bool p_enabled) {
scripting_enabled = p_enabled;
}
@@ -216,8 +257,8 @@ void ScriptServer::init_languages() {
if (ProjectSettings::get_singleton()->has_setting("_global_script_classes")) {
Array script_classes = GLOBAL_GET("_global_script_classes");
- for (int i = 0; i < script_classes.size(); i++) {
- Dictionary c = script_classes[i];
+ for (const Variant &script_class : script_classes) {
+ Dictionary c = script_class;
if (!c.has("class") || !c.has("language") || !c.has("path") || !c.has("base")) {
continue;
}
@@ -228,8 +269,8 @@ void ScriptServer::init_languages() {
#endif
Array script_classes = ProjectSettings::get_singleton()->get_global_class_list();
- for (int i = 0; i < script_classes.size(); i++) {
- Dictionary c = script_classes[i];
+ for (const Variant &script_class : script_classes) {
+ Dictionary c = script_class;
if (!c.has("class") || !c.has("language") || !c.has("path") || !c.has("base")) {
continue;
}
@@ -325,12 +366,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) {
@@ -416,8 +469,8 @@ void ScriptServer::save_global_classes() {
Dictionary class_icons;
Array script_classes = ProjectSettings::get_singleton()->get_global_class_list();
- for (int i = 0; i < script_classes.size(); i++) {
- Dictionary d = script_classes[i];
+ for (const Variant &script_class : script_classes) {
+ Dictionary d = script_class;
if (!d.has("name") || !d.has("icon")) {
continue;
}
@@ -484,6 +537,7 @@ void ScriptLanguage::get_core_type_words(List<String> *p_core_type_words) const
p_core_type_words->push_back("PackedVector2Array");
p_core_type_words->push_back("PackedVector3Array");
p_core_type_words->push_back("PackedColorArray");
+ p_core_type_words->push_back("PackedVector4Array");
}
void ScriptLanguage::frame() {