diff options
Diffstat (limited to 'modules/gdscript')
-rw-r--r-- | modules/gdscript/doc_classes/@GDScript.xml | 24 | ||||
-rw-r--r-- | modules/gdscript/doc_classes/GDScript.xml | 2 | ||||
-rw-r--r-- | modules/gdscript/gdscript.cpp | 236 | ||||
-rw-r--r-- | modules/gdscript/gdscript.h | 15 | ||||
-rw-r--r-- | modules/gdscript/gdscript_compiler.cpp | 4 | ||||
-rw-r--r-- | modules/gdscript/gdscript_editor.cpp | 46 | ||||
-rw-r--r-- | modules/gdscript/gdscript_function.cpp | 106 | ||||
-rw-r--r-- | modules/gdscript/gdscript_function.h | 8 | ||||
-rw-r--r-- | modules/gdscript/gdscript_functions.cpp | 380 | ||||
-rw-r--r-- | modules/gdscript/gdscript_functions.h | 2 | ||||
-rw-r--r-- | modules/gdscript/gdscript_parser.cpp | 128 | ||||
-rw-r--r-- | modules/gdscript/gdscript_tokenizer.cpp | 38 | ||||
-rw-r--r-- | modules/gdscript/language_server/gdscript_language_protocol.cpp | 201 | ||||
-rw-r--r-- | modules/gdscript/language_server/gdscript_language_protocol.h | 40 | ||||
-rw-r--r-- | modules/gdscript/language_server/gdscript_workspace.cpp | 55 | ||||
-rw-r--r-- | modules/gdscript/language_server/gdscript_workspace.h | 5 |
16 files changed, 691 insertions, 599 deletions
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml index 9fc8ad5573..2f6f9f30a4 100644 --- a/modules/gdscript/doc_classes/@GDScript.xml +++ b/modules/gdscript/doc_classes/@GDScript.xml @@ -131,7 +131,7 @@ <method name="bytes2var"> <return type="Variant"> </return> - <argument index="0" name="bytes" type="PoolByteArray"> + <argument index="0" name="bytes" type="PackedByteArray"> </argument> <argument index="1" name="allow_objects" type="bool" default="false"> </argument> @@ -481,9 +481,13 @@ <argument index="2" name="weight" type="float"> </argument> <description> - Returns a normalized value considering the given range. + Returns a normalized value considering the given range. This is the opposite of [method lerp]. [codeblock] - inverse_lerp(3, 5, 4) # Returns 0.5 + var middle = lerp(20, 30, 0.75) + # `middle` is now 27.5. + # Now, we pretend to have forgotten the original ratio and want to get it back. + var ratio = inverse_lerp(20, 30, 27.5) + # `ratio` is now 0.75. [/codeblock] </description> </method> @@ -558,7 +562,7 @@ <argument index="2" name="weight" type="float"> </argument> <description> - Linearly interpolates between two values by a normalized value. + Linearly interpolates between two values by a normalized value. This is the opposite of [method inverse_lerp]. If the [code]from[/code] and [code]to[/code] arguments are of type [int] or [float], the return value is a [float]. If both are of the same vector type ([Vector2], [Vector3] or [Color]), the return value will be of the same type ([code]lerp[/code] then calls the vector type's [code]linear_interpolate[/code] method). [codeblock] @@ -578,7 +582,7 @@ </argument> <description> Linearly interpolates between two angles (in radians) by a normalized value. - Similar to [method lerp] but interpolate correctly when the angles wrap around [constant @GDScript.TAU]. + Similar to [method lerp], but interpolates correctly when the angles wrap around [constant @GDScript.TAU]. [codeblock] extends Sprite var elapsed = 0.0 @@ -596,7 +600,13 @@ <argument index="0" name="nrg" type="float"> </argument> <description> - Converts from linear energy to decibels (audio). + Converts from linear energy to decibels (audio). This can be used to implement volume sliders that behave as expected (since volume isn't linear). Example: + [codeblock] + # "Slider" refers to a node that inherits Range such as HSlider or VSlider. + # Its range must be configured to go from 0 to 1. + # Change the bus name if you'd like to change the volume of a specific bus only. + AudioServer.set_bus_volume_db(AudioServer.get_bus_index("Master"), linear2db($Slider.value)) + [/codeblock] </description> </method> <method name="load"> @@ -1245,7 +1255,7 @@ </description> </method> <method name="var2bytes"> - <return type="PoolByteArray"> + <return type="PackedByteArray"> </return> <argument index="0" name="var" type="Variant"> </argument> diff --git a/modules/gdscript/doc_classes/GDScript.xml b/modules/gdscript/doc_classes/GDScript.xml index 5d0e93e117..62ccb93901 100644 --- a/modules/gdscript/doc_classes/GDScript.xml +++ b/modules/gdscript/doc_classes/GDScript.xml @@ -12,7 +12,7 @@ </tutorials> <methods> <method name="get_as_byte_code" qualifiers="const"> - <return type="PoolByteArray"> + <return type="PackedByteArray"> </return> <description> Returns byte code for the script source code. diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 07c74a2e26..c641ce37c5 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -84,7 +84,7 @@ Object *GDScriptNativeClass::instance() { return ClassDB::instance(name); } -GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Variant::CallError &r_error) { +GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Callable::CallError &r_error) { /* STEP 1, CREATE */ @@ -104,46 +104,39 @@ GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argco /* STEP 2, INITIALIZE AND CONSTRUCT */ -#ifndef NO_THREADS - GDScriptLanguage::singleton->lock->lock(); -#endif - - instances.insert(instance->owner); + { + MutexLock lock(GDScriptLanguage::singleton->lock); -#ifndef NO_THREADS - GDScriptLanguage::singleton->lock->unlock(); -#endif + instances.insert(instance->owner); + } initializer->call(instance, p_args, p_argcount, r_error); - if (r_error.error != Variant::CallError::CALL_OK) { + if (r_error.error != Callable::CallError::CALL_OK) { instance->script = Ref<GDScript>(); instance->owner->set_script_instance(NULL); -#ifndef NO_THREADS - GDScriptLanguage::singleton->lock->lock(); -#endif - instances.erase(p_owner); -#ifndef NO_THREADS - GDScriptLanguage::singleton->lock->unlock(); -#endif + { + MutexLock lock(GDScriptLanguage::singleton->lock); + instances.erase(p_owner); + } - ERR_FAIL_COND_V(r_error.error != Variant::CallError::CALL_OK, NULL); //error constructing + ERR_FAIL_COND_V(r_error.error != Callable::CallError::CALL_OK, NULL); //error constructing } //@TODO make thread safe return instance; } -Variant GDScript::_new(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { +Variant GDScript::_new(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { /* STEP 1, CREATE */ if (!valid) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; return Variant(); } - r_error.error = Variant::CallError::CALL_OK; + r_error.error = Callable::CallError::CALL_OK; REF ref; Object *owner = NULL; @@ -329,7 +322,7 @@ ScriptInstance *GDScript::instance_create(Object *p_this) { } } - Variant::CallError unchecked_error; + Callable::CallError unchecked_error; return _create_instance(NULL, 0, p_this, Object::cast_to<Reference>(p_this) != NULL, unchecked_error); } @@ -346,16 +339,9 @@ PlaceHolderScriptInstance *GDScript::placeholder_instance_create(Object *p_this) bool GDScript::instance_has(const Object *p_this) const { -#ifndef NO_THREADS - GDScriptLanguage::singleton->lock->lock(); -#endif - bool hasit = instances.has((Object *)p_this); - -#ifndef NO_THREADS - GDScriptLanguage::singleton->lock->unlock(); -#endif + MutexLock lock(GDScriptLanguage::singleton->lock); - return hasit; + return instances.has((Object *)p_this); } bool GDScript::has_source_code() const { @@ -544,14 +530,12 @@ void GDScript::_set_subclass_path(Ref<GDScript> &p_sc, const String &p_path) { Error GDScript::reload(bool p_keep_state) { -#ifndef NO_THREADS - GDScriptLanguage::singleton->lock->lock(); -#endif - bool has_instances = instances.size(); + bool has_instances; + { + MutexLock lock(GDScriptLanguage::singleton->lock); -#ifndef NO_THREADS - GDScriptLanguage::singleton->lock->unlock(); -#endif + has_instances = instances.size(); + } ERR_FAIL_COND_V(!p_keep_state && has_instances, ERR_ALREADY_IN_USE); @@ -739,7 +723,7 @@ MultiplayerAPI::RPCMode GDScript::get_rset_mode(const StringName &p_variable) co return get_rset_mode_by_id(get_rset_property_id(p_variable)); } -Variant GDScript::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) { +Variant GDScript::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { GDScript *top = this; while (top) { @@ -902,7 +886,7 @@ Error GDScript::load_byte_code(const String &p_path) { Error GDScript::load_source_code(const String &p_path) { - PoolVector<uint8_t> sourcef; + Vector<uint8_t> sourcef; Error err; FileAccess *f = FileAccess::open(p_path, FileAccess::READ, &err); if (err) { @@ -912,15 +896,15 @@ Error GDScript::load_source_code(const String &p_path) { int len = f->get_len(); sourcef.resize(len + 1); - PoolVector<uint8_t>::Write w = sourcef.write(); - int r = f->get_buffer(w.ptr(), len); + uint8_t *w = sourcef.ptrw(); + int r = f->get_buffer(w, len); f->close(); memdelete(f); ERR_FAIL_COND_V(r != len, ERR_CANT_OPEN); w[len] = 0; String s; - if (s.parse_utf8((const char *)w.ptr())) { + if (s.parse_utf8((const char *)w)) { ERR_FAIL_V_MSG(ERR_INVALID_DATA, "Script '" + p_path + "' contains invalid unicode (UTF-8), so it was not loaded. Please ensure that scripts are saved in valid UTF-8 unicode."); } @@ -995,7 +979,6 @@ void GDScript::get_script_signal_list(List<MethodInfo> *r_signals) const { GDScript::GDScript() : script_list(this) { - _static_ref = this; valid = false; subclass_count = 0; initializer = NULL; @@ -1008,13 +991,10 @@ GDScript::GDScript() : #endif #ifdef DEBUG_ENABLED - if (GDScriptLanguage::get_singleton()->lock) { - GDScriptLanguage::get_singleton()->lock->lock(); - } - GDScriptLanguage::get_singleton()->script_list.add(&script_list); + { + MutexLock lock(GDScriptLanguage::get_singleton()->lock); - if (GDScriptLanguage::get_singleton()->lock) { - GDScriptLanguage::get_singleton()->lock->unlock(); + GDScriptLanguage::get_singleton()->script_list.add(&script_list); } #endif } @@ -1058,13 +1038,10 @@ GDScript::~GDScript() { _save_orphaned_subclasses(); #ifdef DEBUG_ENABLED - if (GDScriptLanguage::get_singleton()->lock) { - GDScriptLanguage::get_singleton()->lock->lock(); - } - GDScriptLanguage::get_singleton()->script_list.remove(&script_list); + { + MutexLock lock(GDScriptLanguage::get_singleton()->lock); - if (GDScriptLanguage::get_singleton()->lock) { - GDScriptLanguage::get_singleton()->lock->unlock(); + GDScriptLanguage::get_singleton()->script_list.remove(&script_list); } #endif } @@ -1082,18 +1059,18 @@ bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) { const GDScript::MemberInfo *member = &E->get(); if (member->setter) { const Variant *val = &p_value; - Variant::CallError err; + Callable::CallError err; call(member->setter, &val, 1, err); - if (err.error == Variant::CallError::CALL_OK) { + if (err.error == Callable::CallError::CALL_OK) { return true; //function exists, call was successful } } else { if (!member->data_type.is_type(p_value)) { // Try conversion - Variant::CallError ce; + Callable::CallError ce; const Variant *value = &p_value; Variant converted = Variant::construct(member->data_type.builtin_type, &value, 1, ce); - if (ce.error == Variant::CallError::CALL_OK) { + if (ce.error == Callable::CallError::CALL_OK) { members.write[member->index] = converted; return true; } else { @@ -1116,9 +1093,9 @@ bool GDScriptInstance::set(const StringName &p_name, const Variant &p_value) { Variant name = p_name; const Variant *args[2] = { &name, &p_value }; - Variant::CallError err; + Callable::CallError err; Variant ret = E->get()->call(this, (const Variant **)args, 2, err); - if (err.error == Variant::CallError::CALL_OK && ret.get_type() == Variant::BOOL && ret.operator bool()) + if (err.error == Callable::CallError::CALL_OK && ret.get_type() == Variant::BOOL && ret.operator bool()) return true; } sptr = sptr->_base; @@ -1136,9 +1113,9 @@ bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const { const Map<StringName, GDScript::MemberInfo>::Element *E = script->member_indices.find(p_name); if (E) { if (E->get().getter) { - Variant::CallError err; + Callable::CallError err; r_ret = const_cast<GDScriptInstance *>(this)->call(E->get().getter, NULL, 0, err); - if (err.error == Variant::CallError::CALL_OK) { + if (err.error == Callable::CallError::CALL_OK) { return true; } } @@ -1167,9 +1144,9 @@ bool GDScriptInstance::get(const StringName &p_name, Variant &r_ret) const { Variant name = p_name; const Variant *args[1] = { &name }; - Variant::CallError err; + Callable::CallError err; Variant ret = const_cast<GDScriptFunction *>(E->get())->call(const_cast<GDScriptInstance *>(this), (const Variant **)args, 1, err); - if (err.error == Variant::CallError::CALL_OK && ret.get_type() != Variant::NIL) { + if (err.error == Callable::CallError::CALL_OK && ret.get_type() != Variant::NIL) { r_ret = ret; return true; } @@ -1210,9 +1187,9 @@ void GDScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const const Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._get_property_list); if (E) { - Variant::CallError err; + Callable::CallError err; Variant ret = const_cast<GDScriptFunction *>(E->get())->call(const_cast<GDScriptInstance *>(this), NULL, 0, err); - if (err.error == Variant::CallError::CALL_OK) { + if (err.error == Callable::CallError::CALL_OK) { ERR_FAIL_COND_MSG(ret.get_type() != Variant::ARRAY, "Wrong type for _get_property_list, must be an array of dictionaries."); @@ -1297,7 +1274,7 @@ bool GDScriptInstance::has_method(const StringName &p_method) const { return false; } -Variant GDScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) { +Variant GDScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { GDScript *sptr = script.ptr(); while (sptr) { @@ -1307,14 +1284,14 @@ Variant GDScriptInstance::call(const StringName &p_method, const Variant **p_arg } sptr = sptr->_base; } - r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; return Variant(); } void GDScriptInstance::call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount) { GDScript *sptr = script.ptr(); - Variant::CallError ce; + Callable::CallError ce; while (sptr) { Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(p_method); @@ -1330,7 +1307,7 @@ void GDScriptInstance::_ml_call_reversed(GDScript *sptr, const StringName &p_met if (sptr->_base) _ml_call_reversed(sptr->_base, p_method, p_args, p_argcount); - Variant::CallError ce; + Callable::CallError ce; Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(p_method); if (E) { @@ -1355,9 +1332,9 @@ void GDScriptInstance::notification(int p_notification) { while (sptr) { Map<StringName, GDScriptFunction *>::Element *E = sptr->member_functions.find(GDScriptLanguage::get_singleton()->strings._notification); if (E) { - Variant::CallError err; + Callable::CallError err; E->get()->call(this, args, 1, err); - if (err.error != Variant::CallError::CALL_OK) { + if (err.error != Callable::CallError::CALL_OK) { //print error about notification call } } @@ -1367,9 +1344,9 @@ void GDScriptInstance::notification(int p_notification) { String GDScriptInstance::to_string(bool *r_valid) { if (has_method(CoreStringNames::get_singleton()->_to_string)) { - Variant::CallError ce; + Callable::CallError ce; Variant ret = call(CoreStringNames::get_singleton()->_to_string, NULL, 0, ce); - if (ce.error == Variant::CallError::CALL_OK) { + if (ce.error == Callable::CallError::CALL_OK) { if (ret.get_type() != Variant::STRING) { if (r_valid) *r_valid = false; @@ -1473,14 +1450,9 @@ GDScriptInstance::GDScriptInstance() { GDScriptInstance::~GDScriptInstance() { if (script.is_valid() && owner) { -#ifndef NO_THREADS - GDScriptLanguage::singleton->lock->lock(); -#endif + MutexLock lock(GDScriptLanguage::singleton->lock); script->instances.erase(owner); -#ifndef NO_THREADS - GDScriptLanguage::singleton->lock->unlock(); -#endif } } @@ -1581,9 +1553,7 @@ void GDScriptLanguage::finish() { void GDScriptLanguage::profiling_start() { #ifdef DEBUG_ENABLED - if (lock) { - lock->lock(); - } + MutexLock lock(this->lock); SelfList<GDScriptFunction> *elem = function_list.first(); while (elem) { @@ -1600,25 +1570,15 @@ void GDScriptLanguage::profiling_start() { } profiling = true; - if (lock) { - lock->unlock(); - } - #endif } void GDScriptLanguage::profiling_stop() { #ifdef DEBUG_ENABLED - if (lock) { - lock->lock(); - } + MutexLock lock(this->lock); profiling = false; - if (lock) { - lock->unlock(); - } - #endif } @@ -1626,9 +1586,8 @@ int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int current = 0; #ifdef DEBUG_ENABLED - if (lock) { - lock->lock(); - } + + MutexLock lock(this->lock); SelfList<GDScriptFunction> *elem = function_list.first(); while (elem) { @@ -1641,11 +1600,6 @@ int GDScriptLanguage::profiling_get_accumulated_data(ProfilingInfo *p_info_arr, elem = elem->next(); current++; } - - if (lock) { - lock->unlock(); - } - #endif return current; @@ -1656,9 +1610,7 @@ int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_ int current = 0; #ifdef DEBUG_ENABLED - if (lock) { - lock->lock(); - } + MutexLock lock(this->lock); SelfList<GDScriptFunction> *elem = function_list.first(); while (elem) { @@ -1673,11 +1625,6 @@ int GDScriptLanguage::profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_ } elem = elem->next(); } - - if (lock) { - lock->unlock(); - } - #endif return current; @@ -1708,23 +1655,18 @@ void GDScriptLanguage::reload_all_scripts() { #ifdef DEBUG_ENABLED print_verbose("GDScript: Reloading all scripts"); - if (lock) { - lock->lock(); - } - List<Ref<GDScript> > scripts; + { + MutexLock lock(this->lock); - SelfList<GDScript> *elem = script_list.first(); - while (elem) { - 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 + SelfList<GDScript> *elem = script_list.first(); + while (elem) { + 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 + } + elem = elem->next(); } - elem = elem->next(); - } - - if (lock) { - lock->unlock(); } //as scripts are going to be reloaded, must proceed without locking here @@ -1744,23 +1686,18 @@ void GDScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_so #ifdef DEBUG_ENABLED - if (lock) { - lock->lock(); - } - List<Ref<GDScript> > scripts; + { + MutexLock lock(this->lock); - SelfList<GDScript> *elem = script_list.first(); - while (elem) { - if (elem->self()->get_path().is_resource_file()) { + SelfList<GDScript> *elem = script_list.first(); + while (elem) { + if (elem->self()->get_path().is_resource_file()) { - scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident + scripts.push_back(Ref<GDScript>(elem->self())); //cast to gdscript to avoid being erased by accident + } + elem = elem->next(); } - elem = elem->next(); - } - - if (lock) { - lock->unlock(); } //when someone asks you why dynamically typed languages are easier to write.... @@ -1880,9 +1817,7 @@ void GDScriptLanguage::frame() { #ifdef DEBUG_ENABLED if (profiling) { - if (lock) { - lock->lock(); - } + MutexLock lock(this->lock); SelfList<GDScriptFunction> *elem = function_list.first(); while (elem) { @@ -1894,10 +1829,6 @@ void GDScriptLanguage::frame() { elem->self()->profile.frame_total_time = 0; elem = elem->next(); } - - if (lock) { - lock->unlock(); - } } #endif @@ -1986,7 +1917,7 @@ bool GDScriptLanguage::handles_global_class_type(const String &p_type) const { String GDScriptLanguage::get_global_class_name(const String &p_path, String *r_base_type, String *r_icon_path) const { - PoolVector<uint8_t> sourcef; + Vector<uint8_t> sourcef; Error err; FileAccessRef f = FileAccess::open(p_path, FileAccess::READ, &err); if (err) { @@ -2263,11 +2194,6 @@ GDScriptLanguage::GDScriptLanguage() { _debug_parse_err_line = -1; _debug_parse_err_file = ""; -#ifdef NO_THREADS - lock = NULL; -#else - lock = Mutex::create(); -#endif profiling = false; script_frame_time = 0; @@ -2301,10 +2227,6 @@ GDScriptLanguage::GDScriptLanguage() { GDScriptLanguage::~GDScriptLanguage() { - if (lock) { - memdelete(lock); - lock = NULL; - } if (_call_stack) { memdelete_arr(_call_stack); } @@ -2329,7 +2251,7 @@ Ref<GDScript> GDScriptLanguage::get_orphan_subclass(const String &p_qualified_na /*************** RESOURCE ***************/ -RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_original_path, Error *r_error) { +RES ResourceFormatLoaderGDScript::load(const String &p_path, const String &p_original_path, Error *r_error, bool p_use_sub_threads, float *r_progress) { if (r_error) *r_error = ERR_FILE_CANT_OPEN; diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 3d24f9b3f5..3a90f0fc20 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -73,7 +73,6 @@ class GDScript : public Script { friend class GDScriptFunctions; friend class GDScriptLanguage; - Variant _static_ref; //used for static call Ref<GDScriptNativeClass> native; Ref<GDScript> base; GDScript *_base; //fast pointer access @@ -116,7 +115,7 @@ class GDScript : public Script { String fully_qualified_name; SelfList<GDScript> script_list; - GDScriptInstance *_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Variant::CallError &r_error); + GDScriptInstance *_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Callable::CallError &r_error); void _set_subclass_path(Ref<GDScript> &p_sc, const String &p_path); @@ -141,7 +140,7 @@ protected: bool _set(const StringName &p_name, const Variant &p_value); void _get_property_list(List<PropertyInfo> *p_properties) const; - Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error); + Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); //void call_multilevel(const StringName& p_method,const Variant** p_args,int p_argcount); static void _bind_methods(); @@ -170,7 +169,7 @@ public: const Map<StringName, GDScriptFunction *> &debug_get_member_functions() const; //this is debug only StringName debug_get_member_by_index(int p_idx) const; - Variant _new(const Variant **p_args, int p_argcount, Variant::CallError &r_error); + Variant _new(const Variant **p_args, int p_argcount, Callable::CallError &r_error); virtual bool can_instance() const; virtual Ref<Script> get_base_script() const; @@ -262,7 +261,7 @@ public: virtual void get_method_list(List<MethodInfo> *p_list) const; virtual bool has_method(const StringName &p_method) const; - virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error); + virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); virtual void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount); virtual void call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount); @@ -370,7 +369,7 @@ class GDScriptLanguage : public ScriptLanguage { friend class GDScriptInstance; - Mutex *lock; + Mutex lock; friend class GDScript; @@ -487,7 +486,7 @@ public: virtual bool supports_builtin_mode() const; virtual bool can_inherit_from_file() { return true; } virtual int find_function(const String &p_function, const String &p_code) const; - virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const; + virtual String make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const; virtual Error complete_code(const String &p_code, const String &p_path, Object *p_owner, List<ScriptCodeCompletionOption> *r_options, bool &r_forced, String &r_call_hint); #ifdef TOOLS_ENABLED virtual Error lookup_code(const String &p_code, const String &p_symbol, const String &p_path, Object *p_owner, LookupResult &r_result); @@ -543,7 +542,7 @@ public: class ResourceFormatLoaderGDScript : public ResourceFormatLoader { public: - virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL); + virtual RES load(const String &p_path, const String &p_original_path = "", Error *r_error = NULL, bool p_use_sub_threads = false, float *r_progress = nullptr); virtual void get_recognized_extensions(List<String> *p_extensions) const; virtual bool handles_type(const String &p_type) const; virtual String get_resource_type(const String &p_path) const; diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index fba1b992ec..4bd425f999 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -2076,10 +2076,10 @@ Error GDScriptCompiler::_parse_class_blocks(GDScript *p_script, const GDScriptPa /* STEP 2, INITIALIZE AND CONSTRUCT */ - Variant::CallError ce; + Callable::CallError ce; p_script->initializer->call(instance, NULL, 0, ce); - if (ce.error != Variant::CallError::CALL_OK) { + if (ce.error != Callable::CallError::CALL_OK) { //well, tough luck, not goinna do anything here } } diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp index c2c8ff5b99..1bc1aae0d2 100644 --- a/modules/gdscript/gdscript_editor.cpp +++ b/modules/gdscript/gdscript_editor.cpp @@ -457,7 +457,7 @@ void GDScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_cons p_constants->push_back(nan); } -String GDScriptLanguage::make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const { +String GDScriptLanguage::make_function(const String &p_class, const String &p_name, const PackedStringArray &p_args) const { #ifdef TOOLS_ENABLED bool th = EditorSettings::get_singleton()->get_setting("text_editor/completion/add_type_hints"); @@ -905,10 +905,10 @@ static bool _guess_expression_type(GDScriptCompletionContext &p_context, const G argptr.push_back(&args[i]); } - Variant::CallError ce; + Callable::CallError ce; Variant ret = mb->call(baseptr, (const Variant **)argptr.ptr(), argptr.size(), ce); - if (ce.error == Variant::CallError::CALL_OK && ret.get_type() != Variant::NIL) { + if (ce.error == Callable::CallError::CALL_OK && ret.get_type() != Variant::NIL) { if (ret.get_type() != Variant::OBJECT || ret.operator Object *() != NULL) { r_type = _type_from_variant(ret); found = true; @@ -1060,7 +1060,7 @@ static bool _guess_expression_type(GDScriptCompletionContext &p_context, const G StringName id = index.value; found = _guess_identifier_type_from_base(c, base, id, r_type); } else if (!found && index.type.kind == GDScriptParser::DataType::BUILTIN) { - Variant::CallError err; + Callable::CallError err; Variant base_val = Variant::construct(base.type.builtin_type, NULL, 0, err); bool valid = false; Variant res = base_val.get(index.value, &valid); @@ -1114,7 +1114,7 @@ static bool _guess_expression_type(GDScriptCompletionContext &p_context, const G break; } - Variant::CallError ce; + Callable::CallError ce; bool v1_use_value = p1.value.get_type() != Variant::NIL && p1.value.get_type() != Variant::OBJECT; Variant v1 = (v1_use_value) ? p1.value : Variant::construct(p1.type.builtin_type, NULL, 0, ce); bool v2_use_value = p2.value.get_type() != Variant::NIL && p2.value.get_type() != Variant::OBJECT; @@ -1124,7 +1124,7 @@ static bool _guess_expression_type(GDScriptCompletionContext &p_context, const G v2 = 1; v2_use_value = false; } - if (vop == Variant::OP_DIVIDE && v2.get_type() == Variant::REAL) { + if (vop == Variant::OP_DIVIDE && v2.get_type() == Variant::FLOAT) { v2 = 1.0; v2_use_value = false; } @@ -1533,10 +1533,10 @@ static bool _guess_identifier_type_from_base(GDScriptCompletionContext &p_contex return false; } break; case GDScriptParser::DataType::BUILTIN: { - Variant::CallError err; + Callable::CallError err; Variant tmp = Variant::construct(base_type.builtin_type, NULL, 0, err); - if (err.error != Variant::CallError::CALL_OK) { + if (err.error != Callable::CallError::CALL_OK) { return false; } bool valid = false; @@ -1703,9 +1703,9 @@ static bool _guess_method_return_type_from_base(GDScriptCompletionContext &p_con return false; } break; case GDScriptParser::DataType::BUILTIN: { - Variant::CallError err; + Callable::CallError err; Variant tmp = Variant::construct(base_type.builtin_type, NULL, 0, err); - if (err.error != Variant::CallError::CALL_OK) { + if (err.error != Callable::CallError::CALL_OK) { return false; } @@ -2088,9 +2088,9 @@ static void _find_identifiers_in_base(const GDScriptCompletionContext &p_context return; } break; case GDScriptParser::DataType::BUILTIN: { - Variant::CallError err; + Callable::CallError err; Variant tmp = Variant::construct(base_type.builtin_type, NULL, 0, err); - if (err.error != Variant::CallError::CALL_OK) { + if (err.error != Callable::CallError::CALL_OK) { return; } @@ -2172,9 +2172,9 @@ static void _find_identifiers(const GDScriptCompletionContext &p_context, bool p } static const char *_type_names[Variant::VARIANT_MAX] = { - "null", "bool", "int", "float", "String", "Vector2", "Rect2", "Vector3", "Transform2D", "Plane", "Quat", "AABB", "Basis", "Transform", - "Color", "NodePath", "RID", "Object", "Dictionary", "Array", "PoolByteArray", "PoolIntArray", "PoolRealArray", "PoolStringArray", - "PoolVector2Array", "PoolVector3Array", "PoolColorArray" + "null", "bool", "int", "float", "String", "Vector2", "Vector2i", "Rect2", "Rect2i", "Vector3", "Vector3i", "Transform2D", "Plane", "Quat", "AABB", "Basis", "Transform", + "Color", "StringName", "NodePath", "RID", "Object", "Callable", "Signal", "Dictionary", "Array", "PackedByteArray", "PackedInt32Array", "PackedInt64Array", "PackedFloat32Array", "PackedFloat64Array", "PackedStringArray", + "PackedVector2Array", "PackedVector3Array", "PackedColorArray" }; for (int i = 0; i < Variant::VARIANT_MAX; i++) { @@ -2372,9 +2372,9 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con } break; case GDScriptParser::DataType::BUILTIN: { if (base.get_type() == Variant::NIL) { - Variant::CallError err; + Callable::CallError err; base = Variant::construct(base_type.builtin_type, NULL, 0, err); - if (err.error != Variant::CallError::CALL_OK) { + if (err.error != Callable::CallError::CALL_OK) { return; } } @@ -2565,7 +2565,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path } break; case GDScriptParser::COMPLETION_FUNCTION: { is_function = true; - FALLTHROUGH; + [[fallthrough]]; } case GDScriptParser::COMPLETION_IDENTIFIER: { _find_identifiers(context, is_function, options); @@ -2608,7 +2608,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_path } break; case GDScriptParser::COMPLETION_METHOD: { is_function = true; - FALLTHROUGH; + [[fallthrough]]; } case GDScriptParser::COMPLETION_INDEX: { const GDScriptParser::Node *node = parser.get_completion_node(); @@ -3219,9 +3219,9 @@ static Error _lookup_symbol_from_base(const GDScriptParser::DataType &p_base, co v_ref.instance(); v = v_ref; } else { - Variant::CallError err; + Callable::CallError err; v = Variant::construct(base_type.builtin_type, NULL, 0, err); - if (err.error != Variant::CallError::CALL_OK) { + if (err.error != Callable::CallError::CALL_OK) { break; } } @@ -3330,7 +3330,7 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol case GDScriptParser::COMPLETION_PARENT_FUNCTION: case GDScriptParser::COMPLETION_FUNCTION: { is_function = true; - FALLTHROUGH; + [[fallthrough]]; } case GDScriptParser::COMPLETION_IDENTIFIER: { @@ -3462,7 +3462,7 @@ Error GDScriptLanguage::lookup_code(const String &p_code, const String &p_symbol } break; case GDScriptParser::COMPLETION_METHOD: { is_function = true; - FALLTHROUGH; + [[fallthrough]]; } case GDScriptParser::COMPLETION_INDEX: { const GDScriptParser::Node *node = parser.get_completion_node(); diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index cbf7d81a61..79c550c81c 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -34,7 +34,7 @@ #include "gdscript.h" #include "gdscript_functions.h" -Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant *p_stack, String &r_error) const { +Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant &static_ref, Variant *p_stack, String &r_error) const { int address = p_address & ADDR_MASK; @@ -52,7 +52,7 @@ Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_insta } break; case ADDR_TYPE_CLASS: { - return &p_script->_static_ref; + return &static_ref; } break; case ADDR_TYPE_MEMBER: { #ifdef DEBUG_ENABLED @@ -160,11 +160,11 @@ static String _get_var_type(const Variant *p_var) { } #endif // DEBUG_ENABLED -String GDScriptFunction::_get_call_error(const Variant::CallError &p_err, const String &p_where, const Variant **argptrs) const { +String GDScriptFunction::_get_call_error(const Callable::CallError &p_err, const String &p_where, const Variant **argptrs) const { String err_text; - if (p_err.error == Variant::CallError::CALL_ERROR_INVALID_ARGUMENT) { + if (p_err.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) { int errorarg = p_err.argument; // Handle the Object to Object case separately as we don't have further class details. #ifdef DEBUG_ENABLED @@ -173,15 +173,15 @@ String GDScriptFunction::_get_call_error(const Variant::CallError &p_err, const } else #endif // DEBUG_ENABLED { - err_text = "Invalid type in " + p_where + ". Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(p_err.expected) + "."; + err_text = "Invalid type in " + p_where + ". Cannot convert argument " + itos(errorarg + 1) + " from " + Variant::get_type_name(argptrs[errorarg]->get_type()) + " to " + Variant::get_type_name(Variant::Type(p_err.expected)) + "."; } - } else if (p_err.error == Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) { + } else if (p_err.error == Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS) { err_text = "Invalid call to " + p_where + ". Expected " + itos(p_err.argument) + " arguments."; - } else if (p_err.error == Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) { + } else if (p_err.error == Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS) { err_text = "Invalid call to " + p_where + ". Expected " + itos(p_err.argument) + " arguments."; - } else if (p_err.error == Variant::CallError::CALL_ERROR_INVALID_METHOD) { + } else if (p_err.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) { err_text = "Invalid call. Nonexistent " + p_where + "."; - } else if (p_err.error == Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL) { + } else if (p_err.error == Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL) { err_text = "Attempt to call " + p_where + " on a null instance."; } else { err_text = "Bug, call error: #" + itos(p_err.error); @@ -258,7 +258,7 @@ String GDScriptFunction::_get_call_error(const Variant::CallError &p_err, const #define OPCODE_OUT break #endif -Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_args, int p_argcount, Variant::CallError &r_err, CallState *p_state) { +Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_args, int p_argcount, Callable::CallError &r_err, CallState *p_state) { OPCODES_TABLE; @@ -267,9 +267,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a return Variant(); } - r_err.error = Variant::CallError::CALL_OK; + r_err.error = Callable::CallError::CALL_OK; Variant self; + Variant static_ref; Variant retvalue; Variant *stack = NULL; Variant **call_args; @@ -305,13 +306,13 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a if (p_argcount > _argument_count) { - r_err.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; + r_err.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; r_err.argument = _argument_count; return Variant(); } else if (p_argcount < _argument_count - _default_arg_count) { - r_err.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_err.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_err.argument = _argument_count - _default_arg_count; return Variant(); } else { @@ -340,7 +341,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a memnew_placement(&stack[i], Variant); continue; } else { - r_err.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_err.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_err.argument = i; r_err.expected = argument_types[i].kind == GDScriptDataType::BUILTIN ? argument_types[i].builtin_type : Variant::OBJECT; return Variant(); @@ -404,10 +405,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #define CHECK_SPACE(m_space) \ GD_ERR_BREAK((ip + m_space) > _code_size) -#define GET_VARIANT_PTR(m_v, m_code_ofs) \ - Variant *m_v; \ - m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, script, self, stack, err_text); \ - if (unlikely(!m_v)) \ +#define GET_VARIANT_PTR(m_v, m_code_ofs) \ + Variant *m_v; \ + m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, script, self, static_ref, stack, err_text); \ + if (unlikely(!m_v)) \ OPCODE_BREAK; #else @@ -415,7 +416,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #define CHECK_SPACE(m_space) #define GET_VARIANT_PTR(m_v, m_code_ofs) \ Variant *m_v; \ - m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, script, self, stack, err_text); + m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, script, self, static_ref, stack, err_text); #endif @@ -791,7 +792,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #ifdef DEBUG_ENABLED if (Variant::can_convert_strict(src->get_type(), var_type)) { #endif // DEBUG_ENABLED - Variant::CallError ce; + Callable::CallError ce; *dst = Variant::construct(var_type, const_cast<const Variant **>(&src), 1, ce); } else { #ifdef DEBUG_ENABLED @@ -897,11 +898,11 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GD_ERR_BREAK(to_type < 0 || to_type >= Variant::VARIANT_MAX); - Variant::CallError err; + Callable::CallError err; *dst = Variant::construct(to_type, (const Variant **)&src, 1, err); #ifdef DEBUG_ENABLED - if (err.error != Variant::CallError::CALL_OK) { + if (err.error != Callable::CallError::CALL_OK) { err_text = "Invalid cast: could not convert value to '" + Variant::get_type_name(to_type) + "'."; OPCODE_BREAK; } @@ -1000,11 +1001,11 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } GET_VARIANT_PTR(dst, 3 + argc); - Variant::CallError err; + Callable::CallError err; *dst = Variant::construct(t, (const Variant **)argptrs, argc, err); #ifdef DEBUG_ENABLED - if (err.error != Variant::CallError::CALL_OK) { + if (err.error != Callable::CallError::CALL_OK) { err_text = _get_call_error(err, "'" + Variant::get_type_name(t) + "' constructor", (const Variant **)argptrs); OPCODE_BREAK; @@ -1091,7 +1092,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } #endif - Variant::CallError err; + Callable::CallError err; if (call_ret) { GET_VARIANT_PTR(ret, argc); @@ -1105,7 +1106,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a function_call_time += OS::get_singleton()->get_ticks_usec() - call_time; } - if (err.error != Variant::CallError::CALL_OK) { + if (err.error != Callable::CallError::CALL_OK) { String methodstr = *methodname; String basestr = _get_var_type(base); @@ -1113,13 +1114,13 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a if (methodstr == "call") { if (argc >= 1) { methodstr = String(*argptrs[0]) + " (via call)"; - if (err.error == Variant::CallError::CALL_ERROR_INVALID_ARGUMENT) { + if (err.error == Callable::CallError::CALL_ERROR_INVALID_ARGUMENT) { err.argument += 1; } } } else if (methodstr == "free") { - if (err.error == Variant::CallError::CALL_ERROR_INVALID_METHOD) { + if (err.error == Callable::CallError::CALL_ERROR_INVALID_METHOD) { if (base->is_ref()) { err_text = "Attempted to free a reference."; @@ -1160,12 +1161,12 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a GET_VARIANT_PTR(dst, argc); - Variant::CallError err; + Callable::CallError err; GDScriptFunctions::call(func, (const Variant **)argptrs, argc, *dst, err); #ifdef DEBUG_ENABLED - if (err.error != Variant::CallError::CALL_OK) { + if (err.error != Callable::CallError::CALL_OK) { String methodstr = GDScriptFunctions::get_func_name(func); if (dst->get_type() == Variant::STRING) { @@ -1223,7 +1224,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a break; } - Variant::CallError err; + Callable::CallError err; if (E) { @@ -1234,23 +1235,23 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a MethodBind *mb = ClassDB::get_method(gds->native->get_name(), *methodname); if (!mb) { - err.error = Variant::CallError::CALL_ERROR_INVALID_METHOD; + err.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; } else { *dst = mb->call(p_instance->owner, (const Variant **)argptrs, argc, err); } } else { - err.error = Variant::CallError::CALL_OK; + err.error = Callable::CallError::CALL_OK; } } else { if (*methodname != GDScriptLanguage::get_singleton()->strings._init) { - err.error = Variant::CallError::CALL_ERROR_INVALID_METHOD; + err.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; } else { - err.error = Variant::CallError::CALL_OK; + err.error = Callable::CallError::CALL_OK; } } - if (err.error != Variant::CallError::CALL_OK) { + if (err.error != Callable::CallError::CALL_OK) { String methodstr = *methodname; err_text = _get_call_error(err, "function '" + methodstr + "'", (const Variant **)argptrs); @@ -1331,7 +1332,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a OPCODE_BREAK; } - Error err = obj->connect(signal, gdfs.ptr(), "_signal_callback", varray(gdfs), Object::CONNECT_ONESHOT); + Error err = obj->connect_compat(signal, gdfs.ptr(), "_signal_callback", varray(gdfs), Object::CONNECT_ONESHOT); if (err != OK) { err_text = "Error connecting to signal: " + signal + " during yield()."; OPCODE_BREAK; @@ -1340,7 +1341,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a Object *obj = argobj->operator Object *(); String signal = argname->operator String(); - obj->connect(signal, gdfs.ptr(), "_signal_callback", varray(gdfs), Object::CONNECT_ONESHOT); + obj->connect_compat(signal, gdfs.ptr(), "_signal_callback", varray(gdfs), Object::CONNECT_ONESHOT); #endif } @@ -1768,13 +1769,10 @@ GDScriptFunction::GDScriptFunction() : #ifdef DEBUG_ENABLED _func_cname = NULL; - if (GDScriptLanguage::get_singleton()->lock) { - GDScriptLanguage::get_singleton()->lock->lock(); - } - GDScriptLanguage::get_singleton()->function_list.add(&function_list); + { + MutexLock lock(GDScriptLanguage::get_singleton()->lock); - if (GDScriptLanguage::get_singleton()->lock) { - GDScriptLanguage::get_singleton()->lock->unlock(); + GDScriptLanguage::get_singleton()->function_list.add(&function_list); } profile.call_count = 0; @@ -1792,26 +1790,22 @@ GDScriptFunction::GDScriptFunction() : GDScriptFunction::~GDScriptFunction() { #ifdef DEBUG_ENABLED - if (GDScriptLanguage::get_singleton()->lock) { - GDScriptLanguage::get_singleton()->lock->lock(); - } - GDScriptLanguage::get_singleton()->function_list.remove(&function_list); - if (GDScriptLanguage::get_singleton()->lock) { - GDScriptLanguage::get_singleton()->lock->unlock(); - } + MutexLock lock(GDScriptLanguage::get_singleton()->lock); + + GDScriptLanguage::get_singleton()->function_list.remove(&function_list); #endif } ///////////////////// -Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error) { +Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_argcount, Callable::CallError &r_error) { Variant arg; - r_error.error = Variant::CallError::CALL_OK; + r_error.error = Callable::CallError::CALL_OK; if (p_argcount == 0) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 1; return Variant(); } else if (p_argcount == 1) { @@ -1829,7 +1823,7 @@ Variant GDScriptFunctionState::_signal_callback(const Variant **p_args, int p_ar Ref<GDScriptFunctionState> self = *p_args[p_argcount - 1]; if (self.is_null()) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = p_argcount - 1; r_error.expected = Variant::OBJECT; return Variant(); @@ -1864,7 +1858,7 @@ Variant GDScriptFunctionState::resume(const Variant &p_arg) { } state.result = p_arg; - Variant::CallError err; + Callable::CallError err; Variant ret = function->call(NULL, NULL, 0, err, &state); bool completed = true; diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index 7b7bcbaac9..34019e563d 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -265,8 +265,8 @@ private: List<StackDebug> stack_debug; - _FORCE_INLINE_ Variant *_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant *p_stack, String &r_error) const; - _FORCE_INLINE_ String _get_call_error(const Variant::CallError &p_err, const String &p_where, const Variant **argptrs) const; + _FORCE_INLINE_ Variant *_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant &static_ref, Variant *p_stack, String &r_error) const; + _FORCE_INLINE_ String _get_call_error(const Callable::CallError &p_err, const String &p_where, const Variant **argptrs) const; friend class GDScriptLanguage; @@ -339,7 +339,7 @@ public: return default_arguments[p_idx]; } - Variant call(GDScriptInstance *p_instance, const Variant **p_args, int p_argcount, Variant::CallError &r_err, CallState *p_state = NULL); + Variant call(GDScriptInstance *p_instance, const Variant **p_args, int p_argcount, Callable::CallError &r_err, CallState *p_state = NULL); _FORCE_INLINE_ MultiplayerAPI::RPCMode get_rpc_mode() const { return rpc_mode; } GDScriptFunction(); @@ -352,7 +352,7 @@ class GDScriptFunctionState : public Reference { friend class GDScriptFunction; GDScriptFunction *function; GDScriptFunction::CallState state; - Variant _signal_callback(const Variant **p_args, int p_argcount, Variant::CallError &r_error); + Variant _signal_callback(const Variant **p_args, int p_argcount, Callable::CallError &r_error); Ref<GDScriptFunctionState> first_state; protected: diff --git a/modules/gdscript/gdscript_functions.cpp b/modules/gdscript/gdscript_functions.cpp index a46337d7dd..aaa308f40f 100644 --- a/modules/gdscript/gdscript_functions.cpp +++ b/modules/gdscript/gdscript_functions.cpp @@ -139,32 +139,32 @@ const char *GDScriptFunctions::get_func_name(Function p_func) { return _names[p_func]; } -void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_count, Variant &r_ret, Variant::CallError &r_error) { +void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_count, Variant &r_ret, Callable::CallError &r_error) { - r_error.error = Variant::CallError::CALL_OK; + r_error.error = Callable::CallError::CALL_OK; #ifdef DEBUG_ENABLED -#define VALIDATE_ARG_COUNT(m_count) \ - if (p_arg_count < m_count) { \ - r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; \ - r_error.argument = m_count; \ - r_ret = Variant(); \ - return; \ - } \ - if (p_arg_count > m_count) { \ - r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; \ - r_error.argument = m_count; \ - r_ret = Variant(); \ - return; \ +#define VALIDATE_ARG_COUNT(m_count) \ + if (p_arg_count < m_count) { \ + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; \ + r_error.argument = m_count; \ + r_ret = Variant(); \ + return; \ + } \ + if (p_arg_count > m_count) { \ + r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; \ + r_error.argument = m_count; \ + r_ret = Variant(); \ + return; \ } -#define VALIDATE_ARG_NUM(m_arg) \ - if (!p_args[m_arg]->is_num()) { \ - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; \ - r_error.argument = m_arg; \ - r_error.expected = Variant::REAL; \ - r_ret = Variant(); \ - return; \ +#define VALIDATE_ARG_NUM(m_arg) \ + if (!p_args[m_arg]->is_num()) { \ + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; \ + r_error.argument = m_arg; \ + r_error.expected = Variant::FLOAT; \ + r_ret = Variant(); \ + return; \ } #else @@ -272,15 +272,15 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ int64_t i = *p_args[0]; r_ret = ABS(i); - } else if (p_args[0]->get_type() == Variant::REAL) { + } else if (p_args[0]->get_type() == Variant::FLOAT) { double r = *p_args[0]; r_ret = Math::abs(r); } else { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; - r_error.expected = Variant::REAL; + r_error.expected = Variant::FLOAT; r_ret = Variant(); } } break; @@ -290,15 +290,15 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ int64_t i = *p_args[0]; r_ret = i < 0 ? -1 : (i > 0 ? +1 : 0); - } else if (p_args[0]->get_type() == Variant::REAL) { + } else if (p_args[0]->get_type() == Variant::FLOAT) { real_t r = *p_args[0]; r_ret = r < 0.0 ? -1.0 : (r > 0.0 ? +1.0 : 0.0); } else { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; - r_error.expected = Variant::REAL; + r_error.expected = Variant::FLOAT; r_ret = Variant(); } } break; @@ -360,12 +360,12 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ VALIDATE_ARG_COUNT(3); VALIDATE_ARG_NUM(2); const double t = (double)*p_args[2]; - switch (p_args[0]->get_type() == p_args[1]->get_type() ? p_args[0]->get_type() : Variant::REAL) { + switch (p_args[0]->get_type() == p_args[1]->get_type() ? p_args[0]->get_type() : Variant::FLOAT) { case Variant::VECTOR2: { r_ret = ((Vector2)*p_args[0]).linear_interpolate((Vector2)*p_args[1], t); } break; case Variant::VECTOR3: { - r_ret = ((Vector3)*p_args[0]).linear_interpolate((Vector3)*p_args[1], t); + r_ret = (p_args[0]->operator Vector3()).linear_interpolate(p_args[1]->operator Vector3(), t); } break; case Variant::COLOR: { r_ret = ((Color)*p_args[0]).linear_interpolate((Color)*p_args[1], t); @@ -585,7 +585,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ Ref<WeakRef> wref = memnew(WeakRef); r_ret = wref; } else { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::OBJECT; r_ret = Variant(); @@ -596,7 +596,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ VALIDATE_ARG_COUNT(2); if (p_args[0]->get_type() != Variant::OBJECT) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::OBJECT; r_ret = Variant(); @@ -604,7 +604,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ } if (p_args[1]->get_type() != Variant::STRING && p_args[1]->get_type() != Variant::NODE_PATH) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 1; r_error.expected = Variant::STRING; r_ret = Variant(); @@ -626,7 +626,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ if (type < 0 || type >= Variant::VARIANT_MAX) { r_ret = RTR("Invalid type argument to convert(), use TYPE_* constants."); - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::INT; return; @@ -660,7 +660,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ if (p_args[0]->get_type() != Variant::STRING) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING; r_ret = Variant(); @@ -671,7 +671,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ if (str.length() != 1) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING; r_ret = RTR("Expected a string of length 1 (a character)."); @@ -683,7 +683,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ } break; case TEXT_STR: { if (p_arg_count < 1) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 1; r_ret = Variant(); @@ -785,7 +785,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ case PUSH_ERROR: { VALIDATE_ARG_COUNT(1); if (p_args[0]->get_type() != Variant::STRING) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING; r_ret = Variant(); @@ -799,7 +799,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ case PUSH_WARNING: { VALIDATE_ARG_COUNT(1); if (p_args[0]->get_type() != Variant::STRING) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING; r_ret = Variant(); @@ -819,7 +819,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ case STR_TO_VAR: { VALIDATE_ARG_COUNT(1); if (p_args[0]->get_type() != Variant::STRING) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING; r_ret = Variant(); @@ -837,17 +837,17 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ case VAR_TO_BYTES: { bool full_objects = false; if (p_arg_count < 1) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 1; r_ret = Variant(); return; } else if (p_arg_count > 2) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; r_error.argument = 2; r_ret = Variant(); } else if (p_arg_count == 2) { if (p_args[1]->get_type() != Variant::BOOL) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 1; r_error.expected = Variant::BOOL; r_ret = Variant(); @@ -856,11 +856,11 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ full_objects = *p_args[1]; } - PoolByteArray barr; + PackedByteArray barr; int len; Error err = encode_variant(*p_args[0], NULL, len, full_objects); if (err) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::NIL; r_ret = "Unexpected error encoding variable to bytes, likely unserializable type found (Object or RID)."; @@ -869,25 +869,25 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ barr.resize(len); { - PoolByteArray::Write w = barr.write(); - encode_variant(*p_args[0], w.ptr(), len, full_objects); + uint8_t *w = barr.ptrw(); + encode_variant(*p_args[0], w, len, full_objects); } r_ret = barr; } break; case BYTES_TO_VAR: { bool allow_objects = false; if (p_arg_count < 1) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 1; r_ret = Variant(); return; } else if (p_arg_count > 2) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; r_error.argument = 2; r_ret = Variant(); } else if (p_arg_count == 2) { if (p_args[1]->get_type() != Variant::BOOL) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 1; r_error.expected = Variant::BOOL; r_ret = Variant(); @@ -896,24 +896,24 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ allow_objects = *p_args[1]; } - if (p_args[0]->get_type() != Variant::POOL_BYTE_ARRAY) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + if (p_args[0]->get_type() != Variant::PACKED_BYTE_ARRAY) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 1; - r_error.expected = Variant::POOL_BYTE_ARRAY; + r_error.expected = Variant::PACKED_BYTE_ARRAY; r_ret = Variant(); return; } - PoolByteArray varr = *p_args[0]; + PackedByteArray varr = *p_args[0]; Variant ret; { - PoolByteArray::Read r = varr.read(); - Error err = decode_variant(ret, r.ptr(), varr.size(), NULL, allow_objects); + const uint8_t *r = varr.ptr(); + Error err = decode_variant(ret, r, varr.size(), NULL, allow_objects); if (err != OK) { r_ret = RTR("Not enough bytes for decoding bytes, or invalid format."); - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; - r_error.expected = Variant::POOL_BYTE_ARRAY; + r_error.expected = Variant::PACKED_BYTE_ARRAY; return; } } @@ -927,7 +927,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ case 0: { - r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 1; r_ret = Variant(); @@ -943,7 +943,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ } Error err = arr.resize(count); if (err != OK) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; r_ret = Variant(); return; } @@ -969,7 +969,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ } Error err = arr.resize(to - from); if (err != OK) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; r_ret = Variant(); return; } @@ -989,7 +989,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ if (incr == 0) { r_ret = RTR("Step argument is zero!"); - r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; return; } @@ -1016,7 +1016,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ Error err = arr.resize(count); if (err != OK) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; r_ret = Variant(); return; } @@ -1038,7 +1038,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ } break; default: { - r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; r_error.argument = 3; r_ret = Variant(); @@ -1049,7 +1049,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ case RESOURCE_LOAD: { VALIDATE_ARG_COUNT(1); if (p_args[0]->get_type() != Variant::STRING) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING; r_ret = Variant(); @@ -1065,7 +1065,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ if (p_args[0]->get_type() == Variant::NIL) { r_ret = Variant(); } else if (p_args[0]->get_type() != Variant::OBJECT) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_ret = Variant(); } else { @@ -1076,7 +1076,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ } else if (!obj->get_script_instance() || obj->get_script_instance()->get_language() != GDScriptLanguage::get_singleton()) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::DICTIONARY; r_ret = RTR("Not a script with an instance"); @@ -1087,7 +1087,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ Ref<GDScript> base = ins->get_script(); if (base.is_null()) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::DICTIONARY; r_ret = RTR("Not based on a script"); @@ -1105,7 +1105,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ sname.invert(); if (!p->path.is_resource_file()) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::DICTIONARY; r_ret = Variant(); @@ -1137,7 +1137,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ if (p_args[0]->get_type() != Variant::DICTIONARY) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::DICTIONARY; r_ret = Variant(); @@ -1149,7 +1149,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ if (!d.has("@path")) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::OBJECT; r_ret = RTR("Invalid instance dictionary format (missing @path)"); @@ -1160,7 +1160,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ Ref<Script> scr = ResourceLoader::load(d["@path"]); if (!scr.is_valid()) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::OBJECT; r_ret = RTR("Invalid instance dictionary format (can't load script at @path)"); @@ -1171,7 +1171,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ if (!gdscr.is_valid()) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::OBJECT; r_ret = Variant(); @@ -1189,7 +1189,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ gdscr = gdscr->subclasses[sub.get_name(i)]; if (!gdscr.is_valid()) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::OBJECT; r_ret = Variant(); @@ -1215,7 +1215,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ VALIDATE_ARG_COUNT(1); if (p_args[0]->get_type() != Variant::STRING) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING; r_ret = Variant(); @@ -1239,7 +1239,7 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ VALIDATE_ARG_COUNT(1); if (p_args[0]->get_type() != Variant::STRING) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::STRING; r_ret = Variant(); @@ -1271,14 +1271,14 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ case COLOR8: { if (p_arg_count < 3) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 3; r_ret = Variant(); return; } if (p_arg_count > 4) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; r_error.argument = 4; r_ret = Variant(); @@ -1302,21 +1302,21 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ case COLORN: { if (p_arg_count < 1) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = 1; r_ret = Variant(); return; } if (p_arg_count > 2) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; r_error.argument = 2; r_ret = Variant(); return; } if (p_args[0]->get_type() != Variant::STRING) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_ret = Variant(); } else { @@ -1359,8 +1359,8 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ case INSTANCE_FROM_ID: { VALIDATE_ARG_COUNT(1); - if (p_args[0]->get_type() != Variant::INT && p_args[0]->get_type() != Variant::REAL) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + if (p_args[0]->get_type() != Variant::INT && p_args[0]->get_type() != Variant::FLOAT) { + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::INT; r_ret = Variant(); @@ -1390,43 +1390,53 @@ void GDScriptFunctions::call(Function p_func, const Variant **p_args, int p_arg_ Array d = *p_args[0]; r_ret = d.size(); } break; - case Variant::POOL_BYTE_ARRAY: { + case Variant::PACKED_BYTE_ARRAY: { - PoolVector<uint8_t> d = *p_args[0]; + Vector<uint8_t> d = *p_args[0]; r_ret = d.size(); } break; - case Variant::POOL_INT_ARRAY: { + case Variant::PACKED_INT32_ARRAY: { - PoolVector<int> d = *p_args[0]; + Vector<int32_t> d = *p_args[0]; r_ret = d.size(); } break; - case Variant::POOL_REAL_ARRAY: { + case Variant::PACKED_INT64_ARRAY: { - PoolVector<real_t> d = *p_args[0]; + Vector<int64_t> d = *p_args[0]; r_ret = d.size(); } break; - case Variant::POOL_STRING_ARRAY: { + case Variant::PACKED_FLOAT32_ARRAY: { - PoolVector<String> d = *p_args[0]; + Vector<float> d = *p_args[0]; r_ret = d.size(); } break; - case Variant::POOL_VECTOR2_ARRAY: { + case Variant::PACKED_FLOAT64_ARRAY: { - PoolVector<Vector2> d = *p_args[0]; + Vector<double> d = *p_args[0]; r_ret = d.size(); } break; - case Variant::POOL_VECTOR3_ARRAY: { + case Variant::PACKED_STRING_ARRAY: { - PoolVector<Vector3> d = *p_args[0]; + Vector<String> d = *p_args[0]; r_ret = d.size(); } break; - case Variant::POOL_COLOR_ARRAY: { + case Variant::PACKED_VECTOR2_ARRAY: { - PoolVector<Color> d = *p_args[0]; + Vector<Vector2> d = *p_args[0]; + r_ret = d.size(); + } break; + case Variant::PACKED_VECTOR3_ARRAY: { + + Vector<Vector3> d = *p_args[0]; + r_ret = d.size(); + } break; + case Variant::PACKED_COLOR_ARRAY: { + + Vector<Color> d = *p_args[0]; r_ret = d.size(); } break; default: { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = 0; r_error.expected = Variant::OBJECT; r_ret = Variant(); @@ -1530,69 +1540,69 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { switch (p_func) { case MATH_SIN: { - MethodInfo mi("sin", PropertyInfo(Variant::REAL, "s")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("sin", PropertyInfo(Variant::FLOAT, "s")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_COS: { - MethodInfo mi("cos", PropertyInfo(Variant::REAL, "s")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("cos", PropertyInfo(Variant::FLOAT, "s")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_TAN: { - MethodInfo mi("tan", PropertyInfo(Variant::REAL, "s")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("tan", PropertyInfo(Variant::FLOAT, "s")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_SINH: { - MethodInfo mi("sinh", PropertyInfo(Variant::REAL, "s")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("sinh", PropertyInfo(Variant::FLOAT, "s")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_COSH: { - MethodInfo mi("cosh", PropertyInfo(Variant::REAL, "s")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("cosh", PropertyInfo(Variant::FLOAT, "s")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_TANH: { - MethodInfo mi("tanh", PropertyInfo(Variant::REAL, "s")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("tanh", PropertyInfo(Variant::FLOAT, "s")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_ASIN: { - MethodInfo mi("asin", PropertyInfo(Variant::REAL, "s")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("asin", PropertyInfo(Variant::FLOAT, "s")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_ACOS: { - MethodInfo mi("acos", PropertyInfo(Variant::REAL, "s")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("acos", PropertyInfo(Variant::FLOAT, "s")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_ATAN: { - MethodInfo mi("atan", PropertyInfo(Variant::REAL, "s")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("atan", PropertyInfo(Variant::FLOAT, "s")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_ATAN2: { - MethodInfo mi("atan2", PropertyInfo(Variant::REAL, "y"), PropertyInfo(Variant::REAL, "x")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("atan2", PropertyInfo(Variant::FLOAT, "y"), PropertyInfo(Variant::FLOAT, "x")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_SQRT: { - MethodInfo mi("sqrt", PropertyInfo(Variant::REAL, "s")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("sqrt", PropertyInfo(Variant::FLOAT, "s")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_FMOD: { - MethodInfo mi("fmod", PropertyInfo(Variant::REAL, "a"), PropertyInfo(Variant::REAL, "b")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("fmod", PropertyInfo(Variant::FLOAT, "a"), PropertyInfo(Variant::FLOAT, "b")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_FPOSMOD: { - MethodInfo mi("fposmod", PropertyInfo(Variant::REAL, "a"), PropertyInfo(Variant::REAL, "b")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("fposmod", PropertyInfo(Variant::FLOAT, "a"), PropertyInfo(Variant::FLOAT, "b")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_POSMOD: { @@ -1601,114 +1611,114 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { return mi; } break; case MATH_FLOOR: { - MethodInfo mi("floor", PropertyInfo(Variant::REAL, "s")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("floor", PropertyInfo(Variant::FLOAT, "s")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_CEIL: { - MethodInfo mi("ceil", PropertyInfo(Variant::REAL, "s")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("ceil", PropertyInfo(Variant::FLOAT, "s")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_ROUND: { - MethodInfo mi("round", PropertyInfo(Variant::REAL, "s")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("round", PropertyInfo(Variant::FLOAT, "s")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_ABS: { - MethodInfo mi("abs", PropertyInfo(Variant::REAL, "s")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("abs", PropertyInfo(Variant::FLOAT, "s")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_SIGN: { - MethodInfo mi("sign", PropertyInfo(Variant::REAL, "s")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("sign", PropertyInfo(Variant::FLOAT, "s")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_POW: { - MethodInfo mi("pow", PropertyInfo(Variant::REAL, "base"), PropertyInfo(Variant::REAL, "exp")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("pow", PropertyInfo(Variant::FLOAT, "base"), PropertyInfo(Variant::FLOAT, "exp")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_LOG: { - MethodInfo mi("log", PropertyInfo(Variant::REAL, "s")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("log", PropertyInfo(Variant::FLOAT, "s")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_EXP: { - MethodInfo mi("exp", PropertyInfo(Variant::REAL, "s")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("exp", PropertyInfo(Variant::FLOAT, "s")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_ISNAN: { - MethodInfo mi("is_nan", PropertyInfo(Variant::REAL, "s")); + MethodInfo mi("is_nan", PropertyInfo(Variant::FLOAT, "s")); mi.return_val.type = Variant::BOOL; return mi; } break; case MATH_ISINF: { - MethodInfo mi("is_inf", PropertyInfo(Variant::REAL, "s")); + MethodInfo mi("is_inf", PropertyInfo(Variant::FLOAT, "s")); mi.return_val.type = Variant::BOOL; return mi; } break; case MATH_ISEQUALAPPROX: { - MethodInfo mi("is_equal_approx", PropertyInfo(Variant::REAL, "a"), PropertyInfo(Variant::REAL, "b")); + MethodInfo mi("is_equal_approx", PropertyInfo(Variant::FLOAT, "a"), PropertyInfo(Variant::FLOAT, "b")); mi.return_val.type = Variant::BOOL; return mi; } break; case MATH_ISZEROAPPROX: { - MethodInfo mi("is_zero_approx", PropertyInfo(Variant::REAL, "s")); + MethodInfo mi("is_zero_approx", PropertyInfo(Variant::FLOAT, "s")); mi.return_val.type = Variant::BOOL; return mi; } break; case MATH_EASE: { - MethodInfo mi("ease", PropertyInfo(Variant::REAL, "s"), PropertyInfo(Variant::REAL, "curve")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("ease", PropertyInfo(Variant::FLOAT, "s"), PropertyInfo(Variant::FLOAT, "curve")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_STEP_DECIMALS: { - MethodInfo mi("step_decimals", PropertyInfo(Variant::REAL, "step")); + MethodInfo mi("step_decimals", PropertyInfo(Variant::FLOAT, "step")); mi.return_val.type = Variant::INT; return mi; } break; case MATH_STEPIFY: { - MethodInfo mi("stepify", PropertyInfo(Variant::REAL, "s"), PropertyInfo(Variant::REAL, "step")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("stepify", PropertyInfo(Variant::FLOAT, "s"), PropertyInfo(Variant::FLOAT, "step")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_LERP: { - MethodInfo mi("lerp", PropertyInfo(Variant::NIL, "from"), PropertyInfo(Variant::NIL, "to"), PropertyInfo(Variant::REAL, "weight")); + MethodInfo mi("lerp", PropertyInfo(Variant::NIL, "from"), PropertyInfo(Variant::NIL, "to"), PropertyInfo(Variant::FLOAT, "weight")); mi.return_val.type = Variant::NIL; mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; return mi; } break; case MATH_LERP_ANGLE: { - MethodInfo mi("lerp_angle", PropertyInfo(Variant::REAL, "from"), PropertyInfo(Variant::REAL, "to"), PropertyInfo(Variant::REAL, "weight")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("lerp_angle", PropertyInfo(Variant::FLOAT, "from"), PropertyInfo(Variant::FLOAT, "to"), PropertyInfo(Variant::FLOAT, "weight")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_INVERSE_LERP: { - MethodInfo mi("inverse_lerp", PropertyInfo(Variant::REAL, "from"), PropertyInfo(Variant::REAL, "to"), PropertyInfo(Variant::REAL, "weight")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("inverse_lerp", PropertyInfo(Variant::FLOAT, "from"), PropertyInfo(Variant::FLOAT, "to"), PropertyInfo(Variant::FLOAT, "weight")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_RANGE_LERP: { - MethodInfo mi("range_lerp", PropertyInfo(Variant::REAL, "value"), PropertyInfo(Variant::REAL, "istart"), PropertyInfo(Variant::REAL, "istop"), PropertyInfo(Variant::REAL, "ostart"), PropertyInfo(Variant::REAL, "ostop")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("range_lerp", PropertyInfo(Variant::FLOAT, "value"), PropertyInfo(Variant::FLOAT, "istart"), PropertyInfo(Variant::FLOAT, "istop"), PropertyInfo(Variant::FLOAT, "ostart"), PropertyInfo(Variant::FLOAT, "ostop")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_SMOOTHSTEP: { - MethodInfo mi("smoothstep", PropertyInfo(Variant::REAL, "from"), PropertyInfo(Variant::REAL, "to"), PropertyInfo(Variant::REAL, "weight")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("smoothstep", PropertyInfo(Variant::FLOAT, "from"), PropertyInfo(Variant::FLOAT, "to"), PropertyInfo(Variant::FLOAT, "weight")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_MOVE_TOWARD: { - MethodInfo mi("move_toward", PropertyInfo(Variant::REAL, "from"), PropertyInfo(Variant::REAL, "to"), PropertyInfo(Variant::REAL, "delta")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("move_toward", PropertyInfo(Variant::FLOAT, "from"), PropertyInfo(Variant::FLOAT, "to"), PropertyInfo(Variant::FLOAT, "delta")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_DECTIME: { - MethodInfo mi("dectime", PropertyInfo(Variant::REAL, "value"), PropertyInfo(Variant::REAL, "amount"), PropertyInfo(Variant::REAL, "step")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("dectime", PropertyInfo(Variant::FLOAT, "value"), PropertyInfo(Variant::FLOAT, "amount"), PropertyInfo(Variant::FLOAT, "step")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_RANDOMIZE: { @@ -1723,12 +1733,12 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { } break; case MATH_RANDF: { MethodInfo mi("randf"); - mi.return_val.type = Variant::REAL; + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_RANDOM: { - MethodInfo mi("rand_range", PropertyInfo(Variant::REAL, "from"), PropertyInfo(Variant::REAL, "to")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("rand_range", PropertyInfo(Variant::FLOAT, "from"), PropertyInfo(Variant::FLOAT, "to")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_SEED: { @@ -1742,32 +1752,32 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { return mi; } break; case MATH_DEG2RAD: { - MethodInfo mi("deg2rad", PropertyInfo(Variant::REAL, "deg")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("deg2rad", PropertyInfo(Variant::FLOAT, "deg")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_RAD2DEG: { - MethodInfo mi("rad2deg", PropertyInfo(Variant::REAL, "rad")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("rad2deg", PropertyInfo(Variant::FLOAT, "rad")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_LINEAR2DB: { - MethodInfo mi("linear2db", PropertyInfo(Variant::REAL, "nrg")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("linear2db", PropertyInfo(Variant::FLOAT, "nrg")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_DB2LINEAR: { - MethodInfo mi("db2linear", PropertyInfo(Variant::REAL, "db")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("db2linear", PropertyInfo(Variant::FLOAT, "db")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case MATH_POLAR2CARTESIAN: { - MethodInfo mi("polar2cartesian", PropertyInfo(Variant::REAL, "r"), PropertyInfo(Variant::REAL, "th")); + MethodInfo mi("polar2cartesian", PropertyInfo(Variant::FLOAT, "r"), PropertyInfo(Variant::FLOAT, "th")); mi.return_val.type = Variant::VECTOR2; return mi; } break; case MATH_CARTESIAN2POLAR: { - MethodInfo mi("cartesian2polar", PropertyInfo(Variant::REAL, "x"), PropertyInfo(Variant::REAL, "y")); + MethodInfo mi("cartesian2polar", PropertyInfo(Variant::FLOAT, "x"), PropertyInfo(Variant::FLOAT, "y")); mi.return_val.type = Variant::VECTOR2; return mi; } break; @@ -1777,24 +1787,24 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { return mi; } break; case MATH_WRAPF: { - MethodInfo mi("wrapf", PropertyInfo(Variant::REAL, "value"), PropertyInfo(Variant::REAL, "min"), PropertyInfo(Variant::REAL, "max")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("wrapf", PropertyInfo(Variant::FLOAT, "value"), PropertyInfo(Variant::FLOAT, "min"), PropertyInfo(Variant::FLOAT, "max")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case LOGIC_MAX: { - MethodInfo mi("max", PropertyInfo(Variant::REAL, "a"), PropertyInfo(Variant::REAL, "b")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("max", PropertyInfo(Variant::FLOAT, "a"), PropertyInfo(Variant::FLOAT, "b")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case LOGIC_MIN: { - MethodInfo mi("min", PropertyInfo(Variant::REAL, "a"), PropertyInfo(Variant::REAL, "b")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("min", PropertyInfo(Variant::FLOAT, "a"), PropertyInfo(Variant::FLOAT, "b")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case LOGIC_CLAMP: { - MethodInfo mi("clamp", PropertyInfo(Variant::REAL, "value"), PropertyInfo(Variant::REAL, "min"), PropertyInfo(Variant::REAL, "max")); - mi.return_val.type = Variant::REAL; + MethodInfo mi("clamp", PropertyInfo(Variant::FLOAT, "value"), PropertyInfo(Variant::FLOAT, "min"), PropertyInfo(Variant::FLOAT, "max")); + mi.return_val.type = Variant::FLOAT; return mi; } break; case LOGIC_NEAREST_PO2: { @@ -1941,12 +1951,12 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { MethodInfo mi("var2bytes", PropertyInfo(Variant::NIL, "var", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_NIL_IS_VARIANT), PropertyInfo(Variant::BOOL, "full_objects")); mi.default_arguments.push_back(false); - mi.return_val.type = Variant::POOL_BYTE_ARRAY; + mi.return_val.type = Variant::PACKED_BYTE_ARRAY; return mi; } break; case BYTES_TO_VAR: { - MethodInfo mi(Variant::NIL, "bytes2var", PropertyInfo(Variant::POOL_BYTE_ARRAY, "bytes"), PropertyInfo(Variant::BOOL, "allow_objects")); + MethodInfo mi(Variant::NIL, "bytes2var", PropertyInfo(Variant::PACKED_BYTE_ARRAY, "bytes"), PropertyInfo(Variant::BOOL, "allow_objects")); mi.default_arguments.push_back(false); mi.return_val.type = Variant::NIL; mi.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; @@ -2012,7 +2022,7 @@ MethodInfo GDScriptFunctions::get_info(Function p_func) { } break; case COLORN: { - MethodInfo mi("ColorN", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::REAL, "alpha")); + MethodInfo mi("ColorN", PropertyInfo(Variant::STRING, "name"), PropertyInfo(Variant::FLOAT, "alpha")); mi.default_arguments.push_back(1.0f); mi.return_val.type = Variant::COLOR; return mi; diff --git a/modules/gdscript/gdscript_functions.h b/modules/gdscript/gdscript_functions.h index 8b97194ed6..2c6dc02913 100644 --- a/modules/gdscript/gdscript_functions.h +++ b/modules/gdscript/gdscript_functions.h @@ -129,7 +129,7 @@ public: }; static const char *get_func_name(Function p_func); - static void call(Function p_func, const Variant **p_args, int p_arg_count, Variant &r_ret, Variant::CallError &r_error); + static void call(Function p_func, const Variant **p_args, int p_arg_count, Variant &r_ret, Callable::CallError &r_error); static bool is_deterministic(Function p_func); static MethodInfo get_info(Function p_func); }; diff --git a/modules/gdscript/gdscript_parser.cpp b/modules/gdscript/gdscript_parser.cpp index fae6fbbb0c..0382944efd 100644 --- a/modules/gdscript/gdscript_parser.cpp +++ b/modules/gdscript/gdscript_parser.cpp @@ -793,7 +793,7 @@ GDScriptParser::Node *GDScriptParser::_parse_expression(Node *p_parent, bool p_s } _add_warning(GDScriptWarning::UNASSIGNED_VARIABLE_OP_ASSIGN, -1, identifier.operator String()); } - FALLTHROUGH; + [[fallthrough]]; } case GDScriptTokenizer::TK_OP_ASSIGN: { lv->assignments += 1; @@ -1739,7 +1739,7 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to vptr = (const Variant **)&ptrs[0]; } - Variant::CallError ce; + Callable::CallError ce; Variant v; if (op->arguments[0]->type == Node::TYPE_TYPE) { @@ -1751,7 +1751,7 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to GDScriptFunctions::call(func, vptr, ptrs.size(), v, ce); } - if (ce.error != Variant::CallError::CALL_OK) { + if (ce.error != Callable::CallError::CALL_OK) { String errwhere; if (op->arguments[0]->type == Node::TYPE_TYPE) { @@ -1765,16 +1765,16 @@ GDScriptParser::Node *GDScriptParser::_reduce_expression(Node *p_node, bool p_to switch (ce.error) { - case Variant::CallError::CALL_ERROR_INVALID_ARGUMENT: { + case Callable::CallError::CALL_ERROR_INVALID_ARGUMENT: { _set_error("Invalid argument (#" + itos(ce.argument + 1) + ") for " + errwhere + "."); } break; - case Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: { + case Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS: { _set_error("Too many arguments for " + errwhere + "."); } break; - case Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: { + case Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS: { _set_error("Too few arguments for " + errwhere + "."); } break; @@ -2766,13 +2766,12 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { } #endif // DEBUG_ENABLED switch (token) { - case GDScriptTokenizer::TK_EOF: + case GDScriptTokenizer::TK_EOF: { p_block->end_line = tokenizer->get_token_line(); + return; // End of file! + } break; case GDScriptTokenizer::TK_ERROR: { - return; //go back - - //end of file! - + return; } break; case GDScriptTokenizer::TK_NEWLINE: { @@ -3109,7 +3108,7 @@ void GDScriptParser::_parse_block(BlockNode *p_block, bool p_static) { args.push_back(op->arguments[i]); if (constant && op->arguments[i]->type == Node::TYPE_CONSTANT) { ConstantNode *c = static_cast<ConstantNode *>(op->arguments[i]); - if (c->value.get_type() == Variant::REAL || c->value.get_type() == Variant::INT) { + if (c->value.get_type() == Variant::FLOAT || c->value.get_type() == Variant::INT) { constants.push_back(c->value); constant = true; } @@ -3525,11 +3524,12 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { case GDScriptTokenizer::TK_CURSOR: { tokenizer->advance(); } break; - case GDScriptTokenizer::TK_EOF: + case GDScriptTokenizer::TK_EOF: { p_class->end_line = tokenizer->get_token_line(); + return; // End of file! + } break; case GDScriptTokenizer::TK_ERROR: { - return; //go back - //end of file! + return; // Go back. } break; case GDScriptTokenizer::TK_NEWLINE: { if (!_parse_newline()) { @@ -3719,7 +3719,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { return; } - FALLTHROUGH; + [[fallthrough]]; } case GDScriptTokenizer::TK_PR_FUNCTION: { @@ -4220,9 +4220,9 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { break; } - FALLTHROUGH; + [[fallthrough]]; } - case Variant::REAL: { + case Variant::FLOAT: { if (tokenizer->get_token() == GDScriptTokenizer::TK_IDENTIFIER && tokenizer->get_token_identifier() == "EASE") { current_export.hint = PROPERTY_HINT_EXP_EASING; @@ -4809,7 +4809,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { } #ifdef TOOLS_ENABLED - Variant::CallError ce; + Callable::CallError ce; member.default_value = Variant::construct(member._export.type, NULL, 0, ce); #endif @@ -4878,7 +4878,7 @@ void GDScriptParser::_parse_class(ClassNode *p_class) { if (cn->value.get_type() != Variant::NIL) { if (member._export.type != Variant::NIL && cn->value.get_type() != member._export.type) { if (Variant::can_convert(cn->value.get_type(), member._export.type)) { - Variant::CallError err; + Callable::CallError err; const Variant *args = &cn->value; cn->value = Variant::construct(member._export.type, &args, 1, err); } else { @@ -5489,7 +5489,7 @@ String GDScriptParser::DataType::to_string() const { if (!gds_class.empty()) { return gds_class; } - FALLTHROUGH; + [[fallthrough]]; } case SCRIPT: { if (is_meta_type) { @@ -5933,9 +5933,9 @@ GDScriptParser::DataType GDScriptParser::_get_operation_type(const Variant::Oper a_ref.instance(); a = a_ref; } else { - Variant::CallError err; + Callable::CallError err; a = Variant::construct(a_type, NULL, 0, err); - if (err.error != Variant::CallError::CALL_OK) { + if (err.error != Callable::CallError::CALL_OK) { r_valid = false; return DataType(); } @@ -5946,19 +5946,19 @@ GDScriptParser::DataType GDScriptParser::_get_operation_type(const Variant::Oper b_ref.instance(); b = b_ref; } else { - Variant::CallError err; + Callable::CallError err; b = Variant::construct(b_type, NULL, 0, err); - if (err.error != Variant::CallError::CALL_OK) { + if (err.error != Callable::CallError::CALL_OK) { r_valid = false; return DataType(); } } // Avoid division by zero - if (a_type == Variant::INT || a_type == Variant::REAL) { + if (a_type == Variant::INT || a_type == Variant::FLOAT) { Variant::evaluate(Variant::OP_ADD, a, 1, a, r_valid); } - if (b_type == Variant::INT || b_type == Variant::REAL) { + if (b_type == Variant::INT || b_type == Variant::FLOAT) { Variant::evaluate(Variant::OP_ADD, b, 1, b, r_valid); } if (a_type == Variant::STRING && b_type != Variant::ARRAY) { @@ -6218,7 +6218,7 @@ GDScriptParser::Node *GDScriptParser::_get_default_value_for_type(const DataType result = alloc_node<DictionaryNode>(); } else { ConstantNode *c = alloc_node<ConstantNode>(); - Variant::CallError err; + Callable::CallError err; c->value = Variant::construct(p_type.builtin_type, NULL, 0, err); result = c; } @@ -6531,7 +6531,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) { result.has_type = false; } break; default: { - Variant::CallError err; + Callable::CallError err; Variant temp = Variant::construct(base_type.builtin_type, NULL, 0, err); bool valid = false; @@ -6596,16 +6596,18 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) { if (!error) { switch (base_type.builtin_type) { // Expect int or real as index - case Variant::POOL_BYTE_ARRAY: - case Variant::POOL_COLOR_ARRAY: - case Variant::POOL_INT_ARRAY: - case Variant::POOL_REAL_ARRAY: - case Variant::POOL_STRING_ARRAY: - case Variant::POOL_VECTOR2_ARRAY: - case Variant::POOL_VECTOR3_ARRAY: + case Variant::PACKED_BYTE_ARRAY: + case Variant::PACKED_COLOR_ARRAY: + case Variant::PACKED_INT32_ARRAY: + case Variant::PACKED_INT64_ARRAY: + case Variant::PACKED_FLOAT32_ARRAY: + case Variant::PACKED_FLOAT64_ARRAY: + case Variant::PACKED_STRING_ARRAY: + case Variant::PACKED_VECTOR2_ARRAY: + case Variant::PACKED_VECTOR3_ARRAY: case Variant::ARRAY: case Variant::STRING: { - error = index_type.builtin_type != Variant::INT && index_type.builtin_type != Variant::REAL; + error = index_type.builtin_type != Variant::INT && index_type.builtin_type != Variant::FLOAT; } break; // Expect String only case Variant::RECT2: @@ -6621,7 +6623,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) { case Variant::TRANSFORM2D: case Variant::BASIS: case Variant::TRANSFORM: { - error = index_type.builtin_type != Variant::INT && index_type.builtin_type != Variant::REAL && + error = index_type.builtin_type != Variant::INT && index_type.builtin_type != Variant::FLOAT && index_type.builtin_type != Variant::STRING; } break; // Expect String or int @@ -6646,17 +6648,19 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) { case Variant::STRING: case Variant::ARRAY: case Variant::DICTIONARY: - case Variant::POOL_BYTE_ARRAY: - case Variant::POOL_COLOR_ARRAY: - case Variant::POOL_INT_ARRAY: - case Variant::POOL_REAL_ARRAY: - case Variant::POOL_STRING_ARRAY: - case Variant::POOL_VECTOR2_ARRAY: - case Variant::POOL_VECTOR3_ARRAY: { + case Variant::PACKED_BYTE_ARRAY: + case Variant::PACKED_COLOR_ARRAY: + case Variant::PACKED_INT32_ARRAY: + case Variant::PACKED_INT64_ARRAY: + case Variant::PACKED_FLOAT32_ARRAY: + case Variant::PACKED_FLOAT64_ARRAY: + case Variant::PACKED_STRING_ARRAY: + case Variant::PACKED_VECTOR2_ARRAY: + case Variant::PACKED_VECTOR3_ARRAY: { break; } default: { - Variant::CallError err; + Callable::CallError err; Variant temp = Variant::construct(base_type.builtin_type, NULL, 0, err); bool valid = false; @@ -6691,41 +6695,43 @@ GDScriptParser::DataType GDScriptParser::_reduce_node_type(Node *p_node) { case Variant::NIL: case Variant::BOOL: case Variant::INT: - case Variant::REAL: + case Variant::FLOAT: case Variant::NODE_PATH: case Variant::_RID: { _set_error("Can't index on a value of type \"" + base_type.to_string() + "\".", op->line); return DataType(); } break; // Return int - case Variant::POOL_BYTE_ARRAY: - case Variant::POOL_INT_ARRAY: { + case Variant::PACKED_BYTE_ARRAY: + case Variant::PACKED_INT32_ARRAY: + case Variant::PACKED_INT64_ARRAY: { result.builtin_type = Variant::INT; } break; // Return real - case Variant::POOL_REAL_ARRAY: + case Variant::PACKED_FLOAT32_ARRAY: + case Variant::PACKED_FLOAT64_ARRAY: case Variant::VECTOR2: case Variant::VECTOR3: case Variant::QUAT: { - result.builtin_type = Variant::REAL; + result.builtin_type = Variant::FLOAT; } break; // Return color - case Variant::POOL_COLOR_ARRAY: { + case Variant::PACKED_COLOR_ARRAY: { result.builtin_type = Variant::COLOR; } break; // Return string - case Variant::POOL_STRING_ARRAY: + case Variant::PACKED_STRING_ARRAY: case Variant::STRING: { result.builtin_type = Variant::STRING; } break; // Return Vector2 - case Variant::POOL_VECTOR2_ARRAY: + case Variant::PACKED_VECTOR2_ARRAY: case Variant::TRANSFORM2D: case Variant::RECT2: { result.builtin_type = Variant::VECTOR2; } break; // Return Vector3 - case Variant::POOL_VECTOR3_ARRAY: + case Variant::PACKED_VECTOR3_ARRAY: case Variant::AABB: case Variant::BASIS: { result.builtin_type = Variant::VECTOR3; @@ -7002,7 +7008,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat break; } else { #ifdef DEBUG_ENABLED - if (arg_type.kind == DataType::BUILTIN && arg_type.builtin_type == Variant::INT && par_types[i].kind == DataType::BUILTIN && par_types[i].builtin_type == Variant::REAL) { + if (arg_type.kind == DataType::BUILTIN && arg_type.builtin_type == Variant::INT && par_types[i].kind == DataType::BUILTIN && par_types[i].builtin_type == Variant::FLOAT) { _add_warning(GDScriptWarning::NARROWING_CONVERSION, p_call->line, Variant::get_type_name(tn->vtype)); } if (par_types[i].may_yield && p_call->arguments[i + 1]->type == Node::TYPE_OPERATOR) { @@ -7095,7 +7101,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat } if (base_type.kind == DataType::BUILTIN) { - Variant::CallError err; + Callable::CallError err; Variant tmp = Variant::construct(base_type.builtin_type, NULL, 0, err); if (check_types) { @@ -7245,7 +7251,7 @@ GDScriptParser::DataType GDScriptParser::_reduce_function_call_type(const Operat _mark_line_as_unsafe(p_call->line); } } else { - if (arg_type.kind == DataType::BUILTIN && arg_type.builtin_type == Variant::INT && par_type.kind == DataType::BUILTIN && par_type.builtin_type == Variant::REAL) { + if (arg_type.kind == DataType::BUILTIN && arg_type.builtin_type == Variant::INT && par_type.kind == DataType::BUILTIN && par_type.builtin_type == Variant::FLOAT) { _add_warning(GDScriptWarning::NARROWING_CONVERSION, p_call->line, callee_name); } } @@ -8103,7 +8109,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) { lv->assign = convert_call; lv->assign_op->arguments.write[1] = convert_call; #ifdef DEBUG_ENABLED - if (lv->datatype.builtin_type == Variant::INT && assign_type.builtin_type == Variant::REAL) { + if (lv->datatype.builtin_type == Variant::INT && assign_type.builtin_type == Variant::FLOAT) { _add_warning(GDScriptWarning::NARROWING_CONVERSION, lv->line); } #endif // DEBUG_ENABLED @@ -8240,7 +8246,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) { type_match = true; // Since we are converting, the type is matching } #ifdef DEBUG_ENABLED - if (lh_type.builtin_type == Variant::INT && rh_type.builtin_type == Variant::REAL) { + if (lh_type.builtin_type == Variant::INT && rh_type.builtin_type == Variant::FLOAT) { _add_warning(GDScriptWarning::NARROWING_CONVERSION, op->line); } #endif // DEBUG_ENABLED @@ -8345,7 +8351,7 @@ void GDScriptParser::_check_block_types(BlockNode *p_block) { if (cn->value.get_type() == Variant::STRING) { break; } - FALLTHROUGH; + [[fallthrough]]; } default: { _mark_line_as_safe(statement->line); diff --git a/modules/gdscript/gdscript_tokenizer.cpp b/modules/gdscript/gdscript_tokenizer.cpp index a0e0811c1f..9064998d32 100644 --- a/modules/gdscript/gdscript_tokenizer.cpp +++ b/modules/gdscript/gdscript_tokenizer.cpp @@ -146,12 +146,15 @@ static const _bit _type_list[] = { //types { Variant::BOOL, "bool" }, { Variant::INT, "int" }, - { Variant::REAL, "float" }, + { Variant::FLOAT, "float" }, { Variant::STRING, "String" }, { Variant::VECTOR2, "Vector2" }, + { Variant::VECTOR2I, "Vector2i" }, { Variant::RECT2, "Rect2" }, + { Variant::RECT2I, "Rect2i" }, { Variant::TRANSFORM2D, "Transform2D" }, { Variant::VECTOR3, "Vector3" }, + { Variant::VECTOR3I, "Vector3i" }, { Variant::AABB, "AABB" }, { Variant::PLANE, "Plane" }, { Variant::QUAT, "Quat" }, @@ -160,16 +163,21 @@ static const _bit _type_list[] = { { Variant::COLOR, "Color" }, { Variant::_RID, "RID" }, { Variant::OBJECT, "Object" }, + { Variant::STRING_NAME, "StringName" }, { Variant::NODE_PATH, "NodePath" }, { Variant::DICTIONARY, "Dictionary" }, + { Variant::CALLABLE, "Callable" }, + { Variant::SIGNAL, "Signal" }, { Variant::ARRAY, "Array" }, - { Variant::POOL_BYTE_ARRAY, "PoolByteArray" }, - { Variant::POOL_INT_ARRAY, "PoolIntArray" }, - { Variant::POOL_REAL_ARRAY, "PoolRealArray" }, - { Variant::POOL_STRING_ARRAY, "PoolStringArray" }, - { Variant::POOL_VECTOR2_ARRAY, "PoolVector2Array" }, - { Variant::POOL_VECTOR3_ARRAY, "PoolVector3Array" }, - { Variant::POOL_COLOR_ARRAY, "PoolColorArray" }, + { Variant::PACKED_BYTE_ARRAY, "PackedByteArray" }, + { Variant::PACKED_INT32_ARRAY, "PackedInt32Array" }, + { Variant::PACKED_INT64_ARRAY, "PackedInt64Array" }, + { Variant::PACKED_FLOAT32_ARRAY, "PackedFloat32Array" }, + { Variant::PACKED_FLOAT64_ARRAY, "PackedFloat64Array" }, + { Variant::PACKED_STRING_ARRAY, "PackedStringArray" }, + { Variant::PACKED_VECTOR2_ARRAY, "PackedVector2Array" }, + { Variant::PACKED_VECTOR3_ARRAY, "PackedVector3Array" }, + { Variant::PACKED_COLOR_ARRAY, "PackedColorArray" }, { Variant::VARIANT_MAX, NULL }, }; @@ -337,7 +345,7 @@ StringName GDScriptTokenizer::get_token_literal(int p_offset) const { default: { } } - } + } break; case TK_OP_AND: case TK_OP_OR: break; // Don't get into default, since they can be non-literal @@ -475,7 +483,7 @@ void GDScriptTokenizerText::_advance() { } while (true) { - bool is_node_path = false; + bool is_string_name = false; StringMode string_mode = STRING_DOUBLE_QUOTE; switch (GETCHAR(0)) { @@ -533,7 +541,7 @@ void GDScriptTokenizerText::_advance() { ignore_warnings = true; } #endif // DEBUG_ENABLED - FALLTHROUGH; + [[fallthrough]]; } case '\n': { line++; @@ -749,8 +757,8 @@ void GDScriptTokenizerText::_advance() { return; } INCPOS(1); - is_node_path = true; - FALLTHROUGH; + is_string_name = true; + [[fallthrough]]; case '\'': case '"': { @@ -860,8 +868,8 @@ void GDScriptTokenizerText::_advance() { } INCPOS(i); - if (is_node_path) { - _make_constant(NodePath(str)); + if (is_string_name) { + _make_constant(StringName(str)); } else { _make_constant(str); } diff --git a/modules/gdscript/language_server/gdscript_language_protocol.cpp b/modules/gdscript/language_server/gdscript_language_protocol.cpp index 7133c6b4be..2243a7b81d 100644 --- a/modules/gdscript/language_server/gdscript_language_protocol.cpp +++ b/modules/gdscript/language_server/gdscript_language_protocol.cpp @@ -32,32 +32,107 @@ #include "core/io/json.h" #include "core/os/copymem.h" #include "core/project_settings.h" +#include "editor/editor_log.h" #include "editor/editor_node.h" GDScriptLanguageProtocol *GDScriptLanguageProtocol::singleton = NULL; -void GDScriptLanguageProtocol::on_data_received(int p_id) { - lastest_client_id = p_id; - Ref<WebSocketPeer> peer = server->get_peer(p_id); - PoolByteArray data; - if (OK == peer->get_packet_buffer(data)) { - String message; - message.parse_utf8((const char *)data.read().ptr(), data.size()); - if (message.begins_with("Content-Length:")) return; - String output = process_message(message); +Error GDScriptLanguageProtocol::LSPeer::handle_data() { + int read = 0; + // Read headers + if (!has_header) { + while (true) { + if (req_pos >= LSP_MAX_BUFFER_SIZE) { + req_pos = 0; + ERR_FAIL_COND_V_MSG(true, ERR_OUT_OF_MEMORY, "Response header too big"); + } + Error err = connection->get_partial_data(&req_buf[req_pos], 1, read); + if (err != OK) + return FAILED; + else if (read != 1) // Busy, wait until next poll + return ERR_BUSY; + char *r = (char *)req_buf; + int l = req_pos; + + // End of headers + if (l > 3 && r[l] == '\n' && r[l - 1] == '\r' && r[l - 2] == '\n' && r[l - 3] == '\r') { + r[l - 3] = '\0'; // Null terminate to read string + String header; + header.parse_utf8(r); + content_length = header.substr(16).to_int(); + has_header = true; + req_pos = 0; + break; + } + req_pos++; + } + } + if (has_header) { + while (req_pos < content_length) { + if (req_pos >= LSP_MAX_BUFFER_SIZE) { + req_pos = 0; + has_header = false; + ERR_FAIL_COND_V_MSG(req_pos >= LSP_MAX_BUFFER_SIZE, ERR_OUT_OF_MEMORY, "Response content too big"); + } + Error err = connection->get_partial_data(&req_buf[req_pos], 1, read); + if (err != OK) + return FAILED; + else if (read != 1) + return ERR_BUSY; + req_pos++; + } + + // Parse data + String msg; + msg.parse_utf8((const char *)req_buf, req_pos); + + // Reset to read again + req_pos = 0; + has_header = false; + + // Response + String output = GDScriptLanguageProtocol::get_singleton()->process_message(msg); if (!output.empty()) { - CharString charstr = output.utf8(); - peer->put_packet((const uint8_t *)charstr.ptr(), charstr.length()); + res_queue.push_back(output.utf8()); } } + return OK; } -void GDScriptLanguageProtocol::on_client_connected(int p_id, const String &p_protocal) { - clients.set(p_id, server->get_peer(p_id)); +Error GDScriptLanguageProtocol::LSPeer::send_data() { + int sent = 0; + if (!res_queue.empty()) { + CharString c_res = res_queue[0]; + if (res_sent < c_res.size()) { + Error err = connection->put_partial_data((const uint8_t *)c_res.get_data() + res_sent, c_res.size() - res_sent - 1, sent); + if (err != OK) { + return err; + } + res_sent += sent; + } + // Response sent + if (res_sent >= c_res.size() - 1) { + res_sent = 0; + res_queue.remove(0); + } + } + return OK; +} + +Error GDScriptLanguageProtocol::on_client_connected() { + Ref<StreamPeerTCP> tcp_peer = server->take_connection(); + ERR_FAIL_COND_V_MSG(clients.size() >= LSP_MAX_CLIENTS, FAILED, "Max client limits reached"); + Ref<LSPeer> peer = memnew(LSPeer); + peer->connection = tcp_peer; + clients.set(next_client_id, peer); + next_client_id++; + EditorNode::get_log()->add_message("Connection Taken", EditorLog::MSG_TYPE_EDITOR); + return OK; } -void GDScriptLanguageProtocol::on_client_disconnected(int p_id, bool p_was_clean_close) { - clients.erase(p_id); +void GDScriptLanguageProtocol::on_client_disconnected(const int &p_client_id) { + clients.erase(p_client_id); + EditorNode::get_log()->add_message("Disconnected", EditorLog::MSG_TYPE_EDITOR); } String GDScriptLanguageProtocol::process_message(const String &p_text) { @@ -83,11 +158,9 @@ String GDScriptLanguageProtocol::format_output(const String &p_text) { void GDScriptLanguageProtocol::_bind_methods() { ClassDB::bind_method(D_METHOD("initialize", "params"), &GDScriptLanguageProtocol::initialize); ClassDB::bind_method(D_METHOD("initialized", "params"), &GDScriptLanguageProtocol::initialized); - ClassDB::bind_method(D_METHOD("on_data_received"), &GDScriptLanguageProtocol::on_data_received); ClassDB::bind_method(D_METHOD("on_client_connected"), &GDScriptLanguageProtocol::on_client_connected); ClassDB::bind_method(D_METHOD("on_client_disconnected"), &GDScriptLanguageProtocol::on_client_disconnected); - ClassDB::bind_method(D_METHOD("notify_all_clients", "p_method", "p_params"), &GDScriptLanguageProtocol::notify_all_clients, DEFVAL(Variant())); - ClassDB::bind_method(D_METHOD("notify_client", "p_method", "p_params", "p_client"), &GDScriptLanguageProtocol::notify_client, DEFVAL(Variant()), DEFVAL(-1)); + ClassDB::bind_method(D_METHOD("notify_client", "p_method", "p_params"), &GDScriptLanguageProtocol::notify_client, DEFVAL(Variant()), DEFVAL(-1)); ClassDB::bind_method(D_METHOD("is_smart_resolve_enabled"), &GDScriptLanguageProtocol::is_smart_resolve_enabled); ClassDB::bind_method(D_METHOD("get_text_document"), &GDScriptLanguageProtocol::get_text_document); ClassDB::bind_method(D_METHOD("get_workspace"), &GDScriptLanguageProtocol::get_workspace); @@ -116,11 +189,12 @@ Dictionary GDScriptLanguageProtocol::initialize(const Dictionary &p_params) { Dictionary params; params["path"] = workspace->root; Dictionary request = make_notification("gdscrip_client/changeWorkspace", params); - if (Ref<WebSocketPeer> *peer = clients.getptr(lastest_client_id)) { + + Ref<LSPeer> peer = clients.get(latest_client_id); + if (peer != NULL) { String msg = JSON::print(request); msg = format_output(msg); - CharString charstr = msg.utf8(); - (*peer)->put_packet((const uint8_t *)charstr.ptr(), charstr.length()); + (*peer)->res_queue.push_back(msg.utf8()); } } @@ -153,61 +227,59 @@ void GDScriptLanguageProtocol::initialized(const Variant &p_params) { } void GDScriptLanguageProtocol::poll() { - server->poll(); + if (server->is_connection_available()) { + on_client_connected(); + } + const int *id = NULL; + while ((id = clients.next(id))) { + Ref<LSPeer> peer = clients.get(*id); + StreamPeerTCP::Status status = peer->connection->get_status(); + if (status == StreamPeerTCP::STATUS_NONE || status == StreamPeerTCP::STATUS_ERROR) { + on_client_disconnected(*id); + id = NULL; + } else { + if (peer->connection->get_available_bytes() > 0) { + latest_client_id = *id; + Error err = peer->handle_data(); + if (err != OK && err != ERR_BUSY) { + on_client_disconnected(*id); + id = NULL; + } + } + Error err = peer->send_data(); + if (err != OK && err != ERR_BUSY) { + on_client_disconnected(*id); + id = NULL; + } + } + } } Error GDScriptLanguageProtocol::start(int p_port, const IP_Address &p_bind_ip) { - if (server == NULL) { - server = dynamic_cast<WebSocketServer *>(ClassDB::instance("WebSocketServer")); - ERR_FAIL_COND_V(!server, FAILED); - server->set_buffers(8192, 1024, 8192, 1024); // 8mb should be way more than enough - server->connect("data_received", this, "on_data_received"); - server->connect("client_connected", this, "on_client_connected"); - server->connect("client_disconnected", this, "on_client_disconnected"); - } - server->set_bind_ip(p_bind_ip); - return server->listen(p_port); + return server->listen(p_port, p_bind_ip); } void GDScriptLanguageProtocol::stop() { - const int *ptr = clients.next(NULL); - while (ptr) { - clients.get(*ptr)->close(); - ptr = clients.next(ptr); + const int *id = NULL; + while ((id = clients.next(id))) { + Ref<LSPeer> peer = clients.get(*id); + peer->connection->disconnect_from_host(); } - server->stop(); - clients.clear(); -} - -void GDScriptLanguageProtocol::notify_all_clients(const String &p_method, const Variant &p_params) { - Dictionary message = make_notification(p_method, p_params); - String msg = JSON::print(message); - msg = format_output(msg); - CharString charstr = msg.utf8(); - const int *p_id = clients.next(NULL); - while (p_id != NULL) { - Ref<WebSocketPeer> peer = clients.get(*p_id); - (*peer)->put_packet((const uint8_t *)charstr.ptr(), charstr.length()); - p_id = clients.next(p_id); - } + server->stop(); } -void GDScriptLanguageProtocol::notify_client(const String &p_method, const Variant &p_params, int p_client) { - - if (p_client == -1) { - p_client = lastest_client_id; +void GDScriptLanguageProtocol::notify_client(const String &p_method, const Variant &p_params, int p_client_id) { + if (p_client_id == -1) { + p_client_id = latest_client_id; } - - Ref<WebSocketPeer> *peer = clients.getptr(p_client); + Ref<LSPeer> peer = clients.get(p_client_id); ERR_FAIL_COND(peer == NULL); Dictionary message = make_notification(p_method, p_params); String msg = JSON::print(message); msg = format_output(msg); - CharString charstr = msg.utf8(); - - (*peer)->put_packet((const uint8_t *)charstr.ptr(), charstr.length()); + peer->res_queue.push_back(msg.utf8()); } bool GDScriptLanguageProtocol::is_smart_resolve_enabled() const { @@ -219,7 +291,7 @@ bool GDScriptLanguageProtocol::is_goto_native_symbols_enabled() const { } GDScriptLanguageProtocol::GDScriptLanguageProtocol() { - server = NULL; + server.instance(); singleton = this; _initialized = false; workspace.instance(); @@ -228,9 +300,6 @@ GDScriptLanguageProtocol::GDScriptLanguageProtocol() { set_scope("completionItem", text_document.ptr()); set_scope("workspace", workspace.ptr()); workspace->root = ProjectSettings::get_singleton()->get_resource_path(); -} - -GDScriptLanguageProtocol::~GDScriptLanguageProtocol() { - memdelete(server); - server = NULL; + latest_client_id = 0; + next_client_id = 0; } diff --git a/modules/gdscript/language_server/gdscript_language_protocol.h b/modules/gdscript/language_server/gdscript_language_protocol.h index 52c680ab19..3f0ae36af2 100644 --- a/modules/gdscript/language_server/gdscript_language_protocol.h +++ b/modules/gdscript/language_server/gdscript_language_protocol.h @@ -31,16 +31,36 @@ #ifndef GDSCRIPT_PROTOCAL_SERVER_H #define GDSCRIPT_PROTOCAL_SERVER_H +#include "core/io/stream_peer.h" +#include "core/io/stream_peer_tcp.h" +#include "core/io/tcp_server.h" #include "gdscript_text_document.h" #include "gdscript_workspace.h" #include "lsp.hpp" #include "modules/jsonrpc/jsonrpc.h" -#include "modules/websocket/websocket_peer.h" -#include "modules/websocket/websocket_server.h" + +#define LSP_MAX_BUFFER_SIZE 4194304 +#define LSP_MAX_CLIENTS 8 class GDScriptLanguageProtocol : public JSONRPC { GDCLASS(GDScriptLanguageProtocol, JSONRPC) +private: + struct LSPeer : Reference { + Ref<StreamPeerTCP> connection; + + uint8_t req_buf[LSP_MAX_BUFFER_SIZE]; + int req_pos = 0; + bool has_header = false; + bool has_content = false; + int content_length = 0; + Vector<CharString> res_queue; + int res_sent = 0; + + Error handle_data(); + Error send_data(); + }; + enum LSPErrorCode { RequestCancelled = -32800, ContentModified = -32801, @@ -48,16 +68,16 @@ class GDScriptLanguageProtocol : public JSONRPC { static GDScriptLanguageProtocol *singleton; - HashMap<int, Ref<WebSocketPeer> > clients; - WebSocketServer *server; - int lastest_client_id; + HashMap<int, Ref<LSPeer> > clients; + Ref<TCP_Server> server; + int latest_client_id; + int next_client_id; Ref<GDScriptTextDocument> text_document; Ref<GDScriptWorkspace> workspace; - void on_data_received(int p_id); - void on_client_connected(int p_id, const String &p_protocal); - void on_client_disconnected(int p_id, bool p_was_clean_close); + Error on_client_connected(); + void on_client_disconnected(const int &p_client_id); String process_message(const String &p_text); String format_output(const String &p_text); @@ -80,14 +100,12 @@ public: Error start(int p_port, const IP_Address &p_bind_ip); void stop(); - void notify_all_clients(const String &p_method, const Variant &p_params = Variant()); - void notify_client(const String &p_method, const Variant &p_params = Variant(), int p_client = -1); + void notify_client(const String &p_method, const Variant &p_params = Variant(), int p_client_id = -1); bool is_smart_resolve_enabled() const; bool is_goto_native_symbols_enabled() const; GDScriptLanguageProtocol(); - ~GDScriptLanguageProtocol(); }; #endif diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp index 1c0590cff1..205257b8f2 100644 --- a/modules/gdscript/language_server/gdscript_workspace.cpp +++ b/modules/gdscript/language_server/gdscript_workspace.cpp @@ -33,8 +33,11 @@ #include "../gdscript_parser.h" #include "core/project_settings.h" #include "core/script_language.h" +#include "editor/editor_file_system.h" #include "editor/editor_help.h" +#include "editor/editor_node.h" #include "gdscript_language_protocol.h" +#include "scene/resources/packed_scene.h" void GDScriptWorkspace::_bind_methods() { ClassDB::bind_method(D_METHOD("symbol"), &GDScriptWorkspace::symbol); @@ -50,7 +53,7 @@ void GDScriptWorkspace::remove_cache_parser(const String &p_path) { Map<String, ExtendGDScriptParser *>::Element *parser = parse_results.find(p_path); Map<String, ExtendGDScriptParser *>::Element *script = scripts.find(p_path); if (parser && script) { - if (script->get() && script->get() == script->get()) { + if (script->get() && script->get() == parser->get()) { memdelete(script->get()); } else { memdelete(script->get()); @@ -373,6 +376,50 @@ void GDScriptWorkspace::publish_diagnostics(const String &p_path) { GDScriptLanguageProtocol::get_singleton()->notify_client("textDocument/publishDiagnostics", params); } +void GDScriptWorkspace::_get_owners(EditorFileSystemDirectory *efsd, String p_path, List<String> &owners) { + if (!efsd) + return; + + for (int i = 0; i < efsd->get_subdir_count(); i++) { + _get_owners(efsd->get_subdir(i), p_path, owners); + } + + for (int i = 0; i < efsd->get_file_count(); i++) { + + Vector<String> deps = efsd->get_file_deps(i); + bool found = false; + for (int j = 0; j < deps.size(); j++) { + if (deps[j] == p_path) { + found = true; + break; + } + } + if (!found) + continue; + + owners.push_back(efsd->get_file_path(i)); + } +} + +Node *GDScriptWorkspace::_get_owner_scene_node(String p_path) { + Node *owner_scene_node = NULL; + List<String> owners; + + _get_owners(EditorFileSystem::get_singleton()->get_filesystem(), p_path, owners); + + for (int i = 0; i < owners.size(); i++) { + NodePath owner_path = owners[i]; + RES owner_res = ResourceLoader::load(owner_path); + if (Object::cast_to<PackedScene>(owner_res.ptr())) { + Ref<PackedScene> owner_packed_scene = Ref<PackedScene>(Object::cast_to<PackedScene>(*owner_res)); + owner_scene_node = owner_packed_scene->instance(); + break; + } + } + + return owner_scene_node; +} + void GDScriptWorkspace::completion(const lsp::CompletionParams &p_params, List<ScriptCodeCompletionOption> *r_options) { String path = get_file_path(p_params.textDocument.uri); @@ -380,8 +427,12 @@ void GDScriptWorkspace::completion(const lsp::CompletionParams &p_params, List<S bool forced = false; if (const ExtendGDScriptParser *parser = get_parse_result(path)) { + Node *owner_scene_node = _get_owner_scene_node(path); String code = parser->get_text_for_completion(p_params.position); - GDScriptLanguage::get_singleton()->complete_code(code, path, NULL, r_options, forced, call_hint); + GDScriptLanguage::get_singleton()->complete_code(code, path, owner_scene_node, r_options, forced, call_hint); + if (owner_scene_node) { + memdelete(owner_scene_node); + } } } diff --git a/modules/gdscript/language_server/gdscript_workspace.h b/modules/gdscript/language_server/gdscript_workspace.h index 146a5cb7c9..e45b06747d 100644 --- a/modules/gdscript/language_server/gdscript_workspace.h +++ b/modules/gdscript/language_server/gdscript_workspace.h @@ -33,12 +33,17 @@ #include "../gdscript_parser.h" #include "core/variant.h" +#include "editor/editor_file_system.h" #include "gdscript_extend_parser.h" #include "lsp.hpp" class GDScriptWorkspace : public Reference { GDCLASS(GDScriptWorkspace, Reference); +private: + void _get_owners(EditorFileSystemDirectory *efsd, String p_path, List<String> &owners); + Node *_get_owner_scene_node(String p_path); + protected: static void _bind_methods(); void remove_cache_parser(const String &p_path); |