diff options
Diffstat (limited to 'modules')
| -rw-r--r-- | modules/gdscript/gdscript_analyzer.cpp | 61 | ||||
| -rw-r--r-- | modules/gdscript/gdscript_analyzer.h | 11 | ||||
| -rw-r--r-- | modules/gdscript/gdscript_vm.cpp | 19 | ||||
| -rw-r--r-- | modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs | 35 | ||||
| -rw-r--r-- | modules/multiplayer/multiplayer_spawner.cpp | 18 |
5 files changed, 84 insertions, 60 deletions
diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 602d07d9a7..de0dacece3 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -42,6 +42,11 @@ #include "gdscript_utility_functions.h" #include "scene/resources/packed_scene.h" +#if defined(TOOLS_ENABLED) && !defined(DISABLE_DEPRECATED) +#define SUGGEST_GODOT4_RENAMES +#include "editor/renames_map_3_to_4.h" +#endif + #define UNNAMED_ENUM "<anonymous enum>" #define ENUM_SEPARATOR "::" @@ -2601,9 +2606,8 @@ void GDScriptAnalyzer::reduce_binary_op(GDScriptParser::BinaryOpNode *p_binary_o p_binary_op->set_datatype(result); } -#ifdef TOOLS_ENABLED -#ifndef DISABLE_DEPRECATED -const char *GDScriptAnalyzer::get_rename_from_map(const char *map[][2], String key) { +#ifdef SUGGEST_GODOT4_RENAMES +const char *get_rename_from_map(const char *map[][2], String key) { for (int index = 0; map[index][0]; index++) { if (map[index][0] == key) { return map[index][1]; @@ -2614,39 +2618,39 @@ const char *GDScriptAnalyzer::get_rename_from_map(const char *map[][2], String k // Checks if an identifier/function name has been renamed in Godot 4, uses ProjectConverter3To4 for rename map. // Returns the new name if found, nullptr otherwise. -const char *GDScriptAnalyzer::check_for_renamed_identifier(String identifier, GDScriptParser::Node::Type type) { +const char *check_for_renamed_identifier(String identifier, GDScriptParser::Node::Type type) { switch (type) { case GDScriptParser::Node::IDENTIFIER: { // Check properties - const char *result = get_rename_from_map(ProjectConverter3To4::gdscript_properties_renames, identifier); + const char *result = get_rename_from_map(RenamesMap3To4::gdscript_properties_renames, identifier); if (result) { return result; } // Check enum values - result = get_rename_from_map(ProjectConverter3To4::enum_renames, identifier); + result = get_rename_from_map(RenamesMap3To4::enum_renames, identifier); if (result) { return result; } // Check color constants - result = get_rename_from_map(ProjectConverter3To4::color_renames, identifier); + result = get_rename_from_map(RenamesMap3To4::color_renames, identifier); if (result) { return result; } // Check type names - result = get_rename_from_map(ProjectConverter3To4::class_renames, identifier); + result = get_rename_from_map(RenamesMap3To4::class_renames, identifier); if (result) { return result; } - return get_rename_from_map(ProjectConverter3To4::builtin_types_renames, identifier); + return get_rename_from_map(RenamesMap3To4::builtin_types_renames, identifier); } case GDScriptParser::Node::CALL: { - const char *result = get_rename_from_map(ProjectConverter3To4::gdscript_function_renames, identifier); + const char *result = get_rename_from_map(RenamesMap3To4::gdscript_function_renames, identifier); if (result) { return result; } // Built-in Types are mistaken for function calls when the built-in type is not found. // Check built-in types if function rename not found - return get_rename_from_map(ProjectConverter3To4::builtin_types_renames, identifier); + return get_rename_from_map(RenamesMap3To4::builtin_types_renames, identifier); } // Signal references don't get parsed through the GDScriptAnalyzer. No support for signal rename hints. default: @@ -2654,8 +2658,7 @@ const char *GDScriptAnalyzer::check_for_renamed_identifier(String identifier, GD return nullptr; } } -#endif // DISABLE_DEPRECATED -#endif // TOOLS_ENABLED +#endif // SUGGEST_GODOT4_RENAMES void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool p_is_await, bool p_is_root) { bool all_is_constant = true; @@ -3078,8 +3081,7 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool p_is_a } if (!found && (is_self || (base_type.is_hard_type() && base_type.kind == GDScriptParser::DataType::BUILTIN))) { String base_name = is_self && !p_call->is_super ? "self" : base_type.to_string(); -#ifdef TOOLS_ENABLED -#ifndef DISABLE_DEPRECATED +#ifdef SUGGEST_GODOT4_RENAMES String rename_hint = String(); if (GLOBAL_GET(GDScriptWarning::get_settings_path_from_code(GDScriptWarning::Code::RENAMED_IN_GD4_HINT)).booleanize()) { const char *renamed_function_name = check_for_renamed_identifier(p_call->function_name, p_call->type); @@ -3088,12 +3090,9 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool p_is_a } } push_error(vformat(R"*(Function "%s()" not found in base %s.%s)*", p_call->function_name, base_name, rename_hint), p_call->is_super ? p_call : p_call->callee); -#else // !DISABLE_DEPRECATED - push_error(vformat(R"*(Function "%s()" not found in base %s.)*", p_call->function_name, base_name), p_call->is_super ? p_call : p_call->callee); -#endif // DISABLE_DEPRECATED #else push_error(vformat(R"*(Function "%s()" not found in base %s.)*", p_call->function_name, base_name), p_call->is_super ? p_call : p_call->callee); -#endif +#endif // SUGGEST_GODOT4_RENAMES } else if (!found && (!p_call->is_super && base_type.is_hard_type() && base_type.kind == GDScriptParser::DataType::NATIVE && base_type.is_meta_type)) { push_error(vformat(R"*(Static function "%s()" not found in base "%s".)*", p_call->function_name, base_type.native_type), p_call); } @@ -3283,8 +3282,7 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod p_identifier->reduced_value = result; p_identifier->set_datatype(type_from_variant(result, p_identifier)); } else if (base.is_hard_type()) { -#ifdef TOOLS_ENABLED -#ifndef DISABLE_DEPRECATED +#ifdef SUGGEST_GODOT4_RENAMES String rename_hint = String(); if (GLOBAL_GET(GDScriptWarning::get_settings_path_from_code(GDScriptWarning::Code::RENAMED_IN_GD4_HINT)).booleanize()) { const char *renamed_identifier_name = check_for_renamed_identifier(name, p_identifier->type); @@ -3293,12 +3291,9 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod } } push_error(vformat(R"(Cannot find constant "%s" on base "%s".%s)", name, base.to_string(), rename_hint), p_identifier); -#else // !DISABLE_DEPRECATED - push_error(vformat(R"(Cannot find constant "%s" on base "%s".)", name, base.to_string()), p_identifier); -#endif // DISABLE_DEPRECATED #else push_error(vformat(R"(Cannot find constant "%s" on base "%s".)", name, base.to_string()), p_identifier); -#endif +#endif // SUGGEST_GODOT4_RENAMES } } else { switch (base.builtin_type) { @@ -3327,8 +3322,7 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod } } if (base.is_hard_type()) { -#ifdef TOOLS_ENABLED -#ifndef DISABLE_DEPRECATED +#ifdef SUGGEST_GODOT4_RENAMES String rename_hint = String(); if (GLOBAL_GET(GDScriptWarning::get_settings_path_from_code(GDScriptWarning::Code::RENAMED_IN_GD4_HINT)).booleanize()) { const char *renamed_identifier_name = check_for_renamed_identifier(name, p_identifier->type); @@ -3337,12 +3331,9 @@ void GDScriptAnalyzer::reduce_identifier_from_base(GDScriptParser::IdentifierNod } } push_error(vformat(R"(Cannot find property "%s" on base "%s".%s)", name, base.to_string(), rename_hint), p_identifier); -#else // !DISABLE_DEPRECATED - push_error(vformat(R"(Cannot find property "%s" on base "%s".)", name, base.to_string()), p_identifier); -#endif // DISABLE_DEPRECATED #else push_error(vformat(R"(Cannot find property "%s" on base "%s".)", name, base.to_string()), p_identifier); -#endif +#endif // SUGGEST_GODOT4_RENAMES } } } @@ -3682,8 +3673,7 @@ void GDScriptAnalyzer::reduce_identifier(GDScriptParser::IdentifierNode *p_ident if (GDScriptUtilityFunctions::function_exists(name)) { push_error(vformat(R"(Built-in function "%s" cannot be used as an identifier.)", name), p_identifier); } else { -#ifdef TOOLS_ENABLED -#ifndef DISABLE_DEPRECATED +#ifdef SUGGEST_GODOT4_RENAMES String rename_hint = String(); if (GLOBAL_GET(GDScriptWarning::get_settings_path_from_code(GDScriptWarning::Code::RENAMED_IN_GD4_HINT)).booleanize()) { const char *renamed_identifier_name = check_for_renamed_identifier(name, p_identifier->type); @@ -3692,12 +3682,9 @@ void GDScriptAnalyzer::reduce_identifier(GDScriptParser::IdentifierNode *p_ident } } push_error(vformat(R"(Identifier "%s" not declared in the current scope.%s)", name, rename_hint), p_identifier); -#else // !DISABLE_DEPRECATED - push_error(vformat(R"(Identifier "%s" not declared in the current scope.)", name), p_identifier); -#endif // DISABLE_DEPRECATED #else push_error(vformat(R"(Identifier "%s" not declared in the current scope.)", name), p_identifier); -#endif +#endif // SUGGEST_GODOT4_RENAMES } GDScriptParser::DataType dummy; dummy.kind = GDScriptParser::DataType::VARIANT; diff --git a/modules/gdscript/gdscript_analyzer.h b/modules/gdscript/gdscript_analyzer.h index a4c84db6b9..cdeba374c7 100644 --- a/modules/gdscript/gdscript_analyzer.h +++ b/modules/gdscript/gdscript_analyzer.h @@ -37,10 +37,6 @@ #include "gdscript_cache.h" #include "gdscript_parser.h" -#ifdef TOOLS_ENABLED -#include "editor/project_converter_3_to_4.h" -#endif - class GDScriptAnalyzer { GDScriptParser *parser = nullptr; HashMap<String, Ref<GDScriptParserRef>> depended_parsers; @@ -137,13 +133,6 @@ class GDScriptAnalyzer { bool is_shadowing(GDScriptParser::IdentifierNode *p_local, const String &p_context); #endif -#ifdef TOOLS_ENABLED -#ifndef DISABLE_DEPRECATED - const char *get_rename_from_map(const char *map[][2], String key); - const char *check_for_renamed_identifier(String identifier, GDScriptParser::Node::Type type); -#endif // DISABLE_DEPRECATED -#endif // TOOLS_ENABLED - public: Error resolve_inheritance(); Error resolve_interface(); diff --git a/modules/gdscript/gdscript_vm.cpp b/modules/gdscript/gdscript_vm.cpp index 9b94b7a93e..7a11ea52f0 100644 --- a/modules/gdscript/gdscript_vm.cpp +++ b/modules/gdscript/gdscript_vm.cpp @@ -447,6 +447,9 @@ void (*type_init_function_table[])(Variant *) = { #define OP_GET_BASIS get_basis #define OP_GET_RID get_rid +#define METHOD_CALL_ON_NULL_VALUE_ERROR(method_pointer) "Cannot call method '" + (method_pointer)->get_name() + "' on a null value." +#define METHOD_CALL_ON_FREED_INSTANCE_ERROR(method_pointer) "Cannot call method '" + (method_pointer)->get_name() + "' on a previously freed instance." + Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_args, int p_argcount, Callable::CallError &r_err, CallState *p_state) { OPCODES_TABLE; @@ -1675,10 +1678,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a bool freed = false; Object *base_obj = base->get_validated_object_with_check(freed); if (freed) { - err_text = "Trying to call a function on a previously freed instance."; + err_text = METHOD_CALL_ON_FREED_INSTANCE_ERROR(method); OPCODE_BREAK; } else if (!base_obj) { - err_text = "Trying to call a function on a null value."; + err_text = METHOD_CALL_ON_NULL_VALUE_ERROR(method); OPCODE_BREAK; } #else @@ -1839,10 +1842,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a bool freed = false; \ Object *base_obj = base->get_validated_object_with_check(freed); \ if (freed) { \ - err_text = "Trying to call a function on a previously freed instance."; \ + err_text = METHOD_CALL_ON_FREED_INSTANCE_ERROR(method); \ OPCODE_BREAK; \ } else if (!base_obj) { \ - err_text = "Trying to call a function on a null value."; \ + err_text = METHOD_CALL_ON_NULL_VALUE_ERROR(method); \ OPCODE_BREAK; \ } \ const void **argptrs = call_args_ptr; \ @@ -1941,10 +1944,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a bool freed = false; Object *base_obj = base->get_validated_object_with_check(freed); if (freed) { - err_text = "Trying to call a function on a previously freed instance."; + err_text = METHOD_CALL_ON_FREED_INSTANCE_ERROR(method); OPCODE_BREAK; } else if (!base_obj) { - err_text = "Trying to call a function on a null value."; + err_text = METHOD_CALL_ON_NULL_VALUE_ERROR(method); OPCODE_BREAK; } #else @@ -2002,10 +2005,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a bool freed = false; Object *base_obj = base->get_validated_object_with_check(freed); if (freed) { - err_text = "Trying to call a function on a previously freed instance."; + err_text = METHOD_CALL_ON_FREED_INSTANCE_ERROR(method); OPCODE_BREAK; } else if (!base_obj) { - err_text = "Trying to call a function on a null value."; + err_text = METHOD_CALL_ON_NULL_VALUE_ERROR(method); OPCODE_BREAK; } #else diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs index 027eab30fc..79030c79cc 100644 --- a/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs +++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/GodotSynchronizationContext.cs @@ -1,17 +1,44 @@ using System; using System.Collections.Concurrent; -using System.Collections.Generic; using System.Threading; +using System.Threading.Tasks; namespace Godot { public sealed class GodotSynchronizationContext : SynchronizationContext, IDisposable { - private readonly BlockingCollection<KeyValuePair<SendOrPostCallback, object>> _queue = new(); + private readonly BlockingCollection<(SendOrPostCallback Callback, object State)> _queue = new(); + + public override void Send(SendOrPostCallback d, object state) + { + // Shortcut if we're already on this context + // Also necessary to avoid a deadlock, since Send is blocking + if (Current == this) + { + d(state); + return; + } + + var source = new TaskCompletionSource(); + + _queue.Add((st => + { + try + { + d(st); + } + finally + { + source.SetResult(); + } + }, state)); + + source.Task.Wait(); + } public override void Post(SendOrPostCallback d, object state) { - _queue.Add(new KeyValuePair<SendOrPostCallback, object>(d, state)); + _queue.Add((d, state)); } /// <summary> @@ -21,7 +48,7 @@ namespace Godot { while (_queue.TryTake(out var workItem)) { - workItem.Key(workItem.Value); + workItem.Callback(workItem.State); } } diff --git a/modules/multiplayer/multiplayer_spawner.cpp b/modules/multiplayer/multiplayer_spawner.cpp index 0aa54b69f9..4b1b6b541d 100644 --- a/modules/multiplayer/multiplayer_spawner.cpp +++ b/modules/multiplayer/multiplayer_spawner.cpp @@ -103,6 +103,15 @@ void MultiplayerSpawner::add_spawnable_scene(const String &p_path) { ERR_FAIL_COND(!FileAccess::exists(p_path)); } spawnable_scenes.push_back(sc); +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + return; + } +#endif + Node *node = get_spawn_node(); + if (spawnable_scenes.size() == 1 && node && !node->is_connected("child_entered_tree", callable_mp(this, &MultiplayerSpawner::_node_added))) { + node->connect("child_entered_tree", callable_mp(this, &MultiplayerSpawner::_node_added)); + } } int MultiplayerSpawner::get_spawnable_scene_count() const { @@ -116,6 +125,15 @@ String MultiplayerSpawner::get_spawnable_scene(int p_idx) const { void MultiplayerSpawner::clear_spawnable_scenes() { spawnable_scenes.clear(); +#ifdef TOOLS_ENABLED + if (Engine::get_singleton()->is_editor_hint()) { + return; + } +#endif + Node *node = get_spawn_node(); + if (node && node->is_connected("child_entered_tree", callable_mp(this, &MultiplayerSpawner::_node_added))) { + node->disconnect("child_entered_tree", callable_mp(this, &MultiplayerSpawner::_node_added)); + } } Vector<String> MultiplayerSpawner::_get_spawnable_scenes() const { |