diff options
Diffstat (limited to 'core')
60 files changed, 457 insertions, 307 deletions
diff --git a/core/config/engine.cpp b/core/config/engine.cpp index 2735a1aa67..bcec1a0ad4 100644 --- a/core/config/engine.cpp +++ b/core/config/engine.cpp @@ -119,6 +119,10 @@ void Engine::set_time_scale(double p_scale) { } double Engine::get_time_scale() const { + return freeze_time_scale ? 0 : _time_scale; +} + +double Engine::get_unfrozen_time_scale() const { return _time_scale; } @@ -457,6 +461,10 @@ bool Engine::notify_frame_server_synced() { return server_syncs > SERVER_SYNC_FRAME_COUNT_WARNING; } +void Engine::set_freeze_time_scale(bool p_frozen) { + freeze_time_scale = p_frozen; +} + Engine::Engine() { singleton = this; } diff --git a/core/config/engine.h b/core/config/engine.h index ec089923b3..737f0eb87e 100644 --- a/core/config/engine.h +++ b/core/config/engine.h @@ -101,6 +101,8 @@ private: int server_syncs = 0; bool frame_server_synced = false; + bool freeze_time_scale = false; + public: static Engine *get_singleton(); @@ -132,6 +134,7 @@ public: void set_time_scale(double p_scale); double get_time_scale() const; + double get_unfrozen_time_scale() const; void set_print_to_stdout(bool p_enabled); bool is_printing_to_stdout() const; @@ -202,6 +205,8 @@ public: void increment_frames_drawn(); bool notify_frame_server_synced(); + void set_freeze_time_scale(bool p_frozen); + Engine(); virtual ~Engine(); }; diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 5ac7f05a76..08ce6c0e07 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -216,36 +216,36 @@ String ProjectSettings::localize_path(const String &p_path) const { } void ProjectSettings::set_initial_value(const String &p_name, const Variant &p_value) { - ERR_FAIL_COND_MSG(!props.has(p_name), "Request for nonexistent project setting: " + p_name + "."); + ERR_FAIL_COND_MSG(!props.has(p_name), vformat("Request for nonexistent project setting: '%s'.", p_name)); // Duplicate so that if value is array or dictionary, changing the setting will not change the stored initial value. props[p_name].initial = p_value.duplicate(); } void ProjectSettings::set_restart_if_changed(const String &p_name, bool p_restart) { - ERR_FAIL_COND_MSG(!props.has(p_name), "Request for nonexistent project setting: " + p_name + "."); + ERR_FAIL_COND_MSG(!props.has(p_name), vformat("Request for nonexistent project setting: '%s'.", p_name)); props[p_name].restart_if_changed = p_restart; } void ProjectSettings::set_as_basic(const String &p_name, bool p_basic) { - ERR_FAIL_COND_MSG(!props.has(p_name), "Request for nonexistent project setting: " + p_name + "."); + ERR_FAIL_COND_MSG(!props.has(p_name), vformat("Request for nonexistent project setting: '%s'.", p_name)); props[p_name].basic = p_basic; } void ProjectSettings::set_as_internal(const String &p_name, bool p_internal) { - ERR_FAIL_COND_MSG(!props.has(p_name), "Request for nonexistent project setting: " + p_name + "."); + ERR_FAIL_COND_MSG(!props.has(p_name), vformat("Request for nonexistent project setting: '%s'.", p_name)); props[p_name].internal = p_internal; } void ProjectSettings::set_ignore_value_in_docs(const String &p_name, bool p_ignore) { - ERR_FAIL_COND_MSG(!props.has(p_name), "Request for nonexistent project setting: " + p_name + "."); + ERR_FAIL_COND_MSG(!props.has(p_name), vformat("Request for nonexistent project setting: '%s'.", p_name)); #ifdef DEBUG_METHODS_ENABLED props[p_name].ignore_value_in_docs = p_ignore; #endif } bool ProjectSettings::get_ignore_value_in_docs(const String &p_name) const { - ERR_FAIL_COND_V_MSG(!props.has(p_name), false, "Request for nonexistent project setting: " + p_name + "."); + ERR_FAIL_COND_V_MSG(!props.has(p_name), false, vformat("Request for nonexistent project setting: '%s'.", p_name)); #ifdef DEBUG_METHODS_ENABLED return props[p_name].ignore_value_in_docs; #else @@ -373,7 +373,7 @@ Variant ProjectSettings::get_setting_with_override(const StringName &p_name) con } if (!props.has(name)) { - WARN_PRINT("Property not found: " + String(name)); + WARN_PRINT(vformat("Property not found: '%s'.", String(name))); return Variant(); } return props[name].variant; @@ -567,7 +567,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b if (!p_main_pack.is_empty()) { bool ok = _load_resource_pack(p_main_pack); - ERR_FAIL_COND_V_MSG(!ok, ERR_CANT_OPEN, "Cannot open resource pack '" + p_main_pack + "'."); + ERR_FAIL_COND_V_MSG(!ok, ERR_CANT_OPEN, vformat("Cannot open resource pack '%s'.", p_main_pack)); Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary"); if (err == OK && !p_ignore_override) { @@ -646,7 +646,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b // or, if requested (`p_upwards`) in parent directories. Ref<DirAccess> d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - ERR_FAIL_COND_V_MSG(d.is_null(), ERR_CANT_CREATE, "Cannot create DirAccess for path '" + p_path + "'."); + ERR_FAIL_COND_V_MSG(d.is_null(), ERR_CANT_CREATE, vformat("Cannot create DirAccess for path '%s'.", p_path)); d->change_dir(p_path); String current_dir = d->get_current_dir(); @@ -750,7 +750,7 @@ Error ProjectSettings::_load_settings_binary(const String &p_path) { f->get_buffer(d.ptrw(), vlen); Variant value; err = decode_variant(value, d.ptr(), d.size(), nullptr, true); - ERR_CONTINUE_MSG(err != OK, "Error decoding property: " + key + "."); + ERR_CONTINUE_MSG(err != OK, vformat("Error decoding property: '%s'.", key)); set(key, value); } @@ -792,7 +792,7 @@ Error ProjectSettings::_load_settings_text(const String &p_path) { last_save_time = FileAccess::get_modified_time(get_resource_path().path_join("project.godot")); return OK; } - ERR_FAIL_COND_V_MSG(err != OK, err, "Error parsing " + p_path + " at line " + itos(lines) + ": " + error_text + " File might be corrupted."); + ERR_FAIL_COND_V_MSG(err != OK, err, vformat("Error parsing '%s' at line %d: %s File might be corrupted.", p_path, lines, error_text)); if (!assign.is_empty()) { if (section.is_empty() && assign == "config_version") { @@ -818,7 +818,7 @@ Error ProjectSettings::_load_settings_text_or_binary(const String &p_text_path, return OK; } else if (err != ERR_FILE_NOT_FOUND) { // If the file exists but can't be loaded, we want to know it. - ERR_PRINT("Couldn't load file '" + p_bin_path + "', error code " + itos(err) + "."); + ERR_PRINT(vformat("Couldn't load file '%s', error code %d.", p_bin_path, err)); } // Fallback to text-based project.godot file if binary was not found. @@ -826,7 +826,7 @@ Error ProjectSettings::_load_settings_text_or_binary(const String &p_text_path, if (err == OK) { return OK; } else if (err != ERR_FILE_NOT_FOUND) { - ERR_PRINT("Couldn't load file '" + p_text_path + "', error code " + itos(err) + "."); + ERR_PRINT(vformat("Couldn't load file '%s', error code %d.", p_text_path, err)); } return err; @@ -840,17 +840,17 @@ Error ProjectSettings::load_custom(const String &p_path) { } int ProjectSettings::get_order(const String &p_name) const { - ERR_FAIL_COND_V_MSG(!props.has(p_name), -1, "Request for nonexistent project setting: " + p_name + "."); + ERR_FAIL_COND_V_MSG(!props.has(p_name), -1, vformat("Request for nonexistent project setting: '%s'.", p_name)); return props[p_name].order; } void ProjectSettings::set_order(const String &p_name, int p_order) { - ERR_FAIL_COND_MSG(!props.has(p_name), "Request for nonexistent project setting: " + p_name + "."); + ERR_FAIL_COND_MSG(!props.has(p_name), vformat("Request for nonexistent project setting: '%s'.", p_name)); props[p_name].order = p_order; } void ProjectSettings::set_builtin_order(const String &p_name) { - ERR_FAIL_COND_MSG(!props.has(p_name), "Request for nonexistent project setting: " + p_name + "."); + ERR_FAIL_COND_MSG(!props.has(p_name), vformat("Request for nonexistent project setting: '%s'.", p_name)); if (props[p_name].order >= NO_BUILTIN_ORDER_BASE) { props[p_name].order = last_builtin_order++; } @@ -858,12 +858,12 @@ void ProjectSettings::set_builtin_order(const String &p_name) { bool ProjectSettings::is_builtin_setting(const String &p_name) const { // Return true because a false negative is worse than a false positive. - ERR_FAIL_COND_V_MSG(!props.has(p_name), true, "Request for nonexistent project setting: " + p_name + "."); + ERR_FAIL_COND_V_MSG(!props.has(p_name), true, vformat("Request for nonexistent project setting: '%s'.", p_name)); return props[p_name].order < NO_BUILTIN_ORDER_BASE; } void ProjectSettings::clear(const String &p_name) { - ERR_FAIL_COND_MSG(!props.has(p_name), "Request for nonexistent project setting: " + p_name + "."); + ERR_FAIL_COND_MSG(!props.has(p_name), vformat("Request for nonexistent project setting: '%s'.", p_name)); props.erase(p_name); } @@ -878,7 +878,7 @@ Error ProjectSettings::save() { Error ProjectSettings::_save_settings_binary(const String &p_file, const RBMap<String, List<String>> &p_props, const CustomMap &p_custom, const String &p_custom_features) { Error err; Ref<FileAccess> file = FileAccess::open(p_file, FileAccess::WRITE, &err); - ERR_FAIL_COND_V_MSG(err != OK, err, "Couldn't save project.binary at " + p_file + "."); + ERR_FAIL_COND_V_MSG(err != OK, err, vformat("Couldn't save project.binary at '%s'.", p_file)); uint8_t hdr[4] = { 'E', 'C', 'F', 'G' }; file->store_buffer(hdr, 4); @@ -948,7 +948,7 @@ Error ProjectSettings::_save_settings_text(const String &p_file, const RBMap<Str Error err; Ref<FileAccess> file = FileAccess::open(p_file, FileAccess::WRITE, &err); - ERR_FAIL_COND_V_MSG(err != OK, err, "Couldn't save project.godot - " + p_file + "."); + ERR_FAIL_COND_V_MSG(err != OK, err, vformat("Couldn't save project.godot - %s.", p_file)); file->store_line("; Engine configuration file."); file->store_line("; It's best edited using the editor UI and not directly,"); @@ -1121,7 +1121,7 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust } else if (p_path.ends_with(".binary")) { return _save_settings_binary(p_path, save_props, p_custom, save_features); } else { - ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, "Unknown config file format: " + p_path); + ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, vformat("Unknown config file format: '%s'.", p_path)); } } diff --git a/core/core_bind.cpp b/core/core_bind.cpp index 16467c9615..172ca71370 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -77,7 +77,7 @@ Ref<Resource> ResourceLoader::load(const String &p_path, const String &p_type_hi Error err = OK; Ref<Resource> ret = ::ResourceLoader::load(p_path, p_type_hint, ResourceFormatLoader::CacheMode(p_cache_mode), &err); - ERR_FAIL_COND_V_MSG(err != OK, ret, "Error loading resource: '" + p_path + "'."); + ERR_FAIL_COND_V_MSG(err != OK, ret, vformat("Error loading resource: '%s'.", p_path)); return ret; } @@ -1317,7 +1317,7 @@ void Thread::_start_func(void *ud) { } if (ce.error != Callable::CallError::CALL_OK) { - ERR_FAIL_MSG("Could not call function '" + func_name + "' to start thread " + t->get_id() + ": " + Variant::get_callable_error_text(t->target_callable, nullptr, 0, ce) + "."); + ERR_FAIL_MSG(vformat("Could not call function '%s' to start thread %d: %s.", func_name, t->get_id(), Variant::get_callable_error_text(t->target_callable, nullptr, 0, ce))); } } @@ -1542,7 +1542,7 @@ TypedArray<Dictionary> ClassDB::class_get_method_list(const StringName &p_class, return ret; } -Variant ClassDB::class_call_static_method(const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) { +Variant ClassDB::class_call_static(const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error) { if (p_argcount < 2) { r_call_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; return Variant::NIL; @@ -1683,7 +1683,7 @@ void ClassDB::_bind_methods() { ::ClassDB::bind_method(D_METHOD("class_get_method_list", "class", "no_inheritance"), &ClassDB::class_get_method_list, DEFVAL(false)); - ::ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "class_call_static_method", &ClassDB::class_call_static_method, MethodInfo("class_call_static_method", PropertyInfo(Variant::STRING_NAME, "class"), PropertyInfo(Variant::STRING_NAME, "method"))); + ::ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "class_call_static", &ClassDB::class_call_static, MethodInfo("class_call_static", PropertyInfo(Variant::STRING_NAME, "class"), PropertyInfo(Variant::STRING_NAME, "method"))); ::ClassDB::bind_method(D_METHOD("class_get_integer_constant_list", "class", "no_inheritance"), &ClassDB::class_get_integer_constant_list, DEFVAL(false)); @@ -1828,8 +1828,8 @@ Object *Engine::get_singleton_object(const StringName &p_name) const { } void Engine::register_singleton(const StringName &p_name, Object *p_object) { - ERR_FAIL_COND_MSG(has_singleton(p_name), "Singleton already registered: " + String(p_name)); - ERR_FAIL_COND_MSG(!String(p_name).is_valid_ascii_identifier(), "Singleton name is not a valid identifier: " + p_name); + ERR_FAIL_COND_MSG(has_singleton(p_name), vformat("Singleton already registered: '%s'.", String(p_name))); + ERR_FAIL_COND_MSG(!String(p_name).is_valid_ascii_identifier(), vformat("Singleton name is not a valid identifier: '%s'.", p_name)); ::Engine::Singleton s; s.class_name = p_name; s.name = p_name; @@ -1839,8 +1839,8 @@ void Engine::register_singleton(const StringName &p_name, Object *p_object) { } void Engine::unregister_singleton(const StringName &p_name) { - ERR_FAIL_COND_MSG(!has_singleton(p_name), "Attempt to remove unregistered singleton: " + String(p_name)); - ERR_FAIL_COND_MSG(!::Engine::get_singleton()->is_singleton_user_created(p_name), "Attempt to remove non-user created singleton: " + String(p_name)); + ERR_FAIL_COND_MSG(!has_singleton(p_name), vformat("Attempt to remove unregistered singleton: '%s'.", String(p_name))); + ERR_FAIL_COND_MSG(!::Engine::get_singleton()->is_singleton_user_created(p_name), vformat("Attempt to remove non-user created singleton: '%s'.", String(p_name))); ::Engine::get_singleton()->remove_singleton(p_name); } @@ -1987,14 +1987,14 @@ bool EngineDebugger::is_active() { void EngineDebugger::register_profiler(const StringName &p_name, Ref<EngineProfiler> p_profiler) { ERR_FAIL_COND(p_profiler.is_null()); ERR_FAIL_COND_MSG(p_profiler->is_bound(), "Profiler already registered."); - ERR_FAIL_COND_MSG(profilers.has(p_name) || has_profiler(p_name), "Profiler name already in use: " + p_name); + ERR_FAIL_COND_MSG(profilers.has(p_name) || has_profiler(p_name), vformat("Profiler name already in use: '%s'.", p_name)); Error err = p_profiler->bind(p_name); - ERR_FAIL_COND_MSG(err != OK, "Profiler failed to register with error: " + itos(err)); + ERR_FAIL_COND_MSG(err != OK, vformat("Profiler failed to register with error: %d.", err)); profilers.insert(p_name, p_profiler); } void EngineDebugger::unregister_profiler(const StringName &p_name) { - ERR_FAIL_COND_MSG(!profilers.has(p_name), "Profiler not registered: " + p_name); + ERR_FAIL_COND_MSG(!profilers.has(p_name), vformat("Profiler not registered: '%s'.", p_name)); profilers[p_name]->unbind(); profilers.erase(p_name); } @@ -2018,7 +2018,7 @@ void EngineDebugger::profiler_enable(const StringName &p_name, bool p_enabled, c } void EngineDebugger::register_message_capture(const StringName &p_name, const Callable &p_callable) { - ERR_FAIL_COND_MSG(captures.has(p_name) || has_capture(p_name), "Capture already registered: " + p_name); + ERR_FAIL_COND_MSG(captures.has(p_name) || has_capture(p_name), vformat("Capture already registered: '%s'.", p_name)); captures.insert(p_name, p_callable); Callable &c = captures[p_name]; ::EngineDebugger::Capture capture(&c, &EngineDebugger::call_capture); @@ -2026,7 +2026,7 @@ void EngineDebugger::register_message_capture(const StringName &p_name, const Ca } void EngineDebugger::unregister_message_capture(const StringName &p_name) { - ERR_FAIL_COND_MSG(!captures.has(p_name), "Capture not registered: " + p_name); + ERR_FAIL_COND_MSG(!captures.has(p_name), vformat("Capture not registered: '%s'.", p_name)); ::EngineDebugger::unregister_message_capture(p_name); captures.erase(p_name); } @@ -2060,8 +2060,8 @@ Error EngineDebugger::call_capture(void *p_user, const String &p_cmd, const Arra Variant retval; Callable::CallError err; capture.callp(args, 2, retval, err); - ERR_FAIL_COND_V_MSG(err.error != Callable::CallError::CALL_OK, FAILED, "Error calling 'capture' to callable: " + Variant::get_callable_error_text(capture, args, 2, err)); - ERR_FAIL_COND_V_MSG(retval.get_type() != Variant::BOOL, FAILED, "Error calling 'capture' to callable: " + String(capture) + ". Return type is not bool."); + ERR_FAIL_COND_V_MSG(err.error != Callable::CallError::CALL_OK, FAILED, vformat("Error calling 'capture' to callable: %s.", Variant::get_callable_error_text(capture, args, 2, err))); + ERR_FAIL_COND_V_MSG(retval.get_type() != Variant::BOOL, FAILED, vformat("Error calling 'capture' to callable: '%s'. Return type is not bool.", String(capture))); r_captured = retval; return OK; } diff --git a/core/core_bind.h b/core/core_bind.h index e44268d539..86828365f9 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -486,7 +486,7 @@ public: int class_get_method_argument_count(const StringName &p_class, const StringName &p_method, bool p_no_inheritance = false) const; TypedArray<Dictionary> class_get_method_list(const StringName &p_class, bool p_no_inheritance = false) const; - Variant class_call_static_method(const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error); + Variant class_call_static(const Variant **p_arguments, int p_argcount, Callable::CallError &r_call_error); PackedStringArray class_get_integer_constant_list(const StringName &p_class, bool p_no_inheritance = false) const; bool class_has_integer_constant(const StringName &p_class, const StringName &p_name) const; diff --git a/core/crypto/crypto.cpp b/core/crypto/crypto.cpp index d41a4233f4..9ba219d73a 100644 --- a/core/crypto/crypto.cpp +++ b/core/crypto/crypto.cpp @@ -242,7 +242,7 @@ Error ResourceFormatSaverCrypto::save(const Ref<Resource> &p_resource, const Str } else { ERR_FAIL_V(ERR_INVALID_PARAMETER); } - ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot save Crypto resource to file '" + p_path + "'."); + ERR_FAIL_COND_V_MSG(err != OK, err, vformat("Cannot save Crypto resource to file '%s'.", p_path)); return OK; } diff --git a/core/crypto/crypto_core.cpp b/core/crypto/crypto_core.cpp index 1071a0f0ae..c191066709 100644 --- a/core/crypto/crypto_core.cpp +++ b/core/crypto/crypto_core.cpp @@ -72,7 +72,7 @@ int CryptoCore::RandomGenerator::_entropy_poll(void *p_data, unsigned char *r_bu Error CryptoCore::RandomGenerator::init() { int ret = mbedtls_ctr_drbg_seed((mbedtls_ctr_drbg_context *)ctx, mbedtls_entropy_func, (mbedtls_entropy_context *)entropy, nullptr, 0); if (ret) { - ERR_FAIL_COND_V_MSG(ret, FAILED, " failed\n ! mbedtls_ctr_drbg_seed returned an error" + itos(ret)); + ERR_FAIL_COND_V_MSG(ret, FAILED, vformat(" failed\n ! mbedtls_ctr_drbg_seed returned an error %d.", ret)); } return OK; } @@ -80,7 +80,7 @@ Error CryptoCore::RandomGenerator::init() { Error CryptoCore::RandomGenerator::get_random_bytes(uint8_t *r_buffer, size_t p_bytes) { ERR_FAIL_NULL_V(ctx, ERR_UNCONFIGURED); int ret = mbedtls_ctr_drbg_random((mbedtls_ctr_drbg_context *)ctx, r_buffer, p_bytes); - ERR_FAIL_COND_V_MSG(ret, FAILED, " failed\n ! mbedtls_ctr_drbg_seed returned an error" + itos(ret)); + ERR_FAIL_COND_V_MSG(ret, FAILED, vformat(" failed\n ! mbedtls_ctr_drbg_seed returned an error %d.", ret)); return OK; } diff --git a/core/debugger/engine_debugger.cpp b/core/debugger/engine_debugger.cpp index 3c27691857..0928180591 100644 --- a/core/debugger/engine_debugger.cpp +++ b/core/debugger/engine_debugger.cpp @@ -48,12 +48,12 @@ HashMap<String, EngineDebugger::CreatePeerFunc> EngineDebugger::protocols; void (*EngineDebugger::allow_focus_steal_fn)(); void EngineDebugger::register_profiler(const StringName &p_name, const Profiler &p_func) { - ERR_FAIL_COND_MSG(profilers.has(p_name), "Profiler already registered: " + p_name); + ERR_FAIL_COND_MSG(profilers.has(p_name), vformat("Profiler already registered: '%s'.", p_name)); profilers.insert(p_name, p_func); } void EngineDebugger::unregister_profiler(const StringName &p_name) { - ERR_FAIL_COND_MSG(!profilers.has(p_name), "Profiler not registered: " + p_name); + ERR_FAIL_COND_MSG(!profilers.has(p_name), vformat("Profiler not registered: '%s'.", p_name)); Profiler &p = profilers[p_name]; if (p.active && p.toggle) { p.toggle(p.data, false, Array()); @@ -63,22 +63,22 @@ void EngineDebugger::unregister_profiler(const StringName &p_name) { } void EngineDebugger::register_message_capture(const StringName &p_name, Capture p_func) { - ERR_FAIL_COND_MSG(captures.has(p_name), "Capture already registered: " + p_name); + ERR_FAIL_COND_MSG(captures.has(p_name), vformat("Capture already registered: '%s'.", p_name)); captures.insert(p_name, p_func); } void EngineDebugger::unregister_message_capture(const StringName &p_name) { - ERR_FAIL_COND_MSG(!captures.has(p_name), "Capture not registered: " + p_name); + ERR_FAIL_COND_MSG(!captures.has(p_name), vformat("Capture not registered: '%s'.", p_name)); captures.erase(p_name); } void EngineDebugger::register_uri_handler(const String &p_protocol, CreatePeerFunc p_func) { - ERR_FAIL_COND_MSG(protocols.has(p_protocol), "Protocol handler already registered: " + p_protocol); + ERR_FAIL_COND_MSG(protocols.has(p_protocol), vformat("Protocol handler already registered: '%s'.", p_protocol)); protocols.insert(p_protocol, p_func); } void EngineDebugger::profiler_enable(const StringName &p_name, bool p_enabled, const Array &p_opts) { - ERR_FAIL_COND_MSG(!profilers.has(p_name), "Can't change profiler state, no profiler: " + p_name); + ERR_FAIL_COND_MSG(!profilers.has(p_name), vformat("Can't change profiler state, no profiler: '%s'.", p_name)); Profiler &p = profilers[p_name]; if (p.toggle) { p.toggle(p.data, p_enabled, p_opts); @@ -87,7 +87,7 @@ void EngineDebugger::profiler_enable(const StringName &p_name, bool p_enabled, c } void EngineDebugger::profiler_add_frame_data(const StringName &p_name, const Array &p_data) { - ERR_FAIL_COND_MSG(!profilers.has(p_name), "Can't add frame data, no profiler: " + p_name); + ERR_FAIL_COND_MSG(!profilers.has(p_name), vformat("Can't add frame data, no profiler: '%s'.", p_name)); Profiler &p = profilers[p_name]; if (p.add) { p.add(p.data, p_data); @@ -108,7 +108,7 @@ bool EngineDebugger::has_capture(const StringName &p_name) { Error EngineDebugger::capture_parse(const StringName &p_name, const String &p_msg, const Array &p_args, bool &r_captured) { r_captured = false; - ERR_FAIL_COND_V_MSG(!captures.has(p_name), ERR_UNCONFIGURED, "Capture not registered: " + p_name); + ERR_FAIL_COND_V_MSG(!captures.has(p_name), ERR_UNCONFIGURED, vformat("Capture not registered: '%s'.", p_name)); const Capture &cap = captures[p_name]; return cap.capture(cap.data, p_msg, p_args, r_captured); } @@ -166,7 +166,7 @@ void EngineDebugger::initialize(const String &p_uri, bool p_skip_breakpoints, co for (int i = 0; i < p_breakpoints.size(); i++) { const String &bp = p_breakpoints[i]; int sp = bp.rfind(":"); - ERR_CONTINUE_MSG(sp == -1, "Invalid breakpoint: '" + bp + "', expected file:line format."); + ERR_CONTINUE_MSG(sp == -1, vformat("Invalid breakpoint: '%s', expected file:line format.", bp)); singleton_script_debugger->insert_breakpoint(bp.substr(sp + 1, bp.length()).to_int(), bp.substr(0, sp)); } diff --git a/core/debugger/remote_debugger.cpp b/core/debugger/remote_debugger.cpp index aca5f56505..b69a7db989 100644 --- a/core/debugger/remote_debugger.cpp +++ b/core/debugger/remote_debugger.cpp @@ -81,7 +81,7 @@ public: for (int i = 0; i < custom_monitor_names.size(); i++) { Variant monitor_value = performance->call("get_custom_monitor", custom_monitor_names[i]); if (!monitor_value.is_num()) { - ERR_PRINT("Value of custom monitor '" + String(custom_monitor_names[i]) + "' is not a number"); + ERR_PRINT(vformat("Value of custom monitor '%s' is not a number.", String(custom_monitor_names[i]))); arr[i + max] = Variant(); } else { arr[i + max] = monitor_value; @@ -571,7 +571,7 @@ void RemoteDebugger::debug(bool p_can_continue, bool p_is_error_breakpoint) { bool captured = false; ERR_CONTINUE(_try_capture(command, data, captured) != OK); if (!captured) { - WARN_PRINT("Unknown message received from debugger: " + command); + WARN_PRINT(vformat("Unknown message received from debugger: %s.", command)); } } } else { diff --git a/core/debugger/remote_debugger_peer.cpp b/core/debugger/remote_debugger_peer.cpp index 233893dc4f..45a433e125 100644 --- a/core/debugger/remote_debugger_peer.cpp +++ b/core/debugger/remote_debugger_peer.cpp @@ -180,7 +180,7 @@ Error RemoteDebuggerPeerTCP::connect_to_host(const String &p_host, uint16_t p_po } if (tcp_client->get_status() != StreamPeerTCP::STATUS_CONNECTED) { - ERR_PRINT("Remote Debugger: Unable to connect. Status: " + String::num(tcp_client->get_status()) + "."); + ERR_PRINT(vformat("Remote Debugger: Unable to connect. Status: %s.", String::num(tcp_client->get_status()))); return FAILED; } connected = true; diff --git a/core/extension/extension_api_dump.cpp b/core/extension/extension_api_dump.cpp index 2033ff2b43..b70bd23918 100644 --- a/core/extension/extension_api_dump.cpp +++ b/core/extension/extension_api_dump.cpp @@ -1366,7 +1366,7 @@ static bool compare_dict_array(const Dictionary &p_old_api, const Dictionary &p_ return true; // May just not have this array and its still good. Probably added recently. } bool failed = false; - ERR_FAIL_COND_V_MSG(!p_new_api.has(p_base_array), false, "New API lacks base array: " + p_base_array); + ERR_FAIL_COND_V_MSG(!p_new_api.has(p_base_array), false, vformat("New API lacks base array: %s", p_base_array)); Array new_api = p_new_api[p_base_array]; HashMap<String, Dictionary> new_api_assoc; @@ -1374,6 +1374,9 @@ static bool compare_dict_array(const Dictionary &p_old_api, const Dictionary &p_ Dictionary elem = var; ERR_FAIL_COND_V_MSG(!elem.has(p_name_field), false, vformat("Validate extension JSON: Element of base_array '%s' is missing field '%s'. This is a bug.", base_array, p_name_field)); String name = elem[p_name_field]; + if (name.is_valid_float()) { + name = name.trim_suffix(".0"); // Make "integers" stringified as integers. + } if (p_compare_operators && elem.has("right_type")) { name += " " + String(elem["right_type"]); } @@ -1389,6 +1392,9 @@ static bool compare_dict_array(const Dictionary &p_old_api, const Dictionary &p_ continue; } String name = old_elem[p_name_field]; + if (name.is_valid_float()) { + name = name.trim_suffix(".0"); // Make "integers" stringified as integers. + } if (p_compare_operators && old_elem.has("right_type")) { name += " " + String(old_elem["right_type"]); } @@ -1518,7 +1524,7 @@ static bool compare_sub_dict_array(HashSet<String> &r_removed_classes_registered return true; // May just not have this array and its still good. Probably added recently or optional. } bool failed = false; - ERR_FAIL_COND_V_MSG(!p_new_api.has(p_outer), false, "New API lacks base array: " + p_outer); + ERR_FAIL_COND_V_MSG(!p_new_api.has(p_outer), false, vformat("New API lacks base array: %s", p_outer)); Array new_api = p_new_api[p_outer]; HashMap<String, Dictionary> new_api_assoc; diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp index 50f83c9d4d..2dc2735fc5 100644 --- a/core/extension/gdextension.cpp +++ b/core/extension/gdextension.cpp @@ -357,8 +357,8 @@ void GDExtension::_register_extension_class_internal(GDExtensionClassLibraryPtr StringName class_name = *reinterpret_cast<const StringName *>(p_class_name); StringName parent_class_name = *reinterpret_cast<const StringName *>(p_parent_class_name); - ERR_FAIL_COND_MSG(!String(class_name).is_valid_unicode_identifier(), "Attempt to register extension class '" + class_name + "', which is not a valid class identifier."); - ERR_FAIL_COND_MSG(ClassDB::class_exists(class_name), "Attempt to register extension class '" + class_name + "', which appears to be already registered."); + ERR_FAIL_COND_MSG(!String(class_name).is_valid_unicode_identifier(), vformat("Attempt to register extension class '%s', which is not a valid class identifier.", class_name)); + ERR_FAIL_COND_MSG(ClassDB::class_exists(class_name), vformat("Attempt to register extension class '%s', which appears to be already registered.", class_name)); Extension *parent_extension = nullptr; @@ -372,7 +372,7 @@ void GDExtension::_register_extension_class_internal(GDExtensionClassLibraryPtr //inheriting from engine class } } else { - ERR_FAIL_MSG("Attempt to register an extension class '" + String(class_name) + "' using non-existing parent class '" + String(parent_class_name) + "'."); + ERR_FAIL_MSG(vformat("Attempt to register an extension class '%s' using non-existing parent class '%s'.", String(class_name), String(parent_class_name))); } #ifdef TOOLS_ENABLED @@ -465,7 +465,7 @@ void GDExtension::_register_extension_class_method(GDExtensionClassLibraryPtr p_ StringName class_name = *reinterpret_cast<const StringName *>(p_class_name); StringName method_name = *reinterpret_cast<const StringName *>(p_method_info->name); - ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension method '" + String(method_name) + "' for unexisting class '" + class_name + "'."); + ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), vformat("Attempt to register extension method '%s' for unexisting class '%s'.", String(method_name), class_name)); #ifdef TOOLS_ENABLED Extension *extension = &self->extension_classes[class_name]; @@ -515,7 +515,7 @@ void GDExtension::_register_extension_class_integer_constant(GDExtensionClassLib StringName class_name = *reinterpret_cast<const StringName *>(p_class_name); StringName enum_name = *reinterpret_cast<const StringName *>(p_enum_name); StringName constant_name = *reinterpret_cast<const StringName *>(p_constant_name); - ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension constant '" + constant_name + "' for unexisting class '" + class_name + "'."); + ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), vformat("Attempt to register extension constant '%s' for unexisting class '%s'.", constant_name, class_name)); #ifdef TOOLS_ENABLED // If the extension is still marked as reloading, that means it failed to register again. @@ -539,7 +539,7 @@ void GDExtension::_register_extension_class_property_indexed(GDExtensionClassLib StringName setter = *reinterpret_cast<const StringName *>(p_setter); StringName getter = *reinterpret_cast<const StringName *>(p_getter); String property_name = *reinterpret_cast<const StringName *>(p_info->name); - ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension class property '" + property_name + "' for unexisting class '" + class_name + "'."); + ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), vformat("Attempt to register extension class property '%s' for unexisting class '%s'.", property_name, class_name)); #ifdef TOOLS_ENABLED // If the extension is still marked as reloading, that means it failed to register again. @@ -560,7 +560,7 @@ void GDExtension::_register_extension_class_property_group(GDExtensionClassLibra StringName class_name = *reinterpret_cast<const StringName *>(p_class_name); String group_name = *reinterpret_cast<const String *>(p_group_name); String prefix = *reinterpret_cast<const String *>(p_prefix); - ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension class property group '" + group_name + "' for unexisting class '" + class_name + "'."); + ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), vformat("Attempt to register extension class property group '%s' for unexisting class '%s'.", group_name, class_name)); #ifdef TOOLS_ENABLED // If the extension is still marked as reloading, that means it failed to register again. @@ -579,7 +579,7 @@ void GDExtension::_register_extension_class_property_subgroup(GDExtensionClassLi StringName class_name = *reinterpret_cast<const StringName *>(p_class_name); String subgroup_name = *reinterpret_cast<const String *>(p_subgroup_name); String prefix = *reinterpret_cast<const String *>(p_prefix); - ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension class property subgroup '" + subgroup_name + "' for unexisting class '" + class_name + "'."); + ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), vformat("Attempt to register extension class property subgroup '%s' for unexisting class '%s'.", subgroup_name, class_name)); #ifdef TOOLS_ENABLED // If the extension is still marked as reloading, that means it failed to register again. @@ -597,7 +597,7 @@ void GDExtension::_register_extension_class_signal(GDExtensionClassLibraryPtr p_ StringName class_name = *reinterpret_cast<const StringName *>(p_class_name); StringName signal_name = *reinterpret_cast<const StringName *>(p_signal_name); - ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to register extension class signal '" + signal_name + "' for unexisting class '" + class_name + "'."); + ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), vformat("Attempt to register extension class signal '%s' for unexisting class '%s'.", signal_name, class_name)); #ifdef TOOLS_ENABLED // If the extension is still marked as reloading, that means it failed to register again. @@ -620,7 +620,7 @@ void GDExtension::_unregister_extension_class(GDExtensionClassLibraryPtr p_libra GDExtension *self = reinterpret_cast<GDExtension *>(p_library); StringName class_name = *reinterpret_cast<const StringName *>(p_class_name); - ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), "Attempt to unregister unexisting extension class '" + class_name + "'."); + ERR_FAIL_COND_MSG(!self->extension_classes.has(class_name), vformat("Attempt to unregister unexisting extension class '%s'.", class_name)); Extension *ext = &self->extension_classes[class_name]; #ifdef TOOLS_ENABLED @@ -628,7 +628,7 @@ void GDExtension::_unregister_extension_class(GDExtensionClassLibraryPtr p_libra self->_clear_extension(ext); } #endif - ERR_FAIL_COND_MSG(ext->gdextension.children.size(), "Attempt to unregister class '" + class_name + "' while other extension classes inherit from it."); + ERR_FAIL_COND_MSG(ext->gdextension.children.size(), vformat("Attempt to unregister class '%s' while other extension classes inherit from it.", class_name)); #ifdef TOOLS_ENABLED ClassDB::unregister_extension_class(class_name, !ext->is_reloading); @@ -666,13 +666,13 @@ void GDExtension::_get_library_path(GDExtensionClassLibraryPtr p_library, GDExte HashMap<StringName, GDExtensionInterfaceFunctionPtr> GDExtension::gdextension_interface_functions; void GDExtension::register_interface_function(const StringName &p_function_name, GDExtensionInterfaceFunctionPtr p_function_pointer) { - ERR_FAIL_COND_MSG(gdextension_interface_functions.has(p_function_name), "Attempt to register interface function '" + p_function_name + "', which appears to be already registered."); + ERR_FAIL_COND_MSG(gdextension_interface_functions.has(p_function_name), vformat("Attempt to register interface function '%s', which appears to be already registered.", p_function_name)); gdextension_interface_functions.insert(p_function_name, p_function_pointer); } GDExtensionInterfaceFunctionPtr GDExtension::get_interface_function(const StringName &p_function_name) { GDExtensionInterfaceFunctionPtr *function = gdextension_interface_functions.getptr(p_function_name); - ERR_FAIL_NULL_V_MSG(function, nullptr, "Attempt to get non-existent interface function: " + String(p_function_name) + "."); + ERR_FAIL_NULL_V_MSG(function, nullptr, vformat("Attempt to get non-existent interface function: '%s'.", String(p_function_name))); return *function; } @@ -682,8 +682,8 @@ Error GDExtension::open_library(const String &p_path, const Ref<GDExtensionLoade Error err = loader->open_library(p_path); - ERR_FAIL_COND_V_MSG(err == ERR_FILE_NOT_FOUND, err, "GDExtension dynamic library not found: " + p_path); - ERR_FAIL_COND_V_MSG(err != OK, err, "Can't open GDExtension dynamic library: " + p_path); + ERR_FAIL_COND_V_MSG(err == ERR_FILE_NOT_FOUND, err, vformat("GDExtension dynamic library not found: '%s'.", p_path)); + ERR_FAIL_COND_V_MSG(err != OK, err, vformat("Can't open GDExtension dynamic library: '%s'.", p_path)); err = loader->initialize(&gdextension_get_proc_address, this, &initialization); diff --git a/core/extension/gdextension_interface.cpp b/core/extension/gdextension_interface.cpp index 9d5f71e5a6..7ae7355219 100644 --- a/core/extension/gdextension_interface.cpp +++ b/core/extension/gdextension_interface.cpp @@ -1528,7 +1528,7 @@ static GDExtensionMethodBindPtr gdextension_classdb_get_method_bind(GDExtensionC #endif if (!mb && exists) { - ERR_PRINT("Method '" + classname + "." + methodname + "' has changed and no compatibility fallback has been provided. Please open an issue."); + ERR_PRINT(vformat("Method '%s.%s' has changed and no compatibility fallback has been provided. Please open an issue.", classname, methodname)); return nullptr; } ERR_FAIL_NULL_V(mb, nullptr); diff --git a/core/extension/gdextension_library_loader.cpp b/core/extension/gdextension_library_loader.cpp index 48eec44a8c..3ff4f24ed7 100644 --- a/core/extension/gdextension_library_loader.cpp +++ b/core/extension/gdextension_library_loader.cpp @@ -221,7 +221,7 @@ Error GDExtensionLibraryLoader::initialize(GDExtensionInterfaceGetProcAddress p_ Error err = OS::get_singleton()->get_dynamic_library_symbol_handle(library, entry_symbol, entry_funcptr, false); if (err != OK) { - ERR_PRINT("GDExtension entry point '" + entry_symbol + "' not found in library " + library_path); + ERR_PRINT(vformat("GDExtension entry point '%s' not found in library %s.", entry_symbol, library_path)); return err; } @@ -232,7 +232,7 @@ Error GDExtensionLibraryLoader::initialize(GDExtensionInterfaceGetProcAddress p_ if (ret) { return OK; } else { - ERR_PRINT("GDExtension initialization function '" + entry_symbol + "' returned an error."); + ERR_PRINT(vformat("GDExtension initialization function '%s' returned an error.", entry_symbol)); return FAILED; } } @@ -274,12 +274,12 @@ Error GDExtensionLibraryLoader::parse_gdextension_file(const String &p_path) { Error err = config->load(p_path); if (err != OK) { - ERR_PRINT("Error loading GDExtension configuration file: " + p_path); + ERR_PRINT(vformat("Error loading GDExtension configuration file: '%s'.", p_path)); return err; } if (!config->has_section_key("configuration", "entry_symbol")) { - ERR_PRINT("GDExtension configuration file must contain a \"configuration/entry_symbol\" key: " + p_path); + ERR_PRINT(vformat("GDExtension configuration file must contain a \"configuration/entry_symbol\" key: '%s'.", p_path)); return ERR_INVALID_DATA; } @@ -298,7 +298,7 @@ Error GDExtensionLibraryLoader::parse_gdextension_file(const String &p_path) { } } } else { - ERR_PRINT("GDExtension configuration file must contain a \"configuration/compatibility_minimum\" key: " + p_path); + ERR_PRINT(vformat("GDExtension configuration file must contain a \"configuration/compatibility_minimum\" key: '%s'.", p_path)); return ERR_INVALID_DATA; } diff --git a/core/extension/gdextension_manager.cpp b/core/extension/gdextension_manager.cpp index 98596bda27..66203cbbad 100644 --- a/core/extension/gdextension_manager.cpp +++ b/core/extension/gdextension_manager.cpp @@ -260,7 +260,7 @@ void GDExtensionManager::load_extensions() { String s = f->get_line().strip_edges(); if (!s.is_empty()) { LoadStatus err = load_extension(s); - ERR_CONTINUE_MSG(err == LOAD_STATUS_FAILED, "Error loading extension: " + s); + ERR_CONTINUE_MSG(err == LOAD_STATUS_FAILED, vformat("Error loading extension: '%s'.", s)); } } diff --git a/core/input/input.cpp b/core/input/input.cpp index 695d3f131a..0b82292c7c 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -89,11 +89,50 @@ Input *Input::get_singleton() { void Input::set_mouse_mode(MouseMode p_mode) { ERR_FAIL_INDEX((int)p_mode, 5); + + if (p_mode == mouse_mode) { + return; + } + + // Allow to be set even if overridden, to see if the platform allows the mode. set_mouse_mode_func(p_mode); + mouse_mode = get_mouse_mode_func(); + + if (mouse_mode_override_enabled) { + set_mouse_mode_func(mouse_mode_override); + } } Input::MouseMode Input::get_mouse_mode() const { - return get_mouse_mode_func(); + return mouse_mode; +} + +void Input::set_mouse_mode_override_enabled(bool p_enabled) { + if (p_enabled == mouse_mode_override_enabled) { + return; + } + + mouse_mode_override_enabled = p_enabled; + + if (p_enabled) { + set_mouse_mode_func(mouse_mode_override); + mouse_mode_override = get_mouse_mode_func(); + } else { + set_mouse_mode_func(mouse_mode); + } +} + +void Input::set_mouse_mode_override(MouseMode p_mode) { + ERR_FAIL_INDEX((int)p_mode, 5); + + if (p_mode == mouse_mode_override) { + return; + } + + if (mouse_mode_override_enabled) { + set_mouse_mode_func(p_mode); + mouse_mode_override = get_mouse_mode_func(); + } } void Input::_bind_methods() { @@ -254,6 +293,10 @@ Input::VelocityTrack::VelocityTrack() { bool Input::is_anything_pressed() const { _THREAD_SAFE_METHOD_ + if (disable_input) { + return false; + } + if (!keys_pressed.is_empty() || !joy_buttons_pressed.is_empty() || !mouse_button_mask.is_empty()) { return true; } @@ -269,21 +312,41 @@ bool Input::is_anything_pressed() const { bool Input::is_key_pressed(Key p_keycode) const { _THREAD_SAFE_METHOD_ + + if (disable_input) { + return false; + } + return keys_pressed.has(p_keycode); } bool Input::is_physical_key_pressed(Key p_keycode) const { _THREAD_SAFE_METHOD_ + + if (disable_input) { + return false; + } + return physical_keys_pressed.has(p_keycode); } bool Input::is_key_label_pressed(Key p_keycode) const { _THREAD_SAFE_METHOD_ + + if (disable_input) { + return false; + } + return key_label_pressed.has(p_keycode); } bool Input::is_mouse_button_pressed(MouseButton p_button) const { _THREAD_SAFE_METHOD_ + + if (disable_input) { + return false; + } + return mouse_button_mask.has_flag(mouse_button_to_mask(p_button)); } @@ -297,11 +360,21 @@ static JoyButton _combine_device(JoyButton p_value, int p_device) { bool Input::is_joy_button_pressed(int p_device, JoyButton p_button) const { _THREAD_SAFE_METHOD_ + + if (disable_input) { + return false; + } + return joy_buttons_pressed.has(_combine_device(p_button, p_device)); } bool Input::is_action_pressed(const StringName &p_action, bool p_exact) const { ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), false, InputMap::get_singleton()->suggest_actions(p_action)); + + if (disable_input) { + return false; + } + HashMap<StringName, ActionState>::ConstIterator E = action_states.find(p_action); if (!E) { return false; @@ -312,6 +385,11 @@ bool Input::is_action_pressed(const StringName &p_action, bool p_exact) const { bool Input::is_action_just_pressed(const StringName &p_action, bool p_exact) const { ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), false, InputMap::get_singleton()->suggest_actions(p_action)); + + if (disable_input) { + return false; + } + HashMap<StringName, ActionState>::ConstIterator E = action_states.find(p_action); if (!E) { return false; @@ -333,6 +411,11 @@ bool Input::is_action_just_pressed(const StringName &p_action, bool p_exact) con bool Input::is_action_just_released(const StringName &p_action, bool p_exact) const { ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), false, InputMap::get_singleton()->suggest_actions(p_action)); + + if (disable_input) { + return false; + } + HashMap<StringName, ActionState>::ConstIterator E = action_states.find(p_action); if (!E) { return false; @@ -354,6 +437,11 @@ bool Input::is_action_just_released(const StringName &p_action, bool p_exact) co float Input::get_action_strength(const StringName &p_action, bool p_exact) const { ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), 0.0, InputMap::get_singleton()->suggest_actions(p_action)); + + if (disable_input) { + return 0.0f; + } + HashMap<StringName, ActionState>::ConstIterator E = action_states.find(p_action); if (!E) { return 0.0f; @@ -368,6 +456,11 @@ float Input::get_action_strength(const StringName &p_action, bool p_exact) const float Input::get_action_raw_strength(const StringName &p_action, bool p_exact) const { ERR_FAIL_COND_V_MSG(!InputMap::get_singleton()->has_action(p_action), 0.0, InputMap::get_singleton()->suggest_actions(p_action)); + + if (disable_input) { + return 0.0f; + } + HashMap<StringName, ActionState>::ConstIterator E = action_states.find(p_action); if (!E) { return 0.0f; @@ -412,6 +505,11 @@ Vector2 Input::get_vector(const StringName &p_negative_x, const StringName &p_po float Input::get_joy_axis(int p_device, JoyAxis p_axis) const { _THREAD_SAFE_METHOD_ + + if (disable_input) { + return 0; + } + JoyAxis c = _combine_device(p_axis, p_device); if (_joy_axis.has(c)) { return _joy_axis[c]; @@ -1666,6 +1764,14 @@ int Input::get_unused_joy_id() { return -1; } +void Input::set_disable_input(bool p_disable) { + disable_input = p_disable; +} + +bool Input::is_input_disabled() const { + return disable_input; +} + Input::Input() { singleton = this; diff --git a/core/input/input.h b/core/input/input.h index 32db2c0f2f..a4c8bd1d6a 100644 --- a/core/input/input.h +++ b/core/input/input.h @@ -105,6 +105,11 @@ private: Vector2 mouse_pos; int64_t mouse_window = 0; bool legacy_just_pressed_behavior = false; + bool disable_input = false; + + MouseMode mouse_mode = MOUSE_MODE_VISIBLE; + bool mouse_mode_override_enabled = false; + MouseMode mouse_mode_override = MOUSE_MODE_VISIBLE; struct ActionState { uint64_t pressed_physics_frame = UINT64_MAX; @@ -281,6 +286,8 @@ protected: public: void set_mouse_mode(MouseMode p_mode); MouseMode get_mouse_mode() const; + void set_mouse_mode_override_enabled(bool p_enabled); + void set_mouse_mode_override(MouseMode p_mode); #ifdef TOOLS_ENABLED void get_argument_options(const StringName &p_function, int p_idx, List<String> *r_options) const override; @@ -382,6 +389,9 @@ public: void set_event_dispatch_function(EventDispatchFunc p_function); + void set_disable_input(bool p_disable); + bool is_input_disabled() const; + Input(); ~Input(); }; diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp index 9c10b143dd..553de4af9c 100644 --- a/core/input/input_map.cpp +++ b/core/input/input_map.cpp @@ -116,7 +116,7 @@ void InputMap::get_argument_options(const StringName &p_function, int p_idx, Lis #endif void InputMap::add_action(const StringName &p_action, float p_deadzone) { - ERR_FAIL_COND_MSG(input_map.has(p_action), "InputMap already has action \"" + String(p_action) + "\"."); + ERR_FAIL_COND_MSG(input_map.has(p_action), vformat("InputMap already has action \"%s\".", String(p_action))); input_map[p_action] = Action(); static int last_id = 1; input_map[p_action].id = last_id; diff --git a/core/io/dir_access.cpp b/core/io/dir_access.cpp index 7d76156309..18df616332 100644 --- a/core/io/dir_access.cpp +++ b/core/io/dir_access.cpp @@ -179,7 +179,7 @@ Error DirAccess::make_dir_recursive(const String &p_dir) { curpath = curpath.path_join(subdirs[i]); Error err = make_dir(curpath); if (err != OK && err != ERR_ALREADY_EXISTS) { - ERR_FAIL_V_MSG(err, "Could not create directory: " + curpath); + ERR_FAIL_V_MSG(err, vformat("Could not create directory: '%s'.", curpath)); } } @@ -241,7 +241,7 @@ Ref<DirAccess> DirAccess::create_for_path(const String &p_path) { Ref<DirAccess> DirAccess::open(const String &p_path, Error *r_error) { Ref<DirAccess> da = create_for_path(p_path); - ERR_FAIL_COND_V_MSG(da.is_null(), nullptr, "Cannot create DirAccess for path '" + p_path + "'."); + ERR_FAIL_COND_V_MSG(da.is_null(), nullptr, vformat("Cannot create DirAccess for path '%s'.", p_path)); Error err = da->change_dir(p_path); if (r_error) { *r_error = err; @@ -347,10 +347,10 @@ Error DirAccess::copy(const String &p_from, const String &p_to, int p_chmod_flag Error err; { Ref<FileAccess> fsrc = FileAccess::open(p_from, FileAccess::READ, &err); - ERR_FAIL_COND_V_MSG(err != OK, err, "Failed to open " + p_from); + ERR_FAIL_COND_V_MSG(err != OK, err, vformat("Failed to open '%s'.", p_from)); Ref<FileAccess> fdst = FileAccess::open(p_to, FileAccess::WRITE, &err); - ERR_FAIL_COND_V_MSG(err != OK, err, "Failed to open " + p_to); + ERR_FAIL_COND_V_MSG(err != OK, err, vformat("Failed to open '%s'.", p_to)); const size_t copy_buffer_limit = 65536; // 64 KB @@ -446,11 +446,11 @@ Error DirAccess::_copy_dir(Ref<DirAccess> &p_target_da, const String &p_to, int String target_dir = p_to + rel_path; if (!p_target_da->dir_exists(target_dir)) { Error err = p_target_da->make_dir(target_dir); - ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot create directory '" + target_dir + "'."); + ERR_FAIL_COND_V_MSG(err != OK, err, vformat("Cannot create directory '%s'.", target_dir)); } Error err = change_dir(rel_path); - ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot change current directory to '" + rel_path + "'."); + ERR_FAIL_COND_V_MSG(err != OK, err, vformat("Cannot change current directory to '%s'.", rel_path)); err = _copy_dir(p_target_da, p_to + rel_path + "/", p_chmod_flags, p_copy_links); if (err) { @@ -468,11 +468,11 @@ Error DirAccess::copy_dir(const String &p_from, String p_to, int p_chmod_flags, ERR_FAIL_COND_V_MSG(!dir_exists(p_from), ERR_FILE_NOT_FOUND, "Source directory doesn't exist."); Ref<DirAccess> target_da = DirAccess::create_for_path(p_to); - ERR_FAIL_COND_V_MSG(target_da.is_null(), ERR_CANT_CREATE, "Cannot create DirAccess for path '" + p_to + "'."); + ERR_FAIL_COND_V_MSG(target_da.is_null(), ERR_CANT_CREATE, vformat("Cannot create DirAccess for path '%s'.", p_to)); if (!target_da->dir_exists(p_to)) { Error err = target_da->make_dir_recursive(p_to); - ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot create directory '" + p_to + "'."); + ERR_FAIL_COND_V_MSG(err != OK, err, vformat("Cannot create directory '%s'.", p_to)); } if (!p_to.ends_with("/")) { diff --git a/core/io/dir_access.h b/core/io/dir_access.h index 2567764e55..670c512ea9 100644 --- a/core/io/dir_access.h +++ b/core/io/dir_access.h @@ -118,10 +118,10 @@ public: Ref<DirAccess> da = create(ACCESS_FILESYSTEM); if (da->file_exists(p_path)) { if (da->remove(p_path) != OK) { - ERR_FAIL_MSG("Cannot remove file or directory: " + p_path); + ERR_FAIL_MSG(vformat("Cannot remove file or directory: '%s'.", p_path)); } } else { - ERR_FAIL_MSG("Cannot remove non-existent file or directory: " + p_path); + ERR_FAIL_MSG(vformat("Cannot remove non-existent file or directory: '%s'.", p_path)); } } diff --git a/core/io/file_access.cpp b/core/io/file_access.cpp index 69ad8bbeda..e10462adcd 100644 --- a/core/io/file_access.cpp +++ b/core/io/file_access.cpp @@ -461,7 +461,7 @@ Vector<uint8_t> FileAccess::get_buffer(int64_t p_length) const { } Error err = data.resize(p_length); - ERR_FAIL_COND_V_MSG(err != OK, data, "Can't resize data to " + itos(p_length) + " elements."); + ERR_FAIL_COND_V_MSG(err != OK, data, vformat("Can't resize data to %d elements.", p_length)); uint8_t *w = data.ptrw(); int64_t len = get_buffer(w, p_length); @@ -542,7 +542,7 @@ uint64_t FileAccess::get_modified_time(const String &p_file) { } Ref<FileAccess> fa = create_for_path(p_file); - ERR_FAIL_COND_V_MSG(fa.is_null(), 0, "Cannot create FileAccess for path '" + p_file + "'."); + ERR_FAIL_COND_V_MSG(fa.is_null(), 0, vformat("Cannot create FileAccess for path '%s'.", p_file)); uint64_t mt = fa->_get_modified_time(p_file); return mt; @@ -554,7 +554,7 @@ BitField<FileAccess::UnixPermissionFlags> FileAccess::get_unix_permissions(const } Ref<FileAccess> fa = create_for_path(p_file); - ERR_FAIL_COND_V_MSG(fa.is_null(), 0, "Cannot create FileAccess for path '" + p_file + "'."); + ERR_FAIL_COND_V_MSG(fa.is_null(), 0, vformat("Cannot create FileAccess for path '%s'.", p_file)); return fa->_get_unix_permissions(p_file); } @@ -565,7 +565,7 @@ Error FileAccess::set_unix_permissions(const String &p_file, BitField<FileAccess } Ref<FileAccess> fa = create_for_path(p_file); - ERR_FAIL_COND_V_MSG(fa.is_null(), ERR_CANT_CREATE, "Cannot create FileAccess for path '" + p_file + "'."); + ERR_FAIL_COND_V_MSG(fa.is_null(), ERR_CANT_CREATE, vformat("Cannot create FileAccess for path '%s'.", p_file)); Error err = fa->_set_unix_permissions(p_file, p_permissions); return err; @@ -577,7 +577,7 @@ bool FileAccess::get_hidden_attribute(const String &p_file) { } Ref<FileAccess> fa = create_for_path(p_file); - ERR_FAIL_COND_V_MSG(fa.is_null(), false, "Cannot create FileAccess for path '" + p_file + "'."); + ERR_FAIL_COND_V_MSG(fa.is_null(), false, vformat("Cannot create FileAccess for path '%s'.", p_file)); return fa->_get_hidden_attribute(p_file); } @@ -588,7 +588,7 @@ Error FileAccess::set_hidden_attribute(const String &p_file, bool p_hidden) { } Ref<FileAccess> fa = create_for_path(p_file); - ERR_FAIL_COND_V_MSG(fa.is_null(), ERR_CANT_CREATE, "Cannot create FileAccess for path '" + p_file + "'."); + ERR_FAIL_COND_V_MSG(fa.is_null(), ERR_CANT_CREATE, vformat("Cannot create FileAccess for path '%s'.", p_file)); Error err = fa->_set_hidden_attribute(p_file, p_hidden); return err; @@ -600,7 +600,7 @@ bool FileAccess::get_read_only_attribute(const String &p_file) { } Ref<FileAccess> fa = create_for_path(p_file); - ERR_FAIL_COND_V_MSG(fa.is_null(), false, "Cannot create FileAccess for path '" + p_file + "'."); + ERR_FAIL_COND_V_MSG(fa.is_null(), false, vformat("Cannot create FileAccess for path '%s'.", p_file)); return fa->_get_read_only_attribute(p_file); } @@ -611,7 +611,7 @@ Error FileAccess::set_read_only_attribute(const String &p_file, bool p_ro) { } Ref<FileAccess> fa = create_for_path(p_file); - ERR_FAIL_COND_V_MSG(fa.is_null(), ERR_CANT_CREATE, "Cannot create FileAccess for path '" + p_file + "'."); + ERR_FAIL_COND_V_MSG(fa.is_null(), ERR_CANT_CREATE, vformat("Cannot create FileAccess for path '%s'.", p_file)); Error err = fa->_set_read_only_attribute(p_file, p_ro); return err; @@ -699,7 +699,7 @@ Vector<uint8_t> FileAccess::get_file_as_bytes(const String &p_path, Error *r_err if (r_error) { // if error requested, do not throw error return Vector<uint8_t>(); } - ERR_FAIL_V_MSG(Vector<uint8_t>(), "Can't open file from path '" + String(p_path) + "'."); + ERR_FAIL_V_MSG(Vector<uint8_t>(), vformat("Can't open file from path '%s'.", String(p_path))); } Vector<uint8_t> data; data.resize(f->get_length()); @@ -717,7 +717,7 @@ String FileAccess::get_file_as_string(const String &p_path, Error *r_error) { if (r_error) { return String(); } - ERR_FAIL_V_MSG(String(), "Can't get file as string from path '" + String(p_path) + "'."); + ERR_FAIL_V_MSG(String(), vformat("Can't get file as string from path '%s'.", String(p_path))); } String ret; diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp index 05335df9e9..84137251ef 100644 --- a/core/io/file_access_compressed.cpp +++ b/core/io/file_access_compressed.cpp @@ -60,7 +60,7 @@ Error FileAccessCompressed::open_after_magic(Ref<FileAccess> p_base) { block_size = f->get_32(); if (block_size == 0) { f.unref(); - ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, "Can't open compressed file '" + p_base->get_path() + "' with block size 0, it is corrupted."); + ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, vformat("Can't open compressed file '%s' with block size 0, it is corrupted.", p_base->get_path())); } read_total = f->get_32(); uint32_t bc = (read_total / block_size) + 1; diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp index 6c406afff0..a84aa4c800 100644 --- a/core/io/file_access_encrypted.cpp +++ b/core/io/file_access_encrypted.cpp @@ -39,7 +39,7 @@ #include <stdio.h> Error FileAccessEncrypted::open_and_parse(Ref<FileAccess> p_base, const Vector<uint8_t> &p_key, Mode p_mode, bool p_with_magic) { - ERR_FAIL_COND_V_MSG(file.is_valid(), ERR_ALREADY_IN_USE, "Can't open file while another file from path '" + file->get_path_absolute() + "' is open."); + ERR_FAIL_COND_V_MSG(file.is_valid(), ERR_ALREADY_IN_USE, vformat("Can't open file while another file from path '%s' is open.", file->get_path_absolute())); ERR_FAIL_COND_V(p_key.size() != 32, ERR_INVALID_PARAMETER); pos = 0; diff --git a/core/io/file_access_memory.cpp b/core/io/file_access_memory.cpp index 199a51e86d..2ead49ba81 100644 --- a/core/io/file_access_memory.cpp +++ b/core/io/file_access_memory.cpp @@ -87,7 +87,7 @@ Error FileAccessMemory::open_internal(const String &p_path, int p_mode_flags) { //name = DirAccess::normalize_path(name); HashMap<String, Vector<uint8_t>>::Iterator E = files->find(name); - ERR_FAIL_COND_V_MSG(!E, ERR_FILE_NOT_FOUND, "Can't find file '" + p_path + "'."); + ERR_FAIL_COND_V_MSG(!E, ERR_FILE_NOT_FOUND, vformat("Can't find file '%s'.", p_path)); data = E->value.ptrw(); length = E->value.size(); diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp index 6f2685163e..7bc96c4644 100644 --- a/core/io/file_access_pack.cpp +++ b/core/io/file_access_pack.cpp @@ -225,8 +225,8 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files, uint32_t ver_minor = f->get_32(); f->get_32(); // patch number, not used for validation. - ERR_FAIL_COND_V_MSG(version != PACK_FORMAT_VERSION, false, "Pack version unsupported: " + itos(version) + "."); - ERR_FAIL_COND_V_MSG(ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), false, "Pack created with a newer version of the engine: " + itos(ver_major) + "." + itos(ver_minor) + "."); + ERR_FAIL_COND_V_MSG(version != PACK_FORMAT_VERSION, false, vformat("Pack version unsupported: %d.", version)); + ERR_FAIL_COND_V_MSG(ver_major > VERSION_MAJOR || (ver_major == VERSION_MAJOR && ver_minor > VERSION_MINOR), false, vformat("Pack created with a newer version of the engine: %d.%d.", ver_major, ver_minor)); uint32_t pack_flags = f->get_32(); uint64_t file_base = f->get_64(); @@ -388,7 +388,7 @@ void FileAccessPack::close() { FileAccessPack::FileAccessPack(const String &p_path, const PackedData::PackedFile &p_file) : pf(p_file), f(FileAccess::open(pf.pack, FileAccess::READ)) { - ERR_FAIL_COND_MSG(f.is_null(), "Can't open pack-referenced file '" + String(pf.pack) + "'."); + ERR_FAIL_COND_MSG(f.is_null(), vformat("Can't open pack-referenced file '%s'.", String(pf.pack))); f->seek(pf.offset); off = pf.offset; @@ -396,7 +396,7 @@ FileAccessPack::FileAccessPack(const String &p_path, const PackedData::PackedFil if (pf.encrypted) { Ref<FileAccessEncrypted> fae; fae.instantiate(); - ERR_FAIL_COND_MSG(fae.is_null(), "Can't open encrypted pack-referenced file '" + String(pf.pack) + "'."); + ERR_FAIL_COND_MSG(fae.is_null(), vformat("Can't open encrypted pack-referenced file '%s'.", String(pf.pack))); Vector<uint8_t> key; key.resize(32); @@ -405,7 +405,7 @@ FileAccessPack::FileAccessPack(const String &p_path, const PackedData::PackedFil } Error err = fae->open_and_parse(f, key, FileAccessEncrypted::MODE_READ, false); - ERR_FAIL_COND_MSG(err, "Can't open encrypted pack-referenced file '" + String(pf.pack) + "'."); + ERR_FAIL_COND_MSG(err, vformat("Can't open encrypted pack-referenced file '%s'.", String(pf.pack))); f = fae; off = 0; } diff --git a/core/io/file_access_zip.cpp b/core/io/file_access_zip.cpp index 38f86bd04d..71ce18145a 100644 --- a/core/io/file_access_zip.cpp +++ b/core/io/file_access_zip.cpp @@ -118,7 +118,7 @@ void ZipArchive::close_handle(unzFile p_file) const { } unzFile ZipArchive::get_file_handle(const String &p_file) const { - ERR_FAIL_COND_V_MSG(!file_exists(p_file), nullptr, "File '" + p_file + " doesn't exist."); + ERR_FAIL_COND_V_MSG(!file_exists(p_file), nullptr, vformat("File '%s' doesn't exist.", p_file)); File file = files[p_file]; zlib_filefunc_def io; @@ -138,7 +138,7 @@ unzFile ZipArchive::get_file_handle(const String &p_file) const { io.free_mem = godot_free; unzFile pkg = unzOpen2(packages[file.package].filename.utf8().get_data(), &io); - ERR_FAIL_NULL_V_MSG(pkg, nullptr, "Cannot open file '" + packages[file.package].filename + "'."); + ERR_FAIL_NULL_V_MSG(pkg, nullptr, vformat("Cannot open file '%s'.", packages[file.package].filename)); int unz_err = unzGoToFilePos(pkg, &file.file_pos); if (unz_err != UNZ_OK || unzOpenCurrentFile(pkg) != UNZ_OK) { unzClose(pkg); diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp index 323990ef7e..9d2adb2fcf 100644 --- a/core/io/http_client.cpp +++ b/core/io/http_client.cpp @@ -102,9 +102,9 @@ String HTTPClient::query_string_from_dict(const Dictionary &p_dict) { Error HTTPClient::verify_headers(const Vector<String> &p_headers) { for (int i = 0; i < p_headers.size(); i++) { String sanitized = p_headers[i].strip_edges(); - ERR_FAIL_COND_V_MSG(sanitized.is_empty(), ERR_INVALID_PARAMETER, "Invalid HTTP header at index " + itos(i) + ": empty."); + ERR_FAIL_COND_V_MSG(sanitized.is_empty(), ERR_INVALID_PARAMETER, vformat("Invalid HTTP header at index %d: empty.", i)); ERR_FAIL_COND_V_MSG(sanitized.find(":") < 1, ERR_INVALID_PARAMETER, - "Invalid HTTP header at index " + itos(i) + ": String must contain header-value pair, delimited by ':', but was: " + p_headers[i]); + vformat("Invalid HTTP header at index %d: String must contain header-value pair, delimited by ':', but was: '%s'.", i, p_headers[i])); } return OK; diff --git a/core/io/image.cpp b/core/io/image.cpp index 40f1499f77..613e740dd6 100644 --- a/core/io/image.cpp +++ b/core/io/image.cpp @@ -537,7 +537,7 @@ static bool _are_formats_compatible(Image::Format p_format0, Image::Format p_for } void Image::convert(Format p_new_format) { - ERR_FAIL_INDEX_MSG(p_new_format, FORMAT_MAX, "The Image format specified (" + itos(p_new_format) + ") is out of range. See Image's Format enum."); + ERR_FAIL_INDEX_MSG(p_new_format, FORMAT_MAX, vformat("The Image format specified (%d) is out of range. See Image's Format enum.", p_new_format)); if (data.size() == 0) { return; } @@ -1134,9 +1134,9 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) { ERR_FAIL_COND_MSG(p_width <= 0, "Image width must be greater than 0."); ERR_FAIL_COND_MSG(p_height <= 0, "Image height must be greater than 0."); - ERR_FAIL_COND_MSG(p_width > MAX_WIDTH, "Image width cannot be greater than " + itos(MAX_WIDTH) + "."); - ERR_FAIL_COND_MSG(p_height > MAX_HEIGHT, "Image height cannot be greater than " + itos(MAX_HEIGHT) + "."); - ERR_FAIL_COND_MSG(p_width * p_height > MAX_PIXELS, "Too many pixels for image, maximum is " + itos(MAX_PIXELS)); + ERR_FAIL_COND_MSG(p_width > MAX_WIDTH, vformat("Image width cannot be greater than %d pixels.", MAX_WIDTH)); + ERR_FAIL_COND_MSG(p_height > MAX_HEIGHT, vformat("Image height cannot be greater than %d pixels.", MAX_HEIGHT)); + ERR_FAIL_COND_MSG(p_width * p_height > MAX_PIXELS, vformat("Too many pixels for image, maximum is %d pixels.", MAX_PIXELS)); if (p_width == width && p_height == height) { return; @@ -1437,8 +1437,8 @@ void Image::crop_from_point(int p_x, int p_y, int p_width, int p_height) { ERR_FAIL_COND_MSG(p_y < 0, "Start y position cannot be smaller than 0."); ERR_FAIL_COND_MSG(p_width <= 0, "Width of image must be greater than 0."); ERR_FAIL_COND_MSG(p_height <= 0, "Height of image must be greater than 0."); - ERR_FAIL_COND_MSG(p_x + p_width > MAX_WIDTH, "End x position cannot be greater than " + itos(MAX_WIDTH) + "."); - ERR_FAIL_COND_MSG(p_y + p_height > MAX_HEIGHT, "End y position cannot be greater than " + itos(MAX_HEIGHT) + "."); + ERR_FAIL_COND_MSG(p_x + p_width > MAX_WIDTH, vformat("End x position cannot be greater than %d.", MAX_WIDTH)); + ERR_FAIL_COND_MSG(p_y + p_height > MAX_HEIGHT, vformat("End y position cannot be greater than %d.", MAX_HEIGHT)); /* to save memory, cropping should be done in-place, however, since this function will most likely either not be used much, or in critical areas, for now it won't, because @@ -1486,8 +1486,8 @@ void Image::crop(int p_width, int p_height) { void Image::rotate_90(ClockDirection p_direction) { ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot rotate in compressed or custom image formats."); - ERR_FAIL_COND_MSG(width <= 0, "The Image width specified (" + itos(width) + " pixels) must be greater than 0 pixels."); - ERR_FAIL_COND_MSG(height <= 0, "The Image height specified (" + itos(height) + " pixels) must be greater than 0 pixels."); + ERR_FAIL_COND_MSG(width <= 0, vformat("The Image width specified (%d pixels) must be greater than 0 pixels.", width)); + ERR_FAIL_COND_MSG(height <= 0, vformat("The Image height specified (%d pixels) must be greater than 0 pixels.", height)); bool used_mipmaps = has_mipmaps(); if (used_mipmaps) { @@ -1604,8 +1604,8 @@ void Image::rotate_90(ClockDirection p_direction) { void Image::rotate_180() { ERR_FAIL_COND_MSG(!_can_modify(format), "Cannot rotate in compressed or custom image formats."); - ERR_FAIL_COND_MSG(width <= 0, "The Image width specified (" + itos(width) + " pixels) must be greater than 0 pixels."); - ERR_FAIL_COND_MSG(height <= 0, "The Image height specified (" + itos(height) + " pixels) must be greater than 0 pixels."); + ERR_FAIL_COND_MSG(width <= 0, vformat("The Image width specified (%d pixels) must be greater than 0 pixels.", width)); + ERR_FAIL_COND_MSG(height <= 0, vformat("The Image height specified (%d pixels) must be greater than 0 pixels.", height)); bool used_mipmaps = has_mipmaps(); if (used_mipmaps) { @@ -2251,15 +2251,15 @@ void Image::set_data(int p_width, int p_height, bool p_use_mipmaps, Format p_for } void Image::initialize_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format) { - ERR_FAIL_COND_MSG(p_width <= 0, "The Image width specified (" + itos(p_width) + " pixels) must be greater than 0 pixels."); - ERR_FAIL_COND_MSG(p_height <= 0, "The Image height specified (" + itos(p_height) + " pixels) must be greater than 0 pixels."); + ERR_FAIL_COND_MSG(p_width <= 0, vformat("The Image width specified (%d pixels) must be greater than 0 pixels.", p_width)); + ERR_FAIL_COND_MSG(p_height <= 0, vformat("The Image height specified (%d pixels) must be greater than 0 pixels.", p_height)); ERR_FAIL_COND_MSG(p_width > MAX_WIDTH, - "The Image width specified (" + itos(p_width) + " pixels) cannot be greater than " + itos(MAX_WIDTH) + "pixels."); + vformat("The Image width specified (%d pixels) cannot be greater than %d pixels.", p_width, MAX_WIDTH)); ERR_FAIL_COND_MSG(p_height > MAX_HEIGHT, - "The Image height specified (" + itos(p_height) + " pixels) cannot be greater than " + itos(MAX_HEIGHT) + "pixels."); + vformat("The Image height specified (%d pixels) cannot be greater than %d pixels.", p_height, MAX_HEIGHT)); ERR_FAIL_COND_MSG(p_width * p_height > MAX_PIXELS, - "Too many pixels for Image. Maximum is " + itos(MAX_WIDTH) + "x" + itos(MAX_HEIGHT) + " = " + itos(MAX_PIXELS) + "pixels."); - ERR_FAIL_INDEX_MSG(p_format, FORMAT_MAX, "The Image format specified (" + itos(p_format) + ") is out of range. See Image's Format enum."); + vformat("Too many pixels for Image. Maximum is %dx%d = %d pixels.", MAX_WIDTH, MAX_HEIGHT, MAX_PIXELS)); + ERR_FAIL_INDEX_MSG(p_format, FORMAT_MAX, vformat("The Image format specified (%d) is out of range. See Image's Format enum.", p_format)); int mm = 0; int64_t size = _get_dst_image_size(p_width, p_height, p_format, mm, p_use_mipmaps ? -1 : 0); @@ -2277,15 +2277,15 @@ void Image::initialize_data(int p_width, int p_height, bool p_use_mipmaps, Forma } void Image::initialize_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const Vector<uint8_t> &p_data) { - ERR_FAIL_COND_MSG(p_width <= 0, "The Image width specified (" + itos(p_width) + " pixels) must be greater than 0 pixels."); - ERR_FAIL_COND_MSG(p_height <= 0, "The Image height specified (" + itos(p_height) + " pixels) must be greater than 0 pixels."); + ERR_FAIL_COND_MSG(p_width <= 0, vformat("The Image width specified (%d pixels) must be greater than 0 pixels.", p_width)); + ERR_FAIL_COND_MSG(p_height <= 0, vformat("The Image height specified (%d pixels) must be greater than 0 pixels.", p_height)); ERR_FAIL_COND_MSG(p_width > MAX_WIDTH, - "The Image width specified (" + itos(p_width) + " pixels) cannot be greater than " + itos(MAX_WIDTH) + " pixels."); + vformat("The Image width specified (%d pixels) cannot be greater than %d pixels.", p_width, MAX_WIDTH)); ERR_FAIL_COND_MSG(p_height > MAX_HEIGHT, - "The Image height specified (" + itos(p_height) + " pixels) cannot be greater than " + itos(MAX_HEIGHT) + " pixels."); + vformat("The Image height specified (%d pixels) cannot be greater than %d pixels.", p_height, MAX_HEIGHT)); ERR_FAIL_COND_MSG(p_width * p_height > MAX_PIXELS, - "Too many pixels for Image. Maximum is " + itos(MAX_WIDTH) + "x" + itos(MAX_HEIGHT) + " = " + itos(MAX_PIXELS) + "pixels ."); - ERR_FAIL_INDEX_MSG(p_format, FORMAT_MAX, "The Image format specified (" + itos(p_format) + ") is out of range. See Image's Format enum."); + vformat("Too many pixels for Image. Maximum is %dx%d = %d pixels.", MAX_WIDTH, MAX_HEIGHT, MAX_PIXELS)); + ERR_FAIL_INDEX_MSG(p_format, FORMAT_MAX, vformat("The Image format specified (%d) is out of range. See Image's Format enum.", p_format)); int mm; int64_t size = _get_dst_image_size(p_width, p_height, p_format, mm, p_use_mipmaps ? -1 : 0); @@ -2579,7 +2579,7 @@ Image::AlphaMode Image::detect_alpha() const { Error Image::load(const String &p_path) { #ifdef DEBUG_ENABLED if (p_path.begins_with("res://") && ResourceLoader::exists(p_path)) { - WARN_PRINT("Loaded resource as image file, this will not work on export: '" + p_path + "'. Instead, import the image file as an Image resource and load it normally as a resource."); + WARN_PRINT(vformat("Loaded resource as image file, this will not work on export: '%s'. Instead, import the image file as an Image resource and load it normally as a resource.", p_path)); } #endif return ImageLoader::load_image(p_path, this); @@ -2588,7 +2588,7 @@ Error Image::load(const String &p_path) { Ref<Image> Image::load_from_file(const String &p_path) { #ifdef DEBUG_ENABLED if (p_path.begins_with("res://") && ResourceLoader::exists(p_path)) { - WARN_PRINT("Loaded resource as image file, this will not work on export: '" + p_path + "'. Instead, import the image file as an Image resource and load it normally as a resource."); + WARN_PRINT(vformat("Loaded resource as image file, this will not work on export: '%s'. Instead, import the image file as an Image resource and load it normally as a resource.", p_path)); } #endif Ref<Image> image; @@ -2651,7 +2651,7 @@ Error Image::save_webp(const String &p_path, const bool p_lossy, const float p_q if (save_webp_func == nullptr) { return ERR_UNAVAILABLE; } - ERR_FAIL_COND_V_MSG(p_lossy && !(0.0f <= p_quality && p_quality <= 1.0f), ERR_INVALID_PARAMETER, "The WebP lossy quality was set to " + rtos(p_quality) + ", which is not valid. WebP lossy quality must be between 0.0 and 1.0 (inclusive)."); + ERR_FAIL_COND_V_MSG(p_lossy && !(0.0f <= p_quality && p_quality <= 1.0f), ERR_INVALID_PARAMETER, vformat("The WebP lossy quality was set to %f, which is not valid. WebP lossy quality must be between 0.0 and 1.0 (inclusive).", p_quality)); return save_webp_func(p_path, Ref<Image>((Image *)this), p_lossy, p_quality); } @@ -2660,7 +2660,7 @@ Vector<uint8_t> Image::save_webp_to_buffer(const bool p_lossy, const float p_qua if (save_webp_buffer_func == nullptr) { return Vector<uint8_t>(); } - ERR_FAIL_COND_V_MSG(p_lossy && !(0.0f <= p_quality && p_quality <= 1.0f), Vector<uint8_t>(), "The WebP lossy quality was set to " + rtos(p_quality) + ", which is not valid. WebP lossy quality must be between 0.0 and 1.0 (inclusive)."); + ERR_FAIL_COND_V_MSG(p_lossy && !(0.0f <= p_quality && p_quality <= 1.0f), Vector<uint8_t>(), vformat("The WebP lossy quality was set to %f, which is not valid. WebP lossy quality must be between 0.0 and 1.0 (inclusive).", p_quality)); return save_webp_buffer_func(Ref<Image>((Image *)this), p_lossy, p_quality); } diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp index 5724cd66a9..8e87569d7c 100644 --- a/core/io/image_loader.cpp +++ b/core/io/image_loader.cpp @@ -89,7 +89,7 @@ Error ImageLoader::load_image(const String &p_file, Ref<Image> p_image, Ref<File if (f.is_null()) { Error err; f = FileAccess::open(p_file, FileAccess::READ, &err); - ERR_FAIL_COND_V_MSG(f.is_null(), err, "Error opening file '" + p_file + "'."); + ERR_FAIL_COND_V_MSG(f.is_null(), err, vformat("Error opening file '%s'.", p_file)); } String extension = p_file.get_extension(); @@ -100,7 +100,7 @@ Error ImageLoader::load_image(const String &p_file, Ref<Image> p_image, Ref<File } Error err = loader.write[i]->load_image(p_image, f, p_flags, p_scale); if (err != OK) { - ERR_PRINT("Error loading image: " + p_file); + ERR_PRINT(vformat("Error loading image: '%s'.", p_file)); } if (err != ERR_FILE_UNRECOGNIZED) { diff --git a/core/io/ip.cpp b/core/io/ip.cpp index cf152cb41a..381436dc7a 100644 --- a/core/io/ip.cpp +++ b/core/io/ip.cpp @@ -203,7 +203,7 @@ IPAddress IP::get_resolve_item_address(ResolverID p_id) const { MutexLock lock(resolver->mutex); if (resolver->queue[p_id].status.get() != IP::RESOLVER_STATUS_DONE) { - ERR_PRINT("Resolve of '" + resolver->queue[p_id].hostname + "'' didn't complete yet."); + ERR_PRINT(vformat("Resolve of '%s' didn't complete yet.", resolver->queue[p_id].hostname)); return IPAddress(); } @@ -222,7 +222,7 @@ Array IP::get_resolve_item_addresses(ResolverID p_id) const { MutexLock lock(resolver->mutex); if (resolver->queue[p_id].status.get() != IP::RESOLVER_STATUS_DONE) { - ERR_PRINT("Resolve of '" + resolver->queue[p_id].hostname + "'' didn't complete yet."); + ERR_PRINT(vformat("Resolve of '%s' didn't complete yet.", resolver->queue[p_id].hostname)); return Array(); } diff --git a/core/io/json.cpp b/core/io/json.cpp index 0bbe79a0d1..989b292cbd 100644 --- a/core/io/json.cpp +++ b/core/io/json.cpp @@ -1404,7 +1404,7 @@ Error ResourceFormatSaverJSON::save(const Ref<Resource> &p_resource, const Strin Error err; Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::WRITE, &err); - ERR_FAIL_COND_V_MSG(err, err, "Cannot save json '" + p_path + "'."); + ERR_FAIL_COND_V_MSG(err, err, vformat("Cannot save json '%s'.", p_path)); file->store_string(source); if (file->get_error() != OK && file->get_error() != ERR_FILE_EOF) { diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp index 8d6334b4ab..d425af0afd 100644 --- a/core/io/marshalls.cpp +++ b/core/io/marshalls.cpp @@ -700,9 +700,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int if (str == "script" && value.get_type() != Variant::NIL) { ERR_FAIL_COND_V_MSG(value.get_type() != Variant::STRING, ERR_INVALID_DATA, "Invalid value for \"script\" property, expected script path as String."); String path = value; - ERR_FAIL_COND_V_MSG(path.is_empty() || !path.begins_with("res://") || !ResourceLoader::exists(path, "Script"), ERR_INVALID_DATA, "Invalid script path: '" + path + "'."); + ERR_FAIL_COND_V_MSG(path.is_empty() || !path.begins_with("res://") || !ResourceLoader::exists(path, "Script"), ERR_INVALID_DATA, vformat("Invalid script path: '%s'.", path)); Ref<Script> script = ResourceLoader::load(path, "Script"); - ERR_FAIL_COND_V_MSG(script.is_null(), ERR_INVALID_DATA, "Can't load script at path: '" + path + "'."); + ERR_FAIL_COND_V_MSG(script.is_null(), ERR_INVALID_DATA, vformat("Can't load script at path: '%s'.", path)); obj->set_script(script); } else { obj->set(str, value); @@ -822,9 +822,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int builtin_type = Variant::OBJECT; if (p_allow_objects) { - ERR_FAIL_COND_V_MSG(path.is_empty() || !path.begins_with("res://") || !ResourceLoader::exists(path, "Script"), ERR_INVALID_DATA, "Invalid script path: '" + path + "'."); + ERR_FAIL_COND_V_MSG(path.is_empty() || !path.begins_with("res://") || !ResourceLoader::exists(path, "Script"), ERR_INVALID_DATA, vformat("Invalid script path: '%s'.", path)); script = ResourceLoader::load(path, "Script"); - ERR_FAIL_COND_V_MSG(script.is_null(), ERR_INVALID_DATA, "Can't load script at path: '" + path + "'."); + ERR_FAIL_COND_V_MSG(script.is_null(), ERR_INVALID_DATA, vformat("Can't load script at path: '%s'.", path)); class_name = script->get_instance_base_type(); } else { class_name = EncodedObjectAsID::get_class_static(); diff --git a/core/io/pck_packer.cpp b/core/io/pck_packer.cpp index 270f154887..9127d65abd 100644 --- a/core/io/pck_packer.cpp +++ b/core/io/pck_packer.cpp @@ -86,7 +86,7 @@ Error PCKPacker::pck_start(const String &p_pck_path, int p_alignment, const Stri enc_dir = p_encrypt_directory; file = FileAccess::open(p_pck_path, FileAccess::WRITE); - ERR_FAIL_COND_V_MSG(file.is_null(), ERR_CANT_CREATE, "Can't open file to write: " + String(p_pck_path) + "."); + ERR_FAIL_COND_V_MSG(file.is_null(), ERR_CANT_CREATE, vformat("Can't open file to write: '%s'.", String(p_pck_path))); alignment = p_alignment; diff --git a/core/io/plist.cpp b/core/io/plist.cpp index de3ab52644..9fb0b461f1 100644 --- a/core/io/plist.cpp +++ b/core/io/plist.cpp @@ -452,7 +452,7 @@ PList::PList() { PList::PList(const String &p_string) { String err_str; bool ok = load_string(p_string, err_str); - ERR_FAIL_COND_MSG(!ok, "PList: " + err_str); + ERR_FAIL_COND_MSG(!ok, vformat("PList: %s.", err_str)); } uint64_t PList::read_bplist_var_size_int(Ref<FileAccess> p_file, uint8_t p_size) { diff --git a/core/io/remote_filesystem_client.cpp b/core/io/remote_filesystem_client.cpp index ee44f19ec1..7985a59d43 100644 --- a/core/io/remote_filesystem_client.cpp +++ b/core/io/remote_filesystem_client.cpp @@ -98,7 +98,7 @@ Error RemoteFilesystemClient::_store_file(const String &p_path, const LocalVecto } Ref<FileAccess> f = FileAccess::open(full_path, FileAccess::WRITE); - ERR_FAIL_COND_V_MSG(f.is_null(), ERR_FILE_CANT_OPEN, "Unable to open file for writing to remote filesystem cache: " + p_path); + ERR_FAIL_COND_V_MSG(f.is_null(), ERR_FILE_CANT_OPEN, vformat("Unable to open file for writing to remote filesystem cache: '%s'.", p_path)); f->store_buffer(p_file.ptr(), p_file.size()); Error err = f->get_error(); if (err) { @@ -117,10 +117,10 @@ Error RemoteFilesystemClient::_store_cache_file(const Vector<FileCache> &p_cache String full_path = cache_path.path_join(FILES_CACHE_FILE); String base_file_dir = full_path.get_base_dir(); Error err = DirAccess::make_dir_recursive_absolute(base_file_dir); - ERR_FAIL_COND_V_MSG(err != OK && err != ERR_ALREADY_EXISTS, err, "Unable to create base directory to store cache file: " + base_file_dir); + ERR_FAIL_COND_V_MSG(err != OK && err != ERR_ALREADY_EXISTS, err, vformat("Unable to create base directory to store cache file: '%s'.", base_file_dir)); Ref<FileAccess> f = FileAccess::open(full_path, FileAccess::WRITE); - ERR_FAIL_COND_V_MSG(f.is_null(), ERR_FILE_CANT_OPEN, "Unable to open the remote cache file for writing: " + full_path); + ERR_FAIL_COND_V_MSG(f.is_null(), ERR_FILE_CANT_OPEN, vformat("Unable to open the remote cache file for writing: '%s'.", full_path)); f->store_line(itos(FILESYSTEM_CACHE_VERSION)); for (int i = 0; i < p_cache.size(); i++) { String l = p_cache[i].path + "::" + itos(p_cache[i].server_modified_time) + "::" + itos(p_cache[i].modified_time); @@ -153,10 +153,10 @@ Error RemoteFilesystemClient::_synchronize_with_server(const String &p_host, int tcp_client.instantiate(); IPAddress ip = p_host.is_valid_ip_address() ? IPAddress(p_host) : IP::get_singleton()->resolve_hostname(p_host); - ERR_FAIL_COND_V_MSG(!ip.is_valid(), ERR_INVALID_PARAMETER, "Unable to resolve remote filesystem server hostname: " + p_host); + ERR_FAIL_COND_V_MSG(!ip.is_valid(), ERR_INVALID_PARAMETER, vformat("Unable to resolve remote filesystem server hostname: '%s'.", p_host)); print_verbose(vformat("Remote Filesystem: Connecting to host %s, port %d.", ip, p_port)); Error err = tcp_client->connect_to_host(ip, p_port); - ERR_FAIL_COND_V_MSG(err != OK, err, "Unable to open connection to remote file server (" + String(p_host) + ", port " + itos(p_port) + ") failed."); + ERR_FAIL_COND_V_MSG(err != OK, err, vformat("Unable to open connection to remote file server (%s, port %d) failed.", String(p_host), p_port)); while (tcp_client->get_status() == StreamPeerTCP::STATUS_CONNECTING) { tcp_client->poll(); @@ -164,7 +164,7 @@ Error RemoteFilesystemClient::_synchronize_with_server(const String &p_host, int } if (tcp_client->get_status() != StreamPeerTCP::STATUS_CONNECTED) { - ERR_FAIL_V_MSG(ERR_CANT_CONNECT, "Connection to remote file server (" + String(p_host) + ", port " + itos(p_port) + ") failed."); + ERR_FAIL_V_MSG(ERR_CANT_CONNECT, vformat("Connection to remote file server (%s, port %d) failed.", String(p_host), p_port)); } // Connection OK, now send the current file state. @@ -283,7 +283,7 @@ Error RemoteFilesystemClient::_synchronize_with_server(const String &p_host, int err = tcp_client->get_data(file_buffer.ptr(), file_size); if (err != OK) { - ERR_PRINT("Error retrieving file from remote filesystem: " + file); + ERR_PRINT(vformat("Error retrieving file from remote filesystem: '%s'.", file)); server_disconnected = true; } diff --git a/core/io/resource.cpp b/core/io/resource.cpp index 1f2ebbbd50..5b2af556fe 100644 --- a/core/io/resource.cpp +++ b/core/io/resource.cpp @@ -78,7 +78,7 @@ void Resource::set_path(const String &p_path, bool p_take_over) { existing->path_cache = String(); ResourceCache::resources.erase(p_path); } else { - ERR_FAIL_MSG("Another resource is loaded from path '" + p_path + "' (possible cyclic resource inclusion)."); + ERR_FAIL_MSG(vformat("Another resource is loaded from path '%s' (possible cyclic resource inclusion).", p_path)); } } diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp index 7d5b305eb0..a714a065b5 100644 --- a/core/io/resource_format_binary.cpp +++ b/core/io/resource_format_binary.cpp @@ -413,7 +413,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { //always use internal cache for loading internal resources if (!internal_index_cache.has(path)) { - WARN_PRINT(String("Couldn't load resource (no cache): " + path).utf8().get_data()); + WARN_PRINT(vformat("Couldn't load resource (no cache): %s.", path)); r_v = Variant(); } else { r_v = internal_index_cache[path]; @@ -437,7 +437,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { Ref<Resource> res = ResourceLoader::load(path, exttype, cache_mode_for_external); if (res.is_null()) { - WARN_PRINT(String("Couldn't load resource: " + path).utf8().get_data()); + WARN_PRINT(vformat("Couldn't load resource: %s.", path)); } r_v = res; @@ -460,7 +460,7 @@ Error ResourceLoaderBinary::parse_variant(Variant &r_v) { ResourceLoader::notify_dependency_error(local_path, external_resources[erindex].path, external_resources[erindex].type); } else { error = ERR_FILE_MISSING_DEPENDENCIES; - ERR_FAIL_V_MSG(error, "Can't load dependency: " + external_resources[erindex].path + "."); + ERR_FAIL_V_MSG(error, vformat("Can't load dependency: '%s'.", external_resources[erindex].path)); } } } else { @@ -706,7 +706,7 @@ Error ResourceLoaderBinary::load() { ResourceLoader::notify_dependency_error(local_path, path, external_resources[i].type); } else { error = ERR_FILE_MISSING_DEPENDENCIES; - ERR_FAIL_V_MSG(error, "Can't load dependency: " + path + "."); + ERR_FAIL_V_MSG(error, vformat("Can't load dependency: '%s'.", path)); } } } @@ -782,7 +782,7 @@ Error ResourceLoaderBinary::load() { obj = missing_resource; } else { error = ERR_FILE_CORRUPT; - ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource of unrecognized type in file: " + t + "."); + ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, vformat("'%s': Resource of unrecognized type in file: '%s'.", local_path, t)); } } @@ -791,7 +791,7 @@ Error ResourceLoaderBinary::load() { String obj_class = obj->get_class(); error = ERR_FILE_CORRUPT; memdelete(obj); //bye - ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, local_path + ":Resource type in resource field not a resource, type is: " + obj_class + "."); + ERR_FAIL_V_MSG(ERR_FILE_CORRUPT, vformat("'%s': Resource type in resource field not a resource, type is: %s.", local_path, obj_class)); } res = Ref<Resource>(r); @@ -1001,7 +1001,7 @@ void ResourceLoaderBinary::open(Ref<FileAccess> p_f, bool p_no_resources, bool p error = fac->open_after_magic(f); if (error != OK) { f.unref(); - ERR_FAIL_MSG("Failed to open binary resource file: " + local_path + "."); + ERR_FAIL_MSG(vformat("Failed to open binary resource file: '%s'.", local_path)); } f = fac; @@ -1009,7 +1009,7 @@ void ResourceLoaderBinary::open(Ref<FileAccess> p_f, bool p_no_resources, bool p // Not normal. error = ERR_FILE_UNRECOGNIZED; f.unref(); - ERR_FAIL_MSG("Unrecognized binary resource file: " + local_path + "."); + ERR_FAIL_MSG(vformat("Unrecognized binary resource file: '%s'.", local_path)); } bool big_endian = f->get_32(); @@ -1095,10 +1095,10 @@ void ResourceLoaderBinary::open(Ref<FileAccess> p_f, bool p_no_resources, bool p #ifdef TOOLS_ENABLED // Silence a warning that can happen during the initial filesystem scan due to cache being regenerated. if (ResourceLoader::get_resource_uid(res_path) != er.uid) { - WARN_PRINT(String(res_path + ": In external resource #" + itos(i) + ", invalid UID: " + ResourceUID::get_singleton()->id_to_text(er.uid) + " - using text path instead: " + er.path).utf8().get_data()); + WARN_PRINT(vformat("'%s': In external resource #%d, invalid UID: '%s' - using text path instead: '%s'.", res_path, i, ResourceUID::get_singleton()->id_to_text(er.uid), er.path)); } #else - WARN_PRINT(String(res_path + ": In external resource #" + itos(i) + ", invalid UID: " + ResourceUID::get_singleton()->id_to_text(er.uid) + " - using text path instead: " + er.path).utf8().get_data()); + WARN_PRINT(vformat("'%s': In external resource #%d, invalid UID: '%s' - using text path instead: '%s'.", res_path, i, ResourceUID::get_singleton()->id_to_text(er.uid), er.path)); #endif } } @@ -1122,7 +1122,7 @@ void ResourceLoaderBinary::open(Ref<FileAccess> p_f, bool p_no_resources, bool p if (f->eof_reached()) { error = ERR_FILE_CORRUPT; f.unref(); - ERR_FAIL_MSG("Premature end of file (EOF): " + local_path + "."); + ERR_FAIL_MSG(vformat("Premature end of file (EOF): '%s'.", local_path)); } } @@ -1226,7 +1226,7 @@ Ref<Resource> ResourceFormatLoaderBinary::load(const String &p_path, const Strin Error err; Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ, &err); - ERR_FAIL_COND_V_MSG(err != OK, Ref<Resource>(), "Cannot open file '" + p_path + "'."); + ERR_FAIL_COND_V_MSG(err != OK, Ref<Resource>(), vformat("Cannot open file '%s'.", p_path)); ResourceLoaderBinary loader; switch (p_cache_mode) { @@ -1303,7 +1303,7 @@ bool ResourceFormatLoaderBinary::handles_type(const String &p_type) const { void ResourceFormatLoaderBinary::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) { Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ); - ERR_FAIL_COND_MSG(f.is_null(), "Cannot open file '" + p_path + "'."); + ERR_FAIL_COND_MSG(f.is_null(), vformat("Cannot open file '%s'.", p_path)); ResourceLoaderBinary loader; loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path); @@ -1313,7 +1313,7 @@ void ResourceFormatLoaderBinary::get_dependencies(const String &p_path, List<Str Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, const HashMap<String, String> &p_map) { Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ); - ERR_FAIL_COND_V_MSG(f.is_null(), ERR_CANT_OPEN, "Cannot open file '" + p_path + "'."); + ERR_FAIL_COND_V_MSG(f.is_null(), ERR_CANT_OPEN, vformat("Cannot open file '%s'.", p_path)); Ref<FileAccess> fw; @@ -1326,23 +1326,23 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons Ref<FileAccessCompressed> fac; fac.instantiate(); Error err = fac->open_after_magic(f); - ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot open file '" + p_path + "'."); + ERR_FAIL_COND_V_MSG(err != OK, err, vformat("Cannot open file '%s'.", p_path)); f = fac; Ref<FileAccessCompressed> facw; facw.instantiate(); facw->configure("RSCC"); err = facw->open_internal(p_path + ".depren", FileAccess::WRITE); - ERR_FAIL_COND_V_MSG(err, ERR_FILE_CORRUPT, "Cannot create file '" + p_path + ".depren'."); + ERR_FAIL_COND_V_MSG(err, ERR_FILE_CORRUPT, vformat("Cannot create file '%s.depren'.", p_path)); fw = facw; } else if (header[0] != 'R' || header[1] != 'S' || header[2] != 'R' || header[3] != 'C') { // Not normal. - ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, "Unrecognized binary resource file '" + local_path + "'."); + ERR_FAIL_V_MSG(ERR_FILE_UNRECOGNIZED, vformat("Unrecognized binary resource file '%s'.", local_path)); } else { fw = FileAccess::open(p_path + ".depren", FileAccess::WRITE); - ERR_FAIL_COND_V_MSG(fw.is_null(), ERR_CANT_CREATE, "Cannot create file '" + p_path + ".depren'."); + ERR_FAIL_COND_V_MSG(fw.is_null(), ERR_CANT_CREATE, vformat("Cannot create file '%s.depren'.", p_path)); uint8_t magic[4] = { 'R', 'S', 'R', 'C' }; fw->store_buffer(magic, 4); @@ -1374,12 +1374,12 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons // Use the old approach. - WARN_PRINT("This file is old, so it can't refactor dependencies, opening and resaving '" + p_path + "'."); + WARN_PRINT(vformat("This file is old, so it can't refactor dependencies, opening and resaving '%s'.", p_path)); Error err; f = FileAccess::open(p_path, FileAccess::READ, &err); - ERR_FAIL_COND_V_MSG(err != OK, ERR_FILE_CANT_OPEN, "Cannot open file '" + p_path + "'."); + ERR_FAIL_COND_V_MSG(err != OK, ERR_FILE_CANT_OPEN, vformat("Cannot open file '%s'.", p_path)); ResourceLoaderBinary loader; loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path); @@ -1525,7 +1525,7 @@ Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path, cons void ResourceFormatLoaderBinary::get_classes_used(const String &p_path, HashSet<StringName> *r_classes) { Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ); - ERR_FAIL_COND_MSG(f.is_null(), "Cannot open file '" + p_path + "'."); + ERR_FAIL_COND_MSG(f.is_null(), vformat("Cannot open file '%s'.", p_path)); ResourceLoaderBinary loader; loader.local_path = ProjectSettings::get_singleton()->localize_path(p_path); @@ -2029,7 +2029,7 @@ void ResourceFormatSaverBinaryInstance::_find_resources(const Variant &p_variant if (!p_main && (!bundle_resources) && !res->is_built_in()) { if (res->get_path() == path) { - ERR_PRINT("Circular reference to resource being saved found: '" + local_path + "' will be null next time it's loaded."); + ERR_PRINT(vformat("Circular reference to resource being saved found: '%s' will be null next time it's loaded.", local_path)); return; } int idx = external_resources.size(); @@ -2155,7 +2155,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const Ref<Re f = FileAccess::open(p_path, FileAccess::WRITE, &err); } - ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot create file '" + p_path + "'."); + ERR_FAIL_COND_V_MSG(err != OK, err, vformat("Cannot create file '%s'.", p_path)); relative_paths = p_flags & ResourceSaver::FLAG_RELATIVE_PATHS; skip_editor = p_flags & ResourceSaver::FLAG_OMIT_EDITOR_PROPERTIES; @@ -2386,7 +2386,7 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path, const Ref<Re Error ResourceFormatSaverBinaryInstance::set_uid(const String &p_path, ResourceUID::ID p_uid) { Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ); - ERR_FAIL_COND_V_MSG(f.is_null(), ERR_CANT_OPEN, "Cannot open file '" + p_path + "'."); + ERR_FAIL_COND_V_MSG(f.is_null(), ERR_CANT_OPEN, vformat("Cannot open file '%s'.", p_path)); Ref<FileAccess> fw; @@ -2399,14 +2399,14 @@ Error ResourceFormatSaverBinaryInstance::set_uid(const String &p_path, ResourceU Ref<FileAccessCompressed> fac; fac.instantiate(); Error err = fac->open_after_magic(f); - ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot open file '" + p_path + "'."); + ERR_FAIL_COND_V_MSG(err != OK, err, vformat("Cannot open file '%s'.", p_path)); f = fac; Ref<FileAccessCompressed> facw; facw.instantiate(); facw->configure("RSCC"); err = facw->open_internal(p_path + ".uidren", FileAccess::WRITE); - ERR_FAIL_COND_V_MSG(err, ERR_FILE_CORRUPT, "Cannot create file '" + p_path + ".uidren'."); + ERR_FAIL_COND_V_MSG(err, ERR_FILE_CORRUPT, vformat("Cannot create file '%s.uidren'.", p_path)); fw = facw; @@ -2415,7 +2415,7 @@ Error ResourceFormatSaverBinaryInstance::set_uid(const String &p_path, ResourceU return ERR_FILE_UNRECOGNIZED; } else { fw = FileAccess::open(p_path + ".uidren", FileAccess::WRITE); - ERR_FAIL_COND_V_MSG(fw.is_null(), ERR_CANT_CREATE, "Cannot create file '" + p_path + ".uidren'."); + ERR_FAIL_COND_V_MSG(fw.is_null(), ERR_CANT_CREATE, vformat("Cannot create file '%s.uidren'.", p_path)); uint8_t magich[4] = { 'R', 'S', 'R', 'C' }; fw->store_buffer(magich, 4); @@ -2446,7 +2446,7 @@ Error ResourceFormatSaverBinaryInstance::set_uid(const String &p_path, ResourceU // Use the old approach. - WARN_PRINT("This file is old, so it does not support UIDs, opening and resaving '" + p_path + "'."); + WARN_PRINT(vformat("This file is old, so it does not support UIDs, opening and resaving '%s'.", p_path)); return ERR_UNAVAILABLE; } diff --git a/core/io/resource_importer.cpp b/core/io/resource_importer.cpp index 1e481d3aaa..b72b19ae59 100644 --- a/core/io/resource_importer.cpp +++ b/core/io/resource_importer.cpp @@ -77,7 +77,7 @@ Error ResourceFormatImporter::_get_path_and_type(const String &p_path, PathAndTy if (err == ERR_FILE_EOF) { return OK; } else if (err != OK) { - ERR_PRINT("ResourceFormatImporter::load - " + p_path + ".import:" + itos(lines) + " error: " + error_text); + ERR_PRINT(vformat("ResourceFormatImporter::load - %s.import:%d error: %s.", p_path, lines, error_text)); return err; } @@ -337,7 +337,7 @@ void ResourceFormatImporter::get_internal_resource_path_list(const String &p_pat if (err == ERR_FILE_EOF) { return; } else if (err != OK) { - ERR_PRINT("ResourceFormatImporter::get_internal_resource_path_list - " + p_path + ".import:" + itos(lines) + " error: " + error_text); + ERR_PRINT(vformat("ResourceFormatImporter::get_internal_resource_path_list - %s.import:%d error: %s.", p_path, lines, error_text)); return; } diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp index df12a0a3fd..97e6f6da06 100644 --- a/core/io/resource_loader.cpp +++ b/core/io/resource_loader.cpp @@ -164,7 +164,7 @@ Ref<Resource> ResourceFormatLoader::load(const String &p_path, const String &p_o } } - ERR_FAIL_V_MSG(Ref<Resource>(), "Failed to load resource '" + p_path + "'. ResourceFormatLoader::load was not implemented for this resource type."); + ERR_FAIL_V_MSG(Ref<Resource>(), vformat("Failed to load resource '%s'. ResourceFormatLoader::load was not implemented for this resource type.", p_path)); } void ResourceFormatLoader::get_dependencies(const String &p_path, List<String> *p_dependencies, bool p_add_types) { @@ -1165,7 +1165,7 @@ String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_rem // An extra remap may still be necessary afterwards due to the text -> binary converter on export. String locale = TranslationServer::get_singleton()->get_locale(); - ERR_FAIL_COND_V_MSG(locale.length() < 2, p_path, "Could not remap path '" + p_path + "' for translation as configured locale '" + locale + "' is invalid."); + ERR_FAIL_COND_V_MSG(locale.length() < 2, p_path, vformat("Could not remap path '%s' for translation as configured locale '%s' is invalid.", p_path, locale)); Vector<String> &res_remaps = *translation_remaps.getptr(new_path); @@ -1224,7 +1224,7 @@ String ResourceLoader::_path_remap(const String &p_path, bool *r_translation_rem if (err == ERR_FILE_EOF) { break; } else if (err != OK) { - ERR_PRINT("Parse error: " + p_path + ".remap:" + itos(lines) + " error: " + error_text + "."); + ERR_PRINT(vformat("Parse error: %s.remap:%d error: %s.", p_path, lines, error_text)); break; } diff --git a/core/io/resource_saver.cpp b/core/io/resource_saver.cpp index d6f00719f8..b0c551abd2 100644 --- a/core/io/resource_saver.cpp +++ b/core/io/resource_saver.cpp @@ -100,7 +100,7 @@ void ResourceFormatSaver::_bind_methods() { } Error ResourceSaver::save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags) { - ERR_FAIL_COND_V_MSG(p_resource.is_null(), ERR_INVALID_PARAMETER, "Can't save empty resource to path '" + p_path + "'."); + ERR_FAIL_COND_V_MSG(p_resource.is_null(), ERR_INVALID_PARAMETER, vformat("Can't save empty resource to path '%s'.", p_path)); String path = p_path; if (path.is_empty()) { path = p_resource->get_path(); diff --git a/core/io/translation_loader_po.cpp b/core/io/translation_loader_po.cpp index e7b2accf2b..54979a458c 100644 --- a/core/io/translation_loader_po.cpp +++ b/core/io/translation_loader_po.cpp @@ -171,14 +171,14 @@ Ref<Resource> TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_ // If we reached last line and it's not a content line, break, otherwise let processing that last loop if (is_eof && l.is_empty()) { if (status == STATUS_READING_ID || status == STATUS_READING_CONTEXT || (status == STATUS_READING_PLURAL && plural_index != plural_forms - 1)) { - ERR_FAIL_V_MSG(Ref<Resource>(), "Unexpected EOF while reading PO file at: " + path + ":" + itos(line)); + ERR_FAIL_V_MSG(Ref<Resource>(), vformat("Unexpected EOF while reading PO file at: %s:%d.", path, line)); } else { break; } } if (l.begins_with("msgctxt")) { - ERR_FAIL_COND_V_MSG(status != STATUS_READING_STRING && status != STATUS_READING_PLURAL, Ref<Resource>(), "Unexpected 'msgctxt', was expecting 'msgid_plural' or 'msgstr' before 'msgctxt' while parsing: " + path + ":" + itos(line)); + ERR_FAIL_COND_V_MSG(status != STATUS_READING_STRING && status != STATUS_READING_PLURAL, Ref<Resource>(), vformat("Unexpected 'msgctxt', was expecting 'msgid_plural' or 'msgstr' before 'msgctxt' while parsing: %s:%d.", path, line)); // In PO file, "msgctxt" appears before "msgid". If we encounter a "msgctxt", we add what we have read // and set "entered_context" to true to prevent adding twice. @@ -186,7 +186,7 @@ Ref<Resource> TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_ if (status == STATUS_READING_STRING) { translation->add_message(msg_id, msg_str, msg_context); } else if (status == STATUS_READING_PLURAL) { - ERR_FAIL_COND_V_MSG(plural_index != plural_forms - 1, Ref<Resource>(), "Number of 'msgstr[]' doesn't match with number of plural forms: " + path + ":" + itos(line)); + ERR_FAIL_COND_V_MSG(plural_index != plural_forms - 1, Ref<Resource>(), vformat("Number of 'msgstr[]' doesn't match with number of plural forms: %s:%d.", path, line)); translation->add_plural_message(msg_id, msgs_plural, msg_context); } } @@ -198,9 +198,9 @@ Ref<Resource> TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_ if (l.begins_with("msgid_plural")) { if (plural_forms == 0) { - ERR_FAIL_V_MSG(Ref<Resource>(), "PO file uses 'msgid_plural' but 'Plural-Forms' is invalid or missing in header: " + path + ":" + itos(line)); + ERR_FAIL_V_MSG(Ref<Resource>(), vformat("PO file uses 'msgid_plural' but 'Plural-Forms' is invalid or missing in header: %s:%d.", path, line)); } else if (status != STATUS_READING_ID) { - ERR_FAIL_V_MSG(Ref<Resource>(), "Unexpected 'msgid_plural', was expecting 'msgid' before 'msgid_plural' while parsing: " + path + ":" + itos(line)); + ERR_FAIL_V_MSG(Ref<Resource>(), vformat("Unexpected 'msgid_plural', was expecting 'msgid' before 'msgid_plural' while parsing: %s:%d.", path, line)); } // We don't record the message in "msgid_plural" itself as tr_n(), TTRN(), RTRN() interfaces provide the plural string already. // We just have to reset variables related to plurals for "msgstr[]" later on. @@ -210,14 +210,14 @@ Ref<Resource> TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_ msgs_plural.resize(plural_forms); status = STATUS_READING_PLURAL; } else if (l.begins_with("msgid")) { - ERR_FAIL_COND_V_MSG(status == STATUS_READING_ID, Ref<Resource>(), "Unexpected 'msgid', was expecting 'msgstr' while parsing: " + path + ":" + itos(line)); + ERR_FAIL_COND_V_MSG(status == STATUS_READING_ID, Ref<Resource>(), vformat("Unexpected 'msgid', was expecting 'msgstr' while parsing: %s:%d.", path, line)); if (!msg_id.is_empty()) { if (!skip_this && !entered_context) { if (status == STATUS_READING_STRING) { translation->add_message(msg_id, msg_str, msg_context); } else if (status == STATUS_READING_PLURAL) { - ERR_FAIL_COND_V_MSG(plural_index != plural_forms - 1, Ref<Resource>(), "Number of 'msgstr[]' doesn't match with number of plural forms: " + path + ":" + itos(line)); + ERR_FAIL_COND_V_MSG(plural_index != plural_forms - 1, Ref<Resource>(), vformat("Number of 'msgstr[]' doesn't match with number of plural forms: %s:%d.", path, line)); translation->add_plural_message(msg_id, msgs_plural, msg_context); } } @@ -246,11 +246,11 @@ Ref<Resource> TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_ } if (l.begins_with("msgstr[")) { - ERR_FAIL_COND_V_MSG(status != STATUS_READING_PLURAL, Ref<Resource>(), "Unexpected 'msgstr[]', was expecting 'msgid_plural' before 'msgstr[]' while parsing: " + path + ":" + itos(line)); + ERR_FAIL_COND_V_MSG(status != STATUS_READING_PLURAL, Ref<Resource>(), vformat("Unexpected 'msgstr[]', was expecting 'msgid_plural' before 'msgstr[]' while parsing: %s:%d.", path, line)); plural_index++; // Increment to add to the next slot in vector msgs_plural. l = l.substr(9, l.length()).strip_edges(); } else if (l.begins_with("msgstr")) { - ERR_FAIL_COND_V_MSG(status != STATUS_READING_ID, Ref<Resource>(), "Unexpected 'msgstr', was expecting 'msgid' before 'msgstr' while parsing: " + path + ":" + itos(line)); + ERR_FAIL_COND_V_MSG(status != STATUS_READING_ID, Ref<Resource>(), vformat("Unexpected 'msgstr', was expecting 'msgid' before 'msgstr' while parsing: %s:%d.", path, line)); l = l.substr(6, l.length()).strip_edges(); status = STATUS_READING_STRING; } @@ -263,7 +263,7 @@ Ref<Resource> TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_ continue; // Nothing to read or comment. } - ERR_FAIL_COND_V_MSG(!l.begins_with("\"") || status == STATUS_NONE, Ref<Resource>(), "Invalid line '" + l + "' while parsing: " + path + ":" + itos(line)); + ERR_FAIL_COND_V_MSG(!l.begins_with("\"") || status == STATUS_NONE, Ref<Resource>(), vformat("Invalid line '%s' while parsing: %s:%d.", l, path, line)); l = l.substr(1, l.length()); // Find final quote, ignoring escaped ones (\"). @@ -285,7 +285,7 @@ Ref<Resource> TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_ escape_next = false; } - ERR_FAIL_COND_V_MSG(end_pos == -1, Ref<Resource>(), "Expected '\"' at end of message while parsing: " + path + ":" + itos(line)); + ERR_FAIL_COND_V_MSG(end_pos == -1, Ref<Resource>(), vformat("Expected '\"' at end of message while parsing: %s:%d.", path, line)); l = l.substr(0, end_pos); l = l.c_unescape(); @@ -297,7 +297,7 @@ Ref<Resource> TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_ } else if (status == STATUS_READING_CONTEXT) { msg_context += l; } else if (status == STATUS_READING_PLURAL && plural_index >= 0) { - ERR_FAIL_COND_V_MSG(plural_index >= plural_forms, Ref<Resource>(), "Unexpected plural form while parsing: " + path + ":" + itos(line)); + ERR_FAIL_COND_V_MSG(plural_index >= plural_forms, Ref<Resource>(), vformat("Unexpected plural form while parsing: %s:%d.", path, line)); msgs_plural.write[plural_index] = msgs_plural[plural_index] + l; } @@ -315,13 +315,13 @@ Ref<Resource> TranslationLoaderPO::load_translation(Ref<FileAccess> f, Error *r_ } } else if (status == STATUS_READING_PLURAL) { if (!skip_this && !msg_id.is_empty()) { - ERR_FAIL_COND_V_MSG(plural_index != plural_forms - 1, Ref<Resource>(), "Number of 'msgstr[]' doesn't match with number of plural forms: " + path + ":" + itos(line)); + ERR_FAIL_COND_V_MSG(plural_index != plural_forms - 1, Ref<Resource>(), vformat("Number of 'msgstr[]' doesn't match with number of plural forms: %s:%d.", path, line)); translation->add_plural_message(msg_id, msgs_plural, msg_context); } } } - ERR_FAIL_COND_V_MSG(config.is_empty(), Ref<Resource>(), "No config found in file: " + path + "."); + ERR_FAIL_COND_V_MSG(config.is_empty(), Ref<Resource>(), vformat("No config found in file: '%s'.", path)); Vector<String> configs = config.split("\n"); for (int i = 0; i < configs.size(); i++) { @@ -351,7 +351,7 @@ Ref<Resource> TranslationLoaderPO::load(const String &p_path, const String &p_or } Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ); - ERR_FAIL_COND_V_MSG(f.is_null(), Ref<Resource>(), "Cannot open file '" + p_path + "'."); + ERR_FAIL_COND_V_MSG(f.is_null(), Ref<Resource>(), vformat("Cannot open file '%s'.", p_path)); return load_translation(f, r_error); } diff --git a/core/io/xml_parser.cpp b/core/io/xml_parser.cpp index 69cb8d9f64..8021aa303e 100644 --- a/core/io/xml_parser.cpp +++ b/core/io/xml_parser.cpp @@ -431,7 +431,7 @@ String XMLParser::get_named_attribute_value(const String &p_name) const { } } - ERR_FAIL_COND_V_MSG(idx < 0, "", "Attribute not found: " + p_name + "."); + ERR_FAIL_COND_V_MSG(idx < 0, "", vformat("Attribute not found: '%s'.", p_name)); return attributes[idx].value; } @@ -495,7 +495,7 @@ Error XMLParser::open(const String &p_path) { Error err; Ref<FileAccess> file = FileAccess::open(p_path, FileAccess::READ, &err); - ERR_FAIL_COND_V_MSG(err != OK, err, "Cannot open file '" + p_path + "'."); + ERR_FAIL_COND_V_MSG(err != OK, err, vformat("Cannot open file '%s'.", p_path)); length = file->get_length(); ERR_FAIL_COND_V(length < 1, ERR_FILE_CORRUPT); diff --git a/core/math/expression.cpp b/core/math/expression.cpp index 6b8205a726..5eb524efed 100644 --- a/core/math/expression.cpp +++ b/core/math/expression.cpp @@ -1493,7 +1493,7 @@ Error Expression::parse(const String &p_expression, const Vector<String> &p_inpu } Variant Expression::execute(const Array &p_inputs, Object *p_base, bool p_show_error, bool p_const_calls_only) { - ERR_FAIL_COND_V_MSG(error_set, Variant(), "There was previously a parse error: " + error_str + "."); + ERR_FAIL_COND_V_MSG(error_set, Variant(), vformat("There was previously a parse error: %s.", error_str)); execution_error = false; Variant output; diff --git a/core/math/rect2.cpp b/core/math/rect2.cpp index 20b5b05f5e..2b7bb9bc33 100644 --- a/core/math/rect2.cpp +++ b/core/math/rect2.cpp @@ -285,7 +285,7 @@ next4: } Rect2::operator String() const { - return "[P: " + position.operator String() + ", S: " + size + "]"; + return "[P: " + position.operator String() + ", S: " + size.operator String() + "]"; } Rect2::operator Rect2i() const { diff --git a/core/math/vector2.cpp b/core/math/vector2.cpp index 5ec9aeb9c2..b54e185b4d 100644 --- a/core/math/vector2.cpp +++ b/core/math/vector2.cpp @@ -205,7 +205,7 @@ bool Vector2::is_finite() const { } Vector2::operator String() const { - return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ")"; + return "(" + String::num_real(x, true) + ", " + String::num_real(y, true) + ")"; } Vector2::operator Vector2i() const { diff --git a/core/math/vector3.cpp b/core/math/vector3.cpp index e1794222ad..7560528bb9 100644 --- a/core/math/vector3.cpp +++ b/core/math/vector3.cpp @@ -167,7 +167,7 @@ bool Vector3::is_finite() const { } Vector3::operator String() const { - return "(" + String::num_real(x, false) + ", " + String::num_real(y, false) + ", " + String::num_real(z, false) + ")"; + return "(" + String::num_real(x, true) + ", " + String::num_real(y, true) + ", " + String::num_real(z, true) + ")"; } Vector3::operator Vector3i() const { diff --git a/core/object/class_db.cpp b/core/object/class_db.cpp index ca08ec0dcb..3ec1f6e7b4 100644 --- a/core/object/class_db.cpp +++ b/core/object/class_db.cpp @@ -354,7 +354,7 @@ StringName ClassDB::get_compatibility_remapped_class(const StringName &p_class) StringName ClassDB::_get_parent_class(const StringName &p_class) { ClassInfo *ti = classes.getptr(p_class); - ERR_FAIL_NULL_V_MSG(ti, StringName(), "Cannot get class '" + String(p_class) + "'."); + ERR_FAIL_NULL_V_MSG(ti, StringName(), vformat("Cannot get class '%s'.", String(p_class))); return ti->inherits; } @@ -369,7 +369,7 @@ ClassDB::APIType ClassDB::get_api_type(const StringName &p_class) { ClassInfo *ti = classes.getptr(p_class); - ERR_FAIL_NULL_V_MSG(ti, API_NONE, "Cannot get class '" + String(p_class) + "'."); + ERR_FAIL_NULL_V_MSG(ti, API_NONE, vformat("Cannot get class '%s'.", String(p_class))); return ti->api; } @@ -392,7 +392,7 @@ uint32_t ClassDB::get_api_hash(APIType p_api) { for (const StringName &E : class_list) { ClassInfo *t = classes.getptr(E); - ERR_FAIL_NULL_V_MSG(t, 0, "Cannot get class '" + String(E) + "'."); + ERR_FAIL_NULL_V_MSG(t, 0, vformat("Cannot get class '%s'.", String(E))); if (t->api != p_api || !t->exposed) { continue; } @@ -549,14 +549,14 @@ Object *ClassDB::_instantiate_internal(const StringName &p_class, bool p_require ti = classes.getptr(compat_classes[p_class]); } } - ERR_FAIL_NULL_V_MSG(ti, nullptr, "Cannot get class '" + String(p_class) + "'."); - ERR_FAIL_COND_V_MSG(ti->disabled, nullptr, "Class '" + String(p_class) + "' is disabled."); - ERR_FAIL_NULL_V_MSG(ti->creation_func, nullptr, "Class '" + String(p_class) + "' or its base class cannot be instantiated."); + ERR_FAIL_NULL_V_MSG(ti, nullptr, vformat("Cannot get class '%s'.", String(p_class))); + ERR_FAIL_COND_V_MSG(ti->disabled, nullptr, vformat("Class '%s' is disabled.", String(p_class))); + ERR_FAIL_NULL_V_MSG(ti->creation_func, nullptr, vformat("Class '%s' or its base class cannot be instantiated.", String(p_class))); } #ifdef TOOLS_ENABLED if ((ti->api == API_EDITOR || ti->api == API_EDITOR_EXTENSION) && !Engine::get_singleton()->is_editor_hint()) { - ERR_PRINT("Class '" + String(p_class) + "' can only be instantiated by editor."); + ERR_PRINT(vformat("Class '%s' can only be instantiated by editor.", String(p_class))); return nullptr; } #endif @@ -655,8 +655,8 @@ ObjectGDExtension *ClassDB::get_placeholder_extension(const StringName &p_class) ti = classes.getptr(compat_classes[p_class]); } } - ERR_FAIL_NULL_V_MSG(ti, nullptr, "Cannot get class '" + String(p_class) + "'."); - ERR_FAIL_COND_V_MSG(ti->disabled, nullptr, "Class '" + String(p_class) + "' is disabled."); + ERR_FAIL_NULL_V_MSG(ti, nullptr, vformat("Cannot get class '%s'.", String(p_class))); + ERR_FAIL_COND_V_MSG(ti->disabled, nullptr, vformat("Class '%s' is disabled.", String(p_class))); } // Make a "fake" extension to act as a placeholder. @@ -736,9 +736,9 @@ void ClassDB::set_object_extension_instance(Object *p_object, const StringName & ti = classes.getptr(compat_classes[p_class]); } } - ERR_FAIL_NULL_MSG(ti, "Cannot get class '" + String(p_class) + "'."); - ERR_FAIL_COND_MSG(ti->disabled, "Class '" + String(p_class) + "' is disabled."); - ERR_FAIL_NULL_MSG(ti->gdextension, "Class '" + String(p_class) + "' has no native extension."); + ERR_FAIL_NULL_MSG(ti, vformat("Cannot get class '%s'.", String(p_class))); + ERR_FAIL_COND_MSG(ti->disabled, vformat("Class '%s' is disabled.", String(p_class))); + ERR_FAIL_NULL_MSG(ti->gdextension, vformat("Class '%s' has no native extension.", String(p_class))); } p_object->_extension = ti->gdextension; @@ -757,7 +757,7 @@ bool ClassDB::can_instantiate(const StringName &p_class) { ClassInfo *ti = classes.getptr(p_class); if (!ti) { if (!ScriptServer::is_global_class(p_class)) { - ERR_FAIL_V_MSG(false, "Cannot get class '" + String(p_class) + "'."); + ERR_FAIL_V_MSG(false, vformat("Cannot get class '%s'.", String(p_class))); } String path = ScriptServer::get_global_class_path(p_class); Ref<Script> scr = ResourceLoader::load(path); @@ -777,7 +777,7 @@ bool ClassDB::is_abstract(const StringName &p_class) { ClassInfo *ti = classes.getptr(p_class); if (!ti) { if (!ScriptServer::is_global_class(p_class)) { - ERR_FAIL_V_MSG(false, "Cannot get class '" + String(p_class) + "'."); + ERR_FAIL_V_MSG(false, vformat("Cannot get class '%s'.", String(p_class))); } String path = ScriptServer::get_global_class_path(p_class); Ref<Script> scr = ResourceLoader::load(path); @@ -803,7 +803,7 @@ bool ClassDB::is_virtual(const StringName &p_class) { ClassInfo *ti = classes.getptr(p_class); if (!ti) { if (!ScriptServer::is_global_class(p_class)) { - ERR_FAIL_V_MSG(false, "Cannot get class '" + String(p_class) + "'."); + ERR_FAIL_V_MSG(false, vformat("Cannot get class '%s'.", String(p_class))); } String path = ScriptServer::get_global_class_path(p_class); Ref<Script> scr = ResourceLoader::load(path); @@ -822,7 +822,7 @@ void ClassDB::_add_class2(const StringName &p_class, const StringName &p_inherit const StringName &name = p_class; - ERR_FAIL_COND_MSG(classes.has(name), "Class '" + String(p_class) + "' already exists."); + ERR_FAIL_COND_MSG(classes.has(name), vformat("Class '%s' already exists.", String(p_class))); classes[name] = ClassInfo(); ClassInfo &ti = classes[name]; @@ -1330,7 +1330,7 @@ void ClassDB::add_signal(const StringName &p_class, const MethodInfo &p_signal) #ifdef DEBUG_METHODS_ENABLED ClassInfo *check = type; while (check) { - ERR_FAIL_COND_MSG(check->signal_map.has(sname), "Class '" + String(p_class) + "' already has signal '" + String(sname) + "'."); + ERR_FAIL_COND_MSG(check->signal_map.has(sname), vformat("Class '%s' already has signal '%s'.", String(p_class), String(sname))); check = check->inherits_ptr; } #endif @@ -1444,10 +1444,10 @@ void ClassDB::add_property(const StringName &p_class, const PropertyInfo &p_pinf mb_set = get_method(p_class, p_setter); #ifdef DEBUG_METHODS_ENABLED - ERR_FAIL_NULL_MSG(mb_set, "Invalid setter '" + p_class + "::" + p_setter + "' for property '" + p_pinfo.name + "'."); + ERR_FAIL_NULL_MSG(mb_set, vformat("Invalid setter '%s::%s' for property '%s'.", p_class, p_setter, p_pinfo.name)); int exp_args = 1 + (p_index >= 0 ? 1 : 0); - ERR_FAIL_COND_MSG(mb_set->get_argument_count() != exp_args, "Invalid function for setter '" + p_class + "::" + p_setter + " for property '" + p_pinfo.name + "'."); + ERR_FAIL_COND_MSG(mb_set->get_argument_count() != exp_args, vformat("Invalid function for setter '%s::%s' for property '%s'.", p_class, p_setter, p_pinfo.name)); #endif } @@ -1456,15 +1456,15 @@ void ClassDB::add_property(const StringName &p_class, const PropertyInfo &p_pinf mb_get = get_method(p_class, p_getter); #ifdef DEBUG_METHODS_ENABLED - ERR_FAIL_NULL_MSG(mb_get, "Invalid getter '" + p_class + "::" + p_getter + "' for property '" + p_pinfo.name + "'."); + ERR_FAIL_NULL_MSG(mb_get, vformat("Invalid getter '%s::%s' for property '%s'.", p_class, p_getter, p_pinfo.name)); int exp_args = 0 + (p_index >= 0 ? 1 : 0); - ERR_FAIL_COND_MSG(mb_get->get_argument_count() != exp_args, "Invalid function for getter '" + p_class + "::" + p_getter + "' for property: '" + p_pinfo.name + "'."); + ERR_FAIL_COND_MSG(mb_get->get_argument_count() != exp_args, vformat("Invalid function for getter '%s::%s' for property '%s'.", p_class, p_getter, p_pinfo.name)); #endif } #ifdef DEBUG_METHODS_ENABLED - ERR_FAIL_COND_MSG(type->property_setget.has(p_pinfo.name), "Object '" + p_class + "' already has property '" + p_pinfo.name + "'."); + ERR_FAIL_COND_MSG(type->property_setget.has(p_pinfo.name), vformat("Object '%s' already has property '%s'.", p_class, p_pinfo.name)); #endif OBJTYPE_WLOCK @@ -1849,7 +1849,7 @@ void ClassDB::_bind_method_custom(const StringName &p_class, MethodBind *p_metho ClassInfo *type = classes.getptr(p_class); if (!type) { - ERR_FAIL_MSG("Couldn't bind custom method '" + p_method->get_name() + "' for instance '" + p_class + "'."); + ERR_FAIL_MSG(vformat("Couldn't bind custom method '%s' for instance '%s'.", p_method->get_name(), p_class)); } if (p_compatibility) { @@ -1859,7 +1859,7 @@ void ClassDB::_bind_method_custom(const StringName &p_class, MethodBind *p_metho if (type->method_map.has(p_method->get_name())) { // overloading not supported - ERR_FAIL_MSG("Method already bound '" + p_class + "::" + p_method->get_name() + "'."); + ERR_FAIL_MSG(vformat("Method already bound '%s::%s'.", p_class, p_method->get_name())); } #ifdef DEBUG_METHODS_ENABLED @@ -1890,7 +1890,7 @@ MethodBind *ClassDB::_bind_vararg_method(MethodBind *p_bind, const StringName &p if (type->method_map.has(p_name)) { memdelete(bind); // Overloading not supported - ERR_FAIL_V_MSG(nullptr, "Method already bound: " + instance_type + "::" + p_name + "."); + ERR_FAIL_V_MSG(nullptr, vformat("Method already bound: '%s::%s'.", instance_type, p_name)); } type->method_map[p_name] = bind; #ifdef DEBUG_METHODS_ENABLED @@ -1918,26 +1918,26 @@ MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, bool p_ #ifdef DEBUG_ENABLED - ERR_FAIL_COND_V_MSG(!p_compatibility && has_method(instance_type, mdname), nullptr, "Class " + String(instance_type) + " already has a method " + String(mdname) + "."); + ERR_FAIL_COND_V_MSG(!p_compatibility && has_method(instance_type, mdname), nullptr, vformat("Class '%s' already has a method '%s'.", String(instance_type), String(mdname))); #endif ClassInfo *type = classes.getptr(instance_type); if (!type) { memdelete(p_bind); - ERR_FAIL_V_MSG(nullptr, "Couldn't bind method '" + mdname + "' for instance '" + instance_type + "'."); + ERR_FAIL_V_MSG(nullptr, vformat("Couldn't bind method '%s' for instance '%s'.", mdname, instance_type)); } if (!p_compatibility && type->method_map.has(mdname)) { memdelete(p_bind); // overloading not supported - ERR_FAIL_V_MSG(nullptr, "Method already bound '" + instance_type + "::" + mdname + "'."); + ERR_FAIL_V_MSG(nullptr, vformat("Method already bound '%s::%s'.", instance_type, mdname)); } #ifdef DEBUG_METHODS_ENABLED if (method_name.args.size() > p_bind->get_argument_count()) { memdelete(p_bind); - ERR_FAIL_V_MSG(nullptr, "Method definition provides more arguments than the method actually has '" + instance_type + "::" + mdname + "'."); + ERR_FAIL_V_MSG(nullptr, vformat("Method definition provides more arguments than the method actually has '%s::%s'.", instance_type, mdname)); } p_bind->set_argument_names(method_name.args); @@ -1966,7 +1966,7 @@ MethodBind *ClassDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind, bool p_ } void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual, const Vector<String> &p_arg_names, bool p_object_core) { - ERR_FAIL_COND_MSG(!classes.has(p_class), "Request for nonexistent class '" + p_class + "'."); + ERR_FAIL_COND_MSG(!classes.has(p_class), vformat("Request for nonexistent class '%s'.", p_class)); OBJTYPE_WLOCK; @@ -1981,7 +1981,7 @@ void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_ if (!p_object_core) { if (p_arg_names.size() != mi.arguments.size()) { - WARN_PRINT("Mismatch argument name count for virtual method: " + String(p_class) + "::" + p_method.name); + WARN_PRINT(vformat("Mismatch argument name count for virtual method: '%s::%s'.", String(p_class), p_method.name)); } else { List<PropertyInfo>::Iterator itr = mi.arguments.begin(); for (int i = 0; i < p_arg_names.size(); ++itr, ++i) { @@ -1992,7 +1992,7 @@ void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_ if (classes[p_class].virtual_methods_map.has(p_method.name)) { // overloading not supported - ERR_FAIL_MSG("Virtual method already bound '" + String(p_class) + "::" + p_method.name + "'."); + ERR_FAIL_MSG(vformat("Virtual method already bound '%s::%s'.", String(p_class), p_method.name)); } classes[p_class].virtual_methods.push_back(mi); classes[p_class].virtual_methods_map[p_method.name] = mi; @@ -2001,7 +2001,7 @@ void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_ } void ClassDB::get_virtual_methods(const StringName &p_class, List<MethodInfo> *p_methods, bool p_no_inheritance) { - ERR_FAIL_COND_MSG(!classes.has(p_class), "Request for nonexistent class '" + p_class + "'."); + ERR_FAIL_COND_MSG(!classes.has(p_class), vformat("Request for nonexistent class '%s'.", p_class)); #ifdef DEBUG_METHODS_ENABLED @@ -2022,7 +2022,7 @@ void ClassDB::get_virtual_methods(const StringName &p_class, List<MethodInfo> *p } void ClassDB::add_extension_class_virtual_method(const StringName &p_class, const GDExtensionClassVirtualMethodInfo *p_method_info) { - ERR_FAIL_COND_MSG(!classes.has(p_class), "Request for nonexistent class '" + p_class + "'."); + ERR_FAIL_COND_MSG(!classes.has(p_class), vformat("Request for nonexistent class '%s'.", p_class)); #ifdef DEBUG_METHODS_ENABLED PackedStringArray arg_names; @@ -2046,7 +2046,7 @@ void ClassDB::add_extension_class_virtual_method(const StringName &p_class, cons void ClassDB::set_class_enabled(const StringName &p_class, bool p_enable) { OBJTYPE_WLOCK; - ERR_FAIL_COND_MSG(!classes.has(p_class), "Request for nonexistent class '" + p_class + "'."); + ERR_FAIL_COND_MSG(!classes.has(p_class), vformat("Request for nonexistent class '%s'.", p_class)); classes[p_class].disabled = !p_enable; } @@ -2060,7 +2060,7 @@ bool ClassDB::is_class_enabled(const StringName &p_class) { } } - ERR_FAIL_NULL_V_MSG(ti, false, "Cannot get class '" + String(p_class) + "'."); + ERR_FAIL_NULL_V_MSG(ti, false, vformat("Cannot get class '%s'.", String(p_class))); return !ti->disabled; } @@ -2068,7 +2068,7 @@ bool ClassDB::is_class_exposed(const StringName &p_class) { OBJTYPE_RLOCK; ClassInfo *ti = classes.getptr(p_class); - ERR_FAIL_NULL_V_MSG(ti, false, "Cannot get class '" + String(p_class) + "'."); + ERR_FAIL_NULL_V_MSG(ti, false, vformat("Cannot get class '%s'.", String(p_class))); return ti->exposed; } @@ -2076,7 +2076,7 @@ bool ClassDB::is_class_reloadable(const StringName &p_class) { OBJTYPE_RLOCK; ClassInfo *ti = classes.getptr(p_class); - ERR_FAIL_NULL_V_MSG(ti, false, "Cannot get class '" + String(p_class) + "'."); + ERR_FAIL_NULL_V_MSG(ti, false, vformat("Cannot get class '%s'.", String(p_class))); return ti->reloadable; } @@ -2084,7 +2084,7 @@ bool ClassDB::is_class_runtime(const StringName &p_class) { OBJTYPE_RLOCK; ClassInfo *ti = classes.getptr(p_class); - ERR_FAIL_NULL_V_MSG(ti, false, "Cannot get class '" + String(p_class) + "'."); + ERR_FAIL_NULL_V_MSG(ti, false, vformat("Cannot get class '%s'.", String(p_class))); return ti->is_runtime; } @@ -2194,14 +2194,14 @@ Variant ClassDB::class_get_default_property_value(const StringName &p_class, con void ClassDB::register_extension_class(ObjectGDExtension *p_extension) { GLOBAL_LOCK_FUNCTION; - ERR_FAIL_COND_MSG(classes.has(p_extension->class_name), "Class already registered: " + String(p_extension->class_name)); - ERR_FAIL_COND_MSG(!classes.has(p_extension->parent_class_name), "Parent class name for extension class not found: " + String(p_extension->parent_class_name)); + ERR_FAIL_COND_MSG(classes.has(p_extension->class_name), vformat("Class already registered: '%s'.", String(p_extension->class_name))); + ERR_FAIL_COND_MSG(!classes.has(p_extension->parent_class_name), vformat("Parent class name for extension class not found: '%s'.", String(p_extension->parent_class_name))); ClassInfo *parent = classes.getptr(p_extension->parent_class_name); #ifdef TOOLS_ENABLED // @todo This is a limitation of the current implementation, but it should be possible to remove. - ERR_FAIL_COND_MSG(p_extension->is_runtime && parent->gdextension && !parent->is_runtime, "Extension runtime class " + String(p_extension->class_name) + " cannot descend from " + parent->name + " which isn't also a runtime class"); + ERR_FAIL_COND_MSG(p_extension->is_runtime && parent->gdextension && !parent->is_runtime, vformat("Extension runtime class '%s' cannot descend from '%s' which isn't also a runtime class.", String(p_extension->class_name), parent->name)); #endif ClassInfo c; @@ -2217,7 +2217,7 @@ void ClassDB::register_extension_class(ObjectGDExtension *p_extension) { concrete_ancestor->gdextension != nullptr) { concrete_ancestor = concrete_ancestor->inherits_ptr; } - ERR_FAIL_NULL_MSG(concrete_ancestor->creation_func, "Extension class " + String(p_extension->class_name) + " cannot extend native abstract class " + String(concrete_ancestor->name)); + ERR_FAIL_NULL_MSG(concrete_ancestor->creation_func, vformat("Extension class '%s' cannot extend native abstract class '%s'.", String(p_extension->class_name), String(concrete_ancestor->name))); c.creation_func = concrete_ancestor->creation_func; } c.inherits = parent->name; @@ -2241,7 +2241,7 @@ void ClassDB::register_extension_class(ObjectGDExtension *p_extension) { void ClassDB::unregister_extension_class(const StringName &p_class, bool p_free_method_binds) { ClassInfo *c = classes.getptr(p_class); - ERR_FAIL_NULL_MSG(c, "Class '" + String(p_class) + "' does not exist."); + ERR_FAIL_NULL_MSG(c, vformat("Class '%s' does not exist.", String(p_class))); if (p_free_method_binds) { for (KeyValue<StringName, MethodBind *> &F : c->method_map) { memdelete(F.value); diff --git a/core/object/object.cpp b/core/object/object.cpp index 6c7cf1599a..e88b3e70d6 100644 --- a/core/object/object.cpp +++ b/core/object/object.cpp @@ -752,7 +752,7 @@ Variant Object::callv(const StringName &p_method, const Array &p_args) { Callable::CallError ce; const Variant ret = callp(p_method, argptrs, p_args.size(), ce); if (ce.error != Callable::CallError::CALL_OK) { - ERR_FAIL_V_MSG(Variant(), "Error calling method from 'callv': " + Variant::get_call_error_text(this, p_method, argptrs, p_args.size(), ce) + "."); + ERR_FAIL_V_MSG(Variant(), vformat("Error calling method from 'callv': %s.", Variant::get_call_error_text(this, p_method, argptrs, p_args.size(), ce))); } return ret; } @@ -1001,7 +1001,7 @@ void Object::set_meta(const StringName &p_name, const Variant &p_value) { if (E) { E->value = p_value; } else { - ERR_FAIL_COND_MSG(!p_name.operator String().is_valid_ascii_identifier(), "Invalid metadata identifier: '" + p_name + "'."); + ERR_FAIL_COND_MSG(!p_name.operator String().is_valid_ascii_identifier(), vformat("Invalid metadata identifier: '%s'.", p_name)); Variant *V = &metadata.insert(p_name, p_value)->value; const String &sname = p_name; @@ -1017,7 +1017,7 @@ Variant Object::get_meta(const StringName &p_name, const Variant &p_default) con if (p_default != Variant()) { return p_default; } else { - ERR_FAIL_V_MSG(Variant(), "The object does not have any 'meta' values with the key '" + p_name + "'."); + ERR_FAIL_V_MSG(Variant(), vformat("The object does not have any 'meta' values with the key '%s'.", p_name)); } } return metadata[p_name]; @@ -1073,8 +1073,8 @@ void Object::get_meta_list(List<StringName> *p_list) const { void Object::add_user_signal(const MethodInfo &p_signal) { ERR_FAIL_COND_MSG(p_signal.name.is_empty(), "Signal name cannot be empty."); - ERR_FAIL_COND_MSG(ClassDB::has_signal(get_class_name(), p_signal.name), "User signal's name conflicts with a built-in signal of '" + get_class_name() + "'."); - ERR_FAIL_COND_MSG(signal_map.has(p_signal.name), "Trying to add already existing signal '" + p_signal.name + "'."); + ERR_FAIL_COND_MSG(ClassDB::has_signal(get_class_name(), p_signal.name), vformat("User signal's name conflicts with a built-in signal of '%s'.", get_class_name())); + ERR_FAIL_COND_MSG(signal_map.has(p_signal.name), vformat("Trying to add already existing signal '%s'.", p_signal.name)); SignalData s; s.user = p_signal; signal_map[p_signal.name] = s; @@ -1139,7 +1139,7 @@ Error Object::emit_signalp(const StringName &p_name, const Variant **p_args, int #ifdef DEBUG_ENABLED bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_name); //check in script - ERR_FAIL_COND_V_MSG(!signal_is_valid && !script.is_null() && !Ref<Script>(script)->has_script_signal(p_name), ERR_UNAVAILABLE, "Can't emit non-existing signal " + String("\"") + p_name + "\"."); + ERR_FAIL_COND_V_MSG(!signal_is_valid && !script.is_null() && !Ref<Script>(script)->has_script_signal(p_name), ERR_UNAVAILABLE, vformat("Can't emit non-existing signal \"%s\".", p_name)); #endif //not connected? just return return ERR_UNAVAILABLE; @@ -1212,7 +1212,7 @@ Error Object::emit_signalp(const StringName &p_name, const Variant **p_args, int if (ce.error == Callable::CallError::CALL_ERROR_INVALID_METHOD && target && !ClassDB::class_exists(target->get_class_name())) { //most likely object is not initialized yet, do not throw error. } else { - ERR_PRINT("Error calling from signal '" + String(p_name) + "' to callable: " + Variant::get_callable_error_text(callable, args, argc, ce) + "."); + ERR_PRINT(vformat("Error calling from signal '%s' to callable: %s.", String(p_name), Variant::get_callable_error_text(callable, args, argc, ce))); err = ERR_METHOD_NOT_FOUND; } } @@ -1373,15 +1373,15 @@ void Object::get_signals_connected_to_this(List<Connection> *p_connections) cons } Error Object::connect(const StringName &p_signal, const Callable &p_callable, uint32_t p_flags) { - ERR_FAIL_COND_V_MSG(p_callable.is_null(), ERR_INVALID_PARAMETER, "Cannot connect to '" + p_signal + "': the provided callable is null."); + ERR_FAIL_COND_V_MSG(p_callable.is_null(), ERR_INVALID_PARAMETER, vformat("Cannot connect to '%s': the provided callable is null.", p_signal)); if (p_callable.is_standard()) { // FIXME: This branch should probably removed in favor of the `is_valid()` branch, but there exist some classes // that call `connect()` before they are fully registered with ClassDB. Until all such classes can be found // and registered soon enough this branch is needed to allow `connect()` to succeed. - ERR_FAIL_NULL_V_MSG(p_callable.get_object(), ERR_INVALID_PARAMETER, "Cannot connect to '" + p_signal + "' to callable '" + p_callable + "': the callable object is null."); + ERR_FAIL_NULL_V_MSG(p_callable.get_object(), ERR_INVALID_PARAMETER, vformat("Cannot connect to '%s' to callable '%s': the callable object is null.", p_signal, p_callable)); } else { - ERR_FAIL_COND_V_MSG(!p_callable.is_valid(), ERR_INVALID_PARAMETER, "Cannot connect to '" + p_signal + "': the provided callable is not valid: " + p_callable); + ERR_FAIL_COND_V_MSG(!p_callable.is_valid(), ERR_INVALID_PARAMETER, vformat("Cannot connect to '%s': the provided callable is not valid: '%s'.", p_signal, p_callable)); } SignalData *s = signal_map.getptr(p_signal); @@ -1402,7 +1402,7 @@ Error Object::connect(const StringName &p_signal, const Callable &p_callable, ui #endif } - ERR_FAIL_COND_V_MSG(!signal_is_valid, ERR_INVALID_PARAMETER, "In Object of type '" + String(get_class()) + "': Attempt to connect nonexistent signal '" + p_signal + "' to callable '" + p_callable + "'."); + ERR_FAIL_COND_V_MSG(!signal_is_valid, ERR_INVALID_PARAMETER, vformat("In Object of type '%s': Attempt to connect nonexistent signal '%s' to callable '%s'.", String(get_class()), p_signal, p_callable)); signal_map[p_signal] = SignalData(); s = &signal_map[p_signal]; @@ -1414,7 +1414,7 @@ Error Object::connect(const StringName &p_signal, const Callable &p_callable, ui s->slot_map[*p_callable.get_base_comparator()].reference_count++; return OK; } else { - ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, "Signal '" + p_signal + "' is already connected to given callable '" + p_callable + "' in that object."); + ERR_FAIL_V_MSG(ERR_INVALID_PARAMETER, vformat("Signal '%s' is already connected to given callable '%s' in that object.", p_signal, p_callable)); } } @@ -1441,7 +1441,7 @@ Error Object::connect(const StringName &p_signal, const Callable &p_callable, ui } bool Object::is_connected(const StringName &p_signal, const Callable &p_callable) const { - ERR_FAIL_COND_V_MSG(p_callable.is_null(), false, "Cannot determine if connected to '" + p_signal + "': the provided callable is null."); // Should use `is_null`, see note in `connect` about the use of `is_valid`. + ERR_FAIL_COND_V_MSG(p_callable.is_null(), false, vformat("Cannot determine if connected to '%s': the provided callable is null.", p_signal)); // Should use `is_null`, see note in `connect` about the use of `is_valid`. const SignalData *s = signal_map.getptr(p_signal); if (!s) { bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_signal); @@ -1453,7 +1453,7 @@ bool Object::is_connected(const StringName &p_signal, const Callable &p_callable return false; } - ERR_FAIL_V_MSG(false, "Nonexistent signal: " + p_signal + "."); + ERR_FAIL_V_MSG(false, vformat("Nonexistent signal: '%s'.", p_signal)); } return s->slot_map.has(*p_callable.get_base_comparator()); @@ -1471,7 +1471,7 @@ bool Object::has_connections(const StringName &p_signal) const { return false; } - ERR_FAIL_V_MSG(false, "Nonexistent signal: " + p_signal + "."); + ERR_FAIL_V_MSG(false, vformat("Nonexistent signal: '%s'.", p_signal)); } return !s->slot_map.is_empty(); @@ -1482,17 +1482,17 @@ void Object::disconnect(const StringName &p_signal, const Callable &p_callable) } bool Object::_disconnect(const StringName &p_signal, const Callable &p_callable, bool p_force) { - ERR_FAIL_COND_V_MSG(p_callable.is_null(), false, "Cannot disconnect from '" + p_signal + "': the provided callable is null."); // Should use `is_null`, see note in `connect` about the use of `is_valid`. + ERR_FAIL_COND_V_MSG(p_callable.is_null(), false, vformat("Cannot disconnect from '%s': the provided callable is null.", p_signal)); // Should use `is_null`, see note in `connect` about the use of `is_valid`. SignalData *s = signal_map.getptr(p_signal); if (!s) { bool signal_is_valid = ClassDB::has_signal(get_class_name(), p_signal) || (!script.is_null() && Ref<Script>(script)->has_script_signal(p_signal)); - ERR_FAIL_COND_V_MSG(signal_is_valid, false, "Attempt to disconnect a nonexistent connection from '" + to_string() + "'. Signal: '" + p_signal + "', callable: '" + p_callable + "'."); + ERR_FAIL_COND_V_MSG(signal_is_valid, false, vformat("Attempt to disconnect a nonexistent connection from '%s'. Signal: '%s', callable: '%s'.", to_string(), p_signal, p_callable)); } - ERR_FAIL_NULL_V_MSG(s, false, vformat("Disconnecting nonexistent signal '%s' in %s.", p_signal, to_string())); + ERR_FAIL_NULL_V_MSG(s, false, vformat("Disconnecting nonexistent signal '%s' in '%s'.", p_signal, to_string())); - ERR_FAIL_COND_V_MSG(!s->slot_map.has(*p_callable.get_base_comparator()), false, "Attempt to disconnect a nonexistent connection from '" + to_string() + "'. Signal: '" + p_signal + "', callable: '" + p_callable + "'."); + ERR_FAIL_COND_V_MSG(!s->slot_map.has(*p_callable.get_base_comparator()), false, vformat("Attempt to disconnect a nonexistent connection from '%s'. Signal: '%s', callable: '%s'.", to_string(), p_signal, p_callable)); SignalData::Slot *slot = &s->slot_map[*p_callable.get_base_comparator()]; @@ -2130,7 +2130,7 @@ Object::~Object() { if (_emitting) { //@todo this may need to actually reach the debugger prioritarily somehow because it may crash before - ERR_PRINT("Object " + to_string() + " was freed or unreferenced while a signal is being emitted from it. Try connecting to the signal using 'CONNECT_DEFERRED' flag, or use queue_free() to free the object (if this object is a Node) to avoid this error and potential crashes."); + ERR_PRINT(vformat("Object '%s' was freed or unreferenced while a signal is being emitted from it. Try connecting to the signal using 'CONNECT_DEFERRED' flag, or use queue_free() to free the object (if this object is a Node) to avoid this error and potential crashes.", to_string())); } // Drop all connections to the signals of this object. diff --git a/core/object/script_language.cpp b/core/object/script_language.cpp index 8571ccff43..15fa7e13f8 100644 --- a/core/object/script_language.cpp +++ b/core/object/script_language.cpp @@ -241,9 +241,9 @@ Error ScriptServer::register_language(ScriptLanguage *p_language) { ERR_FAIL_COND_V_MSG(_language_count >= MAX_LANGUAGES, ERR_UNAVAILABLE, "Script languages limit has been reach, cannot register more."); for (int i = 0; i < _language_count; i++) { const ScriptLanguage *other_language = _languages[i]; - ERR_FAIL_COND_V_MSG(other_language->get_extension() == p_language->get_extension(), ERR_ALREADY_EXISTS, "A script language with extension '" + p_language->get_extension() + "' is already registered."); - ERR_FAIL_COND_V_MSG(other_language->get_name() == p_language->get_name(), ERR_ALREADY_EXISTS, "A script language with name '" + p_language->get_name() + "' is already registered."); - ERR_FAIL_COND_V_MSG(other_language->get_type() == p_language->get_type(), ERR_ALREADY_EXISTS, "A script language with type '" + p_language->get_type() + "' is already registered."); + ERR_FAIL_COND_V_MSG(other_language->get_extension() == p_language->get_extension(), ERR_ALREADY_EXISTS, vformat("A script language with extension '%s' is already registered.", p_language->get_extension())); + ERR_FAIL_COND_V_MSG(other_language->get_name() == p_language->get_name(), ERR_ALREADY_EXISTS, vformat("A script language with name '%s' is already registered.", p_language->get_name())); + ERR_FAIL_COND_V_MSG(other_language->get_type() == p_language->get_type(), ERR_ALREADY_EXISTS, vformat("A script language with type '%s' is already registered.", p_language->get_type())); } _languages[_language_count++] = p_language; return OK; diff --git a/core/object/undo_redo.cpp b/core/object/undo_redo.cpp index 6b80af3f28..db6c02f330 100644 --- a/core/object/undo_redo.cpp +++ b/core/object/undo_redo.cpp @@ -366,7 +366,7 @@ void UndoRedo::_process_operation_list(List<Operation>::Element *E, bool p_execu Variant ret; op.callable.callp(nullptr, 0, ret, ce); if (ce.error != Callable::CallError::CALL_OK) { - ERR_PRINT("Error calling UndoRedo method operation '" + String(op.name) + "': " + Variant::get_call_error_text(obj, op.name, nullptr, 0, ce)); + ERR_PRINT(vformat("Error calling UndoRedo method operation '%s': %s.", String(op.name), Variant::get_call_error_text(obj, op.name, nullptr, 0, ce))); } #ifdef TOOLS_ENABLED Resource *res = Object::cast_to<Resource>(obj); diff --git a/core/os/os.cpp b/core/os/os.cpp index 91a9f4a2fd..b41ea0a87f 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -354,7 +354,7 @@ void OS::ensure_user_data_dir() { Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); Error err = da->make_dir_recursive(dd); - ERR_FAIL_COND_MSG(err != OK, "Error attempting to create data dir: " + dd + "."); + ERR_FAIL_COND_MSG(err != OK, vformat("Error attempting to create data dir: %s.", dd)); } String OS::get_model_name() const { diff --git a/core/string/node_path.cpp b/core/string/node_path.cpp index 55624c4db8..9b5d3bd1fa 100644 --- a/core/string/node_path.cpp +++ b/core/string/node_path.cpp @@ -422,7 +422,7 @@ NodePath::NodePath(const String &p_path) { continue; // Allow end-of-path : } - ERR_FAIL_MSG("Invalid NodePath '" + p_path + "'."); + ERR_FAIL_MSG(vformat("Invalid NodePath '%s'.", p_path)); } subpath.push_back(str); diff --git a/core/string/translation_po.cpp b/core/string/translation_po.cpp index 756b5af673..5aa230ff00 100644 --- a/core/string/translation_po.cpp +++ b/core/string/translation_po.cpp @@ -248,7 +248,7 @@ void TranslationPO::add_message(const StringName &p_src_text, const StringName & HashMap<StringName, Vector<StringName>> &map_id_str = translation_map[p_context]; if (map_id_str.has(p_src_text)) { - WARN_PRINT("Double translations for \"" + String(p_src_text) + "\" under the same context \"" + String(p_context) + "\" for locale \"" + get_locale() + "\".\nThere should only be one unique translation for a given string under the same context."); + WARN_PRINT(vformat("Double translations for \"%s\" under the same context \"%s\" for locale \"%s\".\nThere should only be one unique translation for a given string under the same context.", String(p_src_text), String(p_context), get_locale())); map_id_str[p_src_text].set(0, p_xlated_text); } else { map_id_str[p_src_text].push_back(p_xlated_text); @@ -256,12 +256,12 @@ void TranslationPO::add_message(const StringName &p_src_text, const StringName & } void TranslationPO::add_plural_message(const StringName &p_src_text, const Vector<String> &p_plural_xlated_texts, const StringName &p_context) { - ERR_FAIL_COND_MSG(p_plural_xlated_texts.size() != plural_forms, "Trying to add plural texts that don't match the required number of plural forms for locale \"" + get_locale() + "\""); + ERR_FAIL_COND_MSG(p_plural_xlated_texts.size() != plural_forms, vformat("Trying to add plural texts that don't match the required number of plural forms for locale \"%s\".", get_locale())); HashMap<StringName, Vector<StringName>> &map_id_str = translation_map[p_context]; if (map_id_str.has(p_src_text)) { - WARN_PRINT("Double translations for \"" + p_src_text + "\" under the same context \"" + p_context + "\" for locale " + get_locale() + ".\nThere should only be one unique translation for a given string under the same context."); + WARN_PRINT(vformat("Double translations for \"%s\" under the same context \"%s\" for locale %s.\nThere should only be one unique translation for a given string under the same context.", p_src_text, p_context, get_locale())); map_id_str[p_src_text].clear(); } @@ -282,7 +282,7 @@ StringName TranslationPO::get_message(const StringName &p_src_text, const String if (!translation_map.has(p_context) || !translation_map[p_context].has(p_src_text)) { return StringName(); } - ERR_FAIL_COND_V_MSG(translation_map[p_context][p_src_text].is_empty(), StringName(), "Source text \"" + String(p_src_text) + "\" is registered but doesn't have a translation. Please report this bug."); + ERR_FAIL_COND_V_MSG(translation_map[p_context][p_src_text].is_empty(), StringName(), vformat("Source text \"%s\" is registered but doesn't have a translation. Please report this bug.", String(p_src_text))); return translation_map[p_context][p_src_text][0]; } @@ -298,7 +298,7 @@ StringName TranslationPO::get_plural_message(const StringName &p_src_text, const if (!translation_map.has(p_context) || !translation_map[p_context].has(p_src_text)) { return StringName(); } - ERR_FAIL_COND_V_MSG(translation_map[p_context][p_src_text].is_empty(), StringName(), "Source text \"" + String(p_src_text) + "\" is registered but doesn't have a translation. Please report this bug."); + ERR_FAIL_COND_V_MSG(translation_map[p_context][p_src_text].is_empty(), StringName(), vformat("Source text \"%s\" is registered but doesn't have a translation. Please report this bug.", String(p_src_text))); int plural_index = _get_plural_index(p_n); ERR_FAIL_COND_V_MSG(plural_index < 0 || translation_map[p_context][p_src_text].size() < plural_index + 1, StringName(), "Plural index returned or number of plural translations is not valid. Please report this bug."); diff --git a/core/string/ustring.cpp b/core/string/ustring.cpp index 38f610eaca..9bfc0a67cb 100644 --- a/core/string/ustring.cpp +++ b/core/string/ustring.cpp @@ -1821,7 +1821,7 @@ String String::num(double p_num, int p_decimals) { #endif buf[324] = 0; - //destroy trailing zeroes + // Destroy trailing zeroes, except one after period. { bool period = false; int z = 0; @@ -1838,7 +1838,7 @@ String String::num(double p_num, int p_decimals) { if (buf[z] == '0') { buf[z] = 0; } else if (buf[z] == '.') { - buf[z] = 0; + buf[z + 1] = '0'; break; } else { break; @@ -1931,14 +1931,28 @@ String String::num_real(double p_num, bool p_trailing) { return num_int64((int64_t)p_num); } } -#ifdef REAL_T_IS_DOUBLE int decimals = 14; -#else + // We want to align the digits to the above sane default, so we only need + // to subtract log10 for numbers with a positive power of ten magnitude. + const double abs_num = Math::abs(p_num); + if (abs_num > 10) { + decimals -= (int)floor(log10(abs_num)); + } + return num(p_num, decimals); +} + +String String::num_real(float p_num, bool p_trailing) { + if (p_num == (float)(int64_t)p_num) { + if (p_trailing) { + return num_int64((int64_t)p_num) + ".0"; + } else { + return num_int64((int64_t)p_num); + } + } int decimals = 6; -#endif // We want to align the digits to the above sane default, so we only need // to subtract log10 for numbers with a positive power of ten magnitude. - double abs_num = Math::abs(p_num); + const float abs_num = Math::abs(p_num); if (abs_num > 10) { decimals -= (int)floor(log10(abs_num)); } @@ -4618,7 +4632,7 @@ String String::humanize_size(uint64_t p_size) { } if (magnitude == 0) { - return String::num(p_size) + " " + RTR("B"); + return String::num_uint64(p_size) + " " + RTR("B"); } else { String suffix; switch (magnitude) { diff --git a/core/string/ustring.h b/core/string/ustring.h index d6c0907ecc..11be148084 100644 --- a/core/string/ustring.h +++ b/core/string/ustring.h @@ -334,6 +334,7 @@ public: static String num(double p_num, int p_decimals = -1); static String num_scientific(double p_num); static String num_real(double p_num, bool p_trailing = true); + static String num_real(float p_num, bool p_trailing = true); static String num_int64(int64_t p_num, int base = 10, bool capitalize_hex = false); static String num_uint64(uint64_t p_num, int base = 10, bool capitalize_hex = false); static String chr(char32_t p_char); diff --git a/core/variant/array.cpp b/core/variant/array.cpp index d5cc1df599..cf24924e0b 100644 --- a/core/variant/array.cpp +++ b/core/variant/array.cpp @@ -387,7 +387,7 @@ int Array::find_custom(const Callable &p_callable, int p_from) const { Callable::CallError ce; p_callable.callp(argptrs, 1, res, ce); if (unlikely(ce.error != Callable::CallError::CALL_OK)) { - ERR_FAIL_V_MSG(ret, "Error calling method from 'find_custom': " + Variant::get_callable_error_text(p_callable, argptrs, 1, ce)); + ERR_FAIL_V_MSG(ret, vformat("Error calling method from 'find_custom': %s.", Variant::get_callable_error_text(p_callable, argptrs, 1, ce))); } ERR_FAIL_COND_V_MSG(res.get_type() != Variant::Type::BOOL, ret, "Error on method from 'find_custom': Return type of callable must be boolean."); @@ -447,7 +447,7 @@ int Array::rfind_custom(const Callable &p_callable, int p_from) const { Callable::CallError ce; p_callable.callp(argptrs, 1, res, ce); if (unlikely(ce.error != Callable::CallError::CALL_OK)) { - ERR_FAIL_V_MSG(-1, "Error calling method from 'rfind_custom': " + Variant::get_callable_error_text(p_callable, argptrs, 1, ce)); + ERR_FAIL_V_MSG(-1, vformat("Error calling method from 'rfind_custom': %s.", Variant::get_callable_error_text(p_callable, argptrs, 1, ce))); } ERR_FAIL_COND_V_MSG(res.get_type() != Variant::Type::BOOL, -1, "Error on method from 'rfind_custom': Return type of callable must be boolean."); @@ -576,7 +576,7 @@ Array Array::filter(const Callable &p_callable) const { Callable::CallError ce; p_callable.callp(argptrs, 1, result, ce); if (ce.error != Callable::CallError::CALL_OK) { - ERR_FAIL_V_MSG(Array(), "Error calling method from 'filter': " + Variant::get_callable_error_text(p_callable, argptrs, 1, ce)); + ERR_FAIL_V_MSG(Array(), vformat("Error calling method from 'filter': %s.", Variant::get_callable_error_text(p_callable, argptrs, 1, ce))); } if (result.operator bool()) { @@ -602,7 +602,7 @@ Array Array::map(const Callable &p_callable) const { Callable::CallError ce; p_callable.callp(argptrs, 1, result, ce); if (ce.error != Callable::CallError::CALL_OK) { - ERR_FAIL_V_MSG(Array(), "Error calling method from 'map': " + Variant::get_callable_error_text(p_callable, argptrs, 1, ce)); + ERR_FAIL_V_MSG(Array(), vformat("Error calling method from 'map': %s.", Variant::get_callable_error_text(p_callable, argptrs, 1, ce))); } new_arr[i] = result; @@ -628,7 +628,7 @@ Variant Array::reduce(const Callable &p_callable, const Variant &p_accum) const Callable::CallError ce; p_callable.callp(argptrs, 2, result, ce); if (ce.error != Callable::CallError::CALL_OK) { - ERR_FAIL_V_MSG(Variant(), "Error calling method from 'reduce': " + Variant::get_callable_error_text(p_callable, argptrs, 2, ce)); + ERR_FAIL_V_MSG(Variant(), vformat("Error calling method from 'reduce': %s.", Variant::get_callable_error_text(p_callable, argptrs, 2, ce))); } ret = result; } @@ -645,7 +645,7 @@ bool Array::any(const Callable &p_callable) const { Callable::CallError ce; p_callable.callp(argptrs, 1, result, ce); if (ce.error != Callable::CallError::CALL_OK) { - ERR_FAIL_V_MSG(false, "Error calling method from 'any': " + Variant::get_callable_error_text(p_callable, argptrs, 1, ce)); + ERR_FAIL_V_MSG(false, vformat("Error calling method from 'any': %s.", Variant::get_callable_error_text(p_callable, argptrs, 1, ce))); } if (result.operator bool()) { @@ -667,7 +667,7 @@ bool Array::all(const Callable &p_callable) const { Callable::CallError ce; p_callable.callp(argptrs, 1, result, ce); if (ce.error != Callable::CallError::CALL_OK) { - ERR_FAIL_V_MSG(false, "Error calling method from 'all': " + Variant::get_callable_error_text(p_callable, argptrs, 1, ce)); + ERR_FAIL_V_MSG(false, vformat("Error calling method from 'all': %s.", Variant::get_callable_error_text(p_callable, argptrs, 1, ce))); } if (!(result.operator bool())) { diff --git a/core/variant/container_type_validate.h b/core/variant/container_type_validate.h index 1bda6f3127..867aadc5d4 100644 --- a/core/variant/container_type_validate.h +++ b/core/variant/container_type_validate.h @@ -96,7 +96,7 @@ struct ContainerTypeValidate { return true; } - ERR_FAIL_V_MSG(false, "Attempted to " + String(p_operation) + " a variable of type '" + Variant::get_type_name(inout_variant.get_type()) + "' into a " + where + " of type '" + Variant::get_type_name(type) + "'."); + ERR_FAIL_V_MSG(false, vformat("Attempted to %s a variable of type '%s' into a %s of type '%s'.", String(p_operation), Variant::get_type_name(inout_variant.get_type()), where, Variant::get_type_name(type))); } if (type != Variant::OBJECT) { @@ -115,7 +115,7 @@ struct ContainerTypeValidate { return true; // This is fine, it's null. } Object *object = ObjectDB::get_instance(object_id); - ERR_FAIL_NULL_V_MSG(object, false, "Attempted to " + String(p_operation) + " an invalid (previously freed?) object instance into a '" + String(where) + "."); + ERR_FAIL_NULL_V_MSG(object, false, vformat("Attempted to %s an invalid (previously freed?) object instance into a '%s'.", String(p_operation), String(where))); #else Object *object = p_variant; if (object == nullptr) { @@ -128,7 +128,7 @@ struct ContainerTypeValidate { StringName obj_class = object->get_class_name(); if (obj_class != class_name) { - ERR_FAIL_COND_V_MSG(!ClassDB::is_parent_class(object->get_class_name(), class_name), false, "Attempted to " + String(p_operation) + " an object of type '" + object->get_class() + "' into a " + where + ", which does not inherit from '" + String(class_name) + "'."); + ERR_FAIL_COND_V_MSG(!ClassDB::is_parent_class(object->get_class_name(), class_name), false, vformat("Attempted to %s an object of type '%s' into a %s, which does not inherit from '%s'.", String(p_operation), object->get_class(), where, String(class_name))); } if (script.is_null()) { @@ -138,8 +138,8 @@ struct ContainerTypeValidate { Ref<Script> other_script = object->get_script(); // Check base script.. - ERR_FAIL_COND_V_MSG(other_script.is_null(), false, "Attempted to " + String(p_operation) + " an object into a " + String(where) + ", that does not inherit from '" + String(script->get_class_name()) + "'."); - ERR_FAIL_COND_V_MSG(!other_script->inherits_script(script), false, "Attempted to " + String(p_operation) + " an object into a " + String(where) + ", that does not inherit from '" + String(script->get_class_name()) + "'."); + ERR_FAIL_COND_V_MSG(other_script.is_null(), false, vformat("Attempted to %s an object into a %s, that does not inherit from '%s'.", String(p_operation), String(where), String(script->get_class_name()))); + ERR_FAIL_COND_V_MSG(!other_script->inherits_script(script), false, vformat("Attempted to %s an object into a %s, that does not inherit from '%s'.", String(p_operation), String(where), String(script->get_class_name()))); return true; } diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index 49119b9303..26c0e8b6e1 100644 --- a/core/variant/variant.cpp +++ b/core/variant/variant.cpp @@ -1738,7 +1738,7 @@ String Variant::stringify(int recursion_count) const { case INT: return itos(_data._int); case FLOAT: - return rtos(_data._float); + return String::num_real(_data._float, true); case STRING: return *reinterpret_cast<const String *>(_data._mem); case VECTOR2: diff --git a/core/variant/variant_construct.cpp b/core/variant/variant_construct.cpp index 0cbdebb110..5d684c96a2 100644 --- a/core/variant/variant_construct.cpp +++ b/core/variant/variant_construct.cpp @@ -45,7 +45,7 @@ static LocalVector<VariantConstructData> construct_data[Variant::VARIANT_MAX]; template <typename T> static void add_constructor(const Vector<String> &arg_names) { - ERR_FAIL_COND_MSG(arg_names.size() != T::get_argument_count(), "Argument names size mismatch for " + Variant::get_type_name(T::get_base_type()) + "."); + ERR_FAIL_COND_MSG(arg_names.size() != T::get_argument_count(), vformat("Argument names size mismatch for '%s'.", Variant::get_type_name(T::get_base_type()))); VariantConstructData cd; cd.construct = T::construct; diff --git a/core/variant/variant_utility.cpp b/core/variant/variant_utility.cpp index 490ccd04a6..8e4231c90e 100644 --- a/core/variant/variant_utility.cpp +++ b/core/variant/variant_utility.cpp @@ -1673,7 +1673,7 @@ static void register_utility_function(const String &p_name, const Vector<String> bfi.argnames = argnames; bfi.argcount = T::get_argument_count(); if (!bfi.is_vararg) { - ERR_FAIL_COND_MSG(argnames.size() != bfi.argcount, "wrong number of arguments binding utility function: " + name); + ERR_FAIL_COND_MSG(argnames.size() != bfi.argcount, vformat("Wrong number of arguments binding utility function: '%s'.", name)); } bfi.get_arg_type = T::get_argument_type; bfi.return_type = T::get_return_type(); |