diff options
Diffstat (limited to 'modules/gdscript/gdscript.cpp')
-rw-r--r-- | modules/gdscript/gdscript.cpp | 134 |
1 files changed, 79 insertions, 55 deletions
diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 1f0830aa17..d7aaf4ce10 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -35,6 +35,7 @@ #include "gdscript_compiler.h" #include "gdscript_parser.h" #include "gdscript_rpc_callable.h" +#include "gdscript_tokenizer_buffer.h" #include "gdscript_warning.h" #ifdef TOOLS_ENABLED @@ -162,13 +163,14 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco _super_implicit_constructor(this, instance, r_error); if (r_error.error != Callable::CallError::CALL_OK) { + String error_text = Variant::get_call_error_text(instance->owner, "@implicit_new", nullptr, 0, r_error); instance->script = Ref<GDScript>(); instance->owner->set_script_instance(nullptr); { MutexLock lock(GDScriptLanguage::singleton->mutex); instances.erase(p_owner); } - ERR_FAIL_V_MSG(nullptr, "Error constructing a GDScriptInstance."); + ERR_FAIL_V_MSG(nullptr, "Error constructing a GDScriptInstance: " + error_text); } if (p_argcount < 0) { @@ -179,13 +181,14 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco if (initializer != nullptr) { initializer->call(instance, p_args, p_argcount, r_error); if (r_error.error != Callable::CallError::CALL_OK) { + String error_text = Variant::get_call_error_text(instance->owner, "_init", p_args, p_argcount, r_error); instance->script = Ref<GDScript>(); instance->owner->set_script_instance(nullptr); { MutexLock lock(GDScriptLanguage::singleton->mutex); instances.erase(p_owner); } - ERR_FAIL_V_MSG(nullptr, "Error constructing a GDScriptInstance."); + ERR_FAIL_V_MSG(nullptr, "Error constructing a GDScriptInstance: " + error_text); } } //@TODO make thread safe @@ -738,7 +741,12 @@ Error GDScript::reload(bool p_keep_state) { valid = false; GDScriptParser parser; - Error err = parser.parse(source, path, false); + Error err; + if (!binary_tokens.is_empty()) { + err = parser.parse_binary(binary_tokens, path); + } else { + err = parser.parse(source, path, false); + } if (err) { if (EngineDebugger::is_active()) { GDScriptLanguage::get_singleton()->debug_break_parse(_get_debug_path(), parser.get_errors().front()->get().line, "Parser Error: " + parser.get_errors().front()->get().message); @@ -1048,6 +1056,19 @@ Error GDScript::load_source_code(const String &p_path) { return OK; } +void GDScript::set_binary_tokens_source(const Vector<uint8_t> &p_binary_tokens) { + binary_tokens = p_binary_tokens; +} + +const Vector<uint8_t> &GDScript::get_binary_tokens_source() const { + return binary_tokens; +} + +Vector<uint8_t> GDScript::get_as_binary_tokens() const { + GDScriptTokenizerBuffer tokenizer; + return tokenizer.parse_code_string(source, GDScriptTokenizerBuffer::COMPRESS_NONE); +} + const HashMap<StringName, GDScriptFunction *> &GDScript::debug_get_member_functions() const { return member_functions; } @@ -1149,7 +1170,7 @@ GDScript *GDScript::get_root_script() { RBSet<GDScript *> GDScript::get_dependencies() { RBSet<GDScript *> dependencies; - _get_dependencies(dependencies, this); + _collect_dependencies(dependencies, this); dependencies.erase(this); return dependencies; @@ -1255,52 +1276,55 @@ GDScript *GDScript::_get_gdscript_from_variant(const Variant &p_variant) { return Object::cast_to<GDScript>(obj); } -void GDScript::_get_dependencies(RBSet<GDScript *> &p_dependencies, const GDScript *p_except) { +void GDScript::_collect_function_dependencies(GDScriptFunction *p_func, RBSet<GDScript *> &p_dependencies, const GDScript *p_except) { + if (p_func == nullptr) { + return; + } + for (GDScriptFunction *lambda : p_func->lambdas) { + _collect_function_dependencies(lambda, p_dependencies, p_except); + } + for (const Variant &V : p_func->constants) { + GDScript *scr = _get_gdscript_from_variant(V); + if (scr != nullptr && scr != p_except) { + scr->_collect_dependencies(p_dependencies, p_except); + } + } +} + +void GDScript::_collect_dependencies(RBSet<GDScript *> &p_dependencies, const GDScript *p_except) { if (p_dependencies.has(this)) { return; } - p_dependencies.insert(this); + if (this != p_except) { + p_dependencies.insert(this); + } for (const KeyValue<StringName, GDScriptFunction *> &E : member_functions) { - if (E.value == nullptr) { - continue; - } - for (const Variant &V : E.value->constants) { - GDScript *scr = _get_gdscript_from_variant(V); - if (scr != nullptr && scr != p_except) { - scr->_get_dependencies(p_dependencies, p_except); - } - } + _collect_function_dependencies(E.value, p_dependencies, p_except); } if (implicit_initializer) { - for (const Variant &V : implicit_initializer->constants) { - GDScript *scr = _get_gdscript_from_variant(V); - if (scr != nullptr && scr != p_except) { - scr->_get_dependencies(p_dependencies, p_except); - } - } + _collect_function_dependencies(implicit_initializer, p_dependencies, p_except); } if (implicit_ready) { - for (const Variant &V : implicit_ready->constants) { - GDScript *scr = _get_gdscript_from_variant(V); - if (scr != nullptr && scr != p_except) { - scr->_get_dependencies(p_dependencies, p_except); - } - } + _collect_function_dependencies(implicit_ready, p_dependencies, p_except); + } + + if (static_initializer) { + _collect_function_dependencies(static_initializer, p_dependencies, p_except); } for (KeyValue<StringName, Ref<GDScript>> &E : subclasses) { if (E.value != p_except) { - E.value->_get_dependencies(p_dependencies, p_except); + E.value->_collect_dependencies(p_dependencies, p_except); } } for (const KeyValue<StringName, Variant> &E : constants) { GDScript *scr = _get_gdscript_from_variant(E.value); if (scr != nullptr && scr != p_except) { - scr->_get_dependencies(p_dependencies, p_except); + scr->_collect_dependencies(p_dependencies, p_except); } } } @@ -1665,7 +1689,7 @@ bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const { { HashMap<StringName, MethodInfo>::ConstIterator E = sptr->_signals.find(p_name); if (E) { - r_ret = Signal(this->owner, E->key); + r_ret = Signal(owner, E->key); return true; } } @@ -1674,9 +1698,9 @@ bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const { HashMap<StringName, GDScriptFunction *>::ConstIterator E = sptr->member_functions.find(p_name); if (E) { if (sptr->rpc_config.has(p_name)) { - r_ret = Callable(memnew(GDScriptRPCCallable(this->owner, E->key))); + r_ret = Callable(memnew(GDScriptRPCCallable(owner, E->key))); } else { - r_ret = Callable(this->owner, E->key); + r_ret = Callable(owner, E->key); } return true; } @@ -2154,7 +2178,7 @@ void GDScriptLanguage::finish() { void GDScriptLanguage::profiling_start() { #ifdef DEBUG_ENABLED - MutexLock lock(this->mutex); + MutexLock lock(mutex); SelfList<GDScriptFunction> *elem = function_list.first(); while (elem) { @@ -2185,7 +2209,7 @@ void GDScriptLanguage::profiling_set_save_native_calls(bool p_enable) { void GDScriptLanguage::profiling_stop() { #ifdef DEBUG_ENABLED - MutexLock lock(this->mutex); + MutexLock lock(mutex); profiling = false; #endif @@ -2195,7 +2219,7 @@ int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int current = 0; #ifdef DEBUG_ENABLED - MutexLock lock(this->mutex); + MutexLock lock(mutex); profiling_collate_native_call_data(true); SelfList<GDScriptFunction> *elem = function_list.first(); @@ -2233,7 +2257,7 @@ int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_ int current = 0; #ifdef DEBUG_ENABLED - MutexLock lock(this->mutex); + MutexLock lock(mutex); profiling_collate_native_call_data(false); SelfList<GDScriptFunction> *elem = function_list.first(); @@ -2320,14 +2344,13 @@ struct GDScriptDepSort { void GDScriptLanguage::reload_all_scripts() { #ifdef DEBUG_ENABLED print_verbose("GDScript: Reloading all scripts"); - List<Ref<GDScript>> scripts; + Array scripts; { - MutexLock lock(this->mutex); + MutexLock lock(mutex); SelfList<GDScript> *elem = script_list.first(); while (elem) { - // Scripts will reload all subclasses, so only reload root scripts. - if (elem->self()->is_root_script() && elem->self()->get_path().is_resource_file()) { + if (elem->self()->get_path().is_resource_file()) { print_verbose("GDScript: Found: " + elem->self()->get_path()); scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident } @@ -2348,24 +2371,16 @@ void GDScriptLanguage::reload_all_scripts() { #endif } - //as scripts are going to be reloaded, must proceed without locking here - - scripts.sort_custom<GDScriptDepSort>(); //update in inheritance dependency order - - for (Ref<GDScript> &scr : scripts) { - print_verbose("GDScript: Reloading: " + scr->get_path()); - scr->load_source_code(scr->get_path()); - scr->reload(true); - } + reload_scripts(scripts, true); #endif } -void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload) { +void GDScriptLanguage::reload_scripts(const Array &p_scripts, bool p_soft_reload) { #ifdef DEBUG_ENABLED List<Ref<GDScript>> scripts; { - MutexLock lock(this->mutex); + MutexLock lock(mutex); SelfList<GDScript> *elem = script_list.first(); while (elem) { @@ -2386,7 +2401,7 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so scripts.sort_custom<GDScriptDepSort>(); //update in inheritance dependency order for (Ref<GDScript> &scr : scripts) { - bool reload = scr == p_script || to_reload.has(scr->get_base()); + bool reload = p_scripts.has(scr) || to_reload.has(scr->get_base()); if (!reload) { continue; @@ -2409,7 +2424,7 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so } } -//same thing for placeholders + //same thing for placeholders #ifdef TOOLS_ENABLED while (scr->placeholders.size()) { @@ -2437,6 +2452,8 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so for (KeyValue<Ref<GDScript>, HashMap<ObjectID, List<Pair<StringName, Variant>>>> &E : to_reload) { Ref<GDScript> scr = E.key; + print_verbose("GDScript: Reloading: " + scr->get_path()); + scr->load_source_code(scr->get_path()); scr->reload(p_soft_reload); //restore state if saved @@ -2484,12 +2501,18 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so #endif } +void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload) { + Array scripts; + scripts.push_back(p_script); + reload_scripts(scripts, p_soft_reload); +} + void GDScriptLanguage::frame() { calls = 0; #ifdef DEBUG_ENABLED if (profiling) { - MutexLock lock(this->mutex); + MutexLock lock(mutex); SelfList<GDScriptFunction> *elem = function_list.first(); while (elem) { @@ -2804,6 +2827,7 @@ Ref<Resource> ResourceFormatLoaderGDScript::load(const String &p_path, const Str void ResourceFormatLoaderGDScript::get_recognized_extensions(List<String> *p_extensions) const { p_extensions->push_back("gd"); + p_extensions->push_back("gdc"); } bool ResourceFormatLoaderGDScript::handles_type(const String &p_type) const { @@ -2812,7 +2836,7 @@ bool ResourceFormatLoaderGDScript::handles_type(const String &p_type) const { String ResourceFormatLoaderGDScript::get_resource_type(const String &p_path) const { String el = p_path.get_extension().to_lower(); - if (el == "gd") { + if (el == "gd" || el == "gdc") { return "GDScript"; } return ""; |