diff options
Diffstat (limited to 'core/config')
-rw-r--r-- | core/config/engine.cpp | 50 | ||||
-rw-r--r-- | core/config/engine.h | 15 | ||||
-rw-r--r-- | core/config/project_settings.cpp | 44 |
3 files changed, 82 insertions, 27 deletions
diff --git a/core/config/engine.cpp b/core/config/engine.cpp index e1da9eb44e..94db3612b4 100644 --- a/core/config/engine.cpp +++ b/core/config/engine.cpp @@ -33,7 +33,10 @@ #include "core/authors.gen.h" #include "core/config/project_settings.h" #include "core/donors.gen.h" +#include "core/io/json.h" #include "core/license.gen.h" +#include "core/os/os.h" +#include "core/variant/typed_array.h" #include "core/version.h" void Engine::set_physics_ticks_per_second(int p_ips) { @@ -134,8 +137,8 @@ Dictionary Engine::get_author_info() const { return dict; } -Array Engine::get_copyright_info() const { - Array components; +TypedArray<Dictionary> Engine::get_copyright_info() const { + TypedArray<Dictionary> components; for (int component_index = 0; component_index < COPYRIGHT_INFO_COUNT; component_index++) { const ComponentCopyright &cp_info = COPYRIGHT_INFO[component_index]; Dictionary component_dict; @@ -188,11 +191,11 @@ String Engine::get_architecture_name() const { #elif defined(__i386) || defined(__i386__) || defined(_M_IX86) return "x86_32"; -#elif defined(__aarch64__) || defined(_M_ARM64) +#elif defined(__aarch64__) || defined(_M_ARM64) || defined(_M_ARM64EC) return "arm64"; -#elif defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7S__) - return "armv7"; +#elif defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7S__) || defined(_M_ARM) + return "arm32"; #elif defined(__riscv) #if __riscv_xlen == 8 @@ -307,6 +310,43 @@ Engine::Engine() { singleton = this; } +void Engine::startup_begin() { + startup_benchmark_total_from = OS::get_singleton()->get_ticks_usec(); +} + +void Engine::startup_benchmark_begin_measure(const String &p_what) { + startup_benchmark_section = p_what; + startup_benchmark_from = OS::get_singleton()->get_ticks_usec(); +} +void Engine::startup_benchmark_end_measure() { + uint64_t total = OS::get_singleton()->get_ticks_usec() - startup_benchmark_from; + double total_f = double(total) / double(1000000); + + startup_benchmark_json[startup_benchmark_section] = total_f; +} + +void Engine::startup_dump(const String &p_to_file) { + uint64_t total = OS::get_singleton()->get_ticks_usec() - startup_benchmark_total_from; + double total_f = double(total) / double(1000000); + startup_benchmark_json["total_time"] = total_f; + + if (!p_to_file.is_empty()) { + Ref<FileAccess> f = FileAccess::open(p_to_file, FileAccess::WRITE); + if (f.is_valid()) { + Ref<JSON> json; + json.instantiate(); + f->store_string(json->stringify(startup_benchmark_json, "\t", false, true)); + } + } else { + List<Variant> keys; + startup_benchmark_json.get_key_list(&keys); + print_line("STARTUP BENCHMARK:"); + for (const Variant &K : keys) { + print_line("\t-", K, ": ", startup_benchmark_json[K], +" sec."); + } + } +} + Engine::Singleton::Singleton(const StringName &p_name, Object *p_ptr, const StringName &p_class_name) : name(p_name), ptr(p_ptr), diff --git a/core/config/engine.h b/core/config/engine.h index 649be23717..121fd4d541 100644 --- a/core/config/engine.h +++ b/core/config/engine.h @@ -36,6 +36,9 @@ #include "core/templates/list.h" #include "core/templates/vector.h" +template <typename T> +class TypedArray; + class Engine { public: struct Singleton { @@ -79,6 +82,11 @@ private: String write_movie_path; String shader_cache_path; + Dictionary startup_benchmark_json; + String startup_benchmark_section; + uint64_t startup_benchmark_from = 0; + uint64_t startup_benchmark_total_from = 0; + public: static Engine *get_singleton(); @@ -134,7 +142,7 @@ public: Dictionary get_version_info() const; Dictionary get_author_info() const; - Array get_copyright_info() const; + TypedArray<Dictionary> get_copyright_info() const; Dictionary get_donor_info() const; Dictionary get_license_info() const; String get_license_text() const; @@ -151,6 +159,11 @@ public: bool is_validation_layers_enabled() const; int32_t get_gpu_index() const; + void startup_begin(); + void startup_benchmark_begin_measure(const String &p_what); + void startup_benchmark_end_measure(); + void startup_dump(const String &p_to_file); + Engine(); virtual ~Engine() {} }; diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 26b683db82..74c06123e1 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -72,7 +72,7 @@ String ProjectSettings::get_safe_project_name() const { } String ProjectSettings::get_imported_files_path() const { - return get_project_data_path().plus_file("imported"); + return get_project_data_path().path_join("imported"); } // Returns the features that a project must have when opened with this build of Godot. @@ -157,12 +157,12 @@ String ProjectSettings::localize_path(const String &p_path) const { // in an absolute path that just happens to contain this string but points to a // different folder (e.g. "/my/project" as resource_path would be contained in // "/my/project_data", even though the latter is not part of res://. - // `plus_file("")` is an easy way to ensure we have a trailing '/'. - const String res_path = resource_path.plus_file(""); + // `path_join("")` is an easy way to ensure we have a trailing '/'. + const String res_path = resource_path.path_join(""); // DirAccess::get_current_dir() is not guaranteed to return a path that with a trailing '/', // so we must make sure we have it as well in order to compare with 'res_path'. - cwd = cwd.plus_file(""); + cwd = cwd.path_join(""); if (!cwd.begins_with(res_path)) { return p_path; @@ -442,6 +442,15 @@ void ProjectSettings::_convert_to_last_version(int p_from_version) { * If nothing was found, error out. */ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, bool p_upwards, bool p_ignore_override) { + if (!OS::get_singleton()->get_resource_dir().is_empty()) { + // OS will call ProjectSettings->get_resource_path which will be empty if not overridden! + // If the OS would rather use a specific location, then it will not be empty. + resource_path = OS::get_singleton()->get_resource_dir().replace("\\", "/"); + if (!resource_path.is_empty() && resource_path[resource_path.length() - 1] == '/') { + resource_path = resource_path.substr(0, resource_path.length() - 1); // Chop end. + } + } + // If looking for files in a network client, use it directly if (FileAccessNetworkClient::get_singleton()) { @@ -463,7 +472,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b if (err == OK && !p_ignore_override) { // Load override from location of the main pack // Optional, we don't mind if it fails - _load_settings_text(p_main_pack.get_base_dir().plus_file("override.cfg")); + _load_settings_text(p_main_pack.get_base_dir().path_join("override.cfg")); } return err; } @@ -491,14 +500,14 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b #ifdef MACOS_ENABLED if (!found) { // Attempt to load PCK from macOS .app bundle resources. - found = _load_resource_pack(OS::get_singleton()->get_bundle_resource_dir().plus_file(exec_basename + ".pck")) || _load_resource_pack(OS::get_singleton()->get_bundle_resource_dir().plus_file(exec_filename + ".pck")); + found = _load_resource_pack(OS::get_singleton()->get_bundle_resource_dir().path_join(exec_basename + ".pck")) || _load_resource_pack(OS::get_singleton()->get_bundle_resource_dir().path_join(exec_filename + ".pck")); } #endif if (!found) { // Try to load data pack at the location of the executable. // As mentioned above, we have two potential names to attempt. - found = _load_resource_pack(exec_dir.plus_file(exec_basename + ".pck")) || _load_resource_pack(exec_dir.plus_file(exec_filename + ".pck")); + found = _load_resource_pack(exec_dir.path_join(exec_basename + ".pck")) || _load_resource_pack(exec_dir.path_join(exec_filename + ".pck")); } if (!found) { @@ -514,7 +523,7 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b // Load overrides from the PCK and the executable location. // Optional, we don't mind if either fails. _load_settings_text("res://override.cfg"); - _load_settings_text(exec_path.get_base_dir().plus_file("override.cfg")); + _load_settings_text(exec_path.get_base_dir().path_join("override.cfg")); } return err; } @@ -524,13 +533,6 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b // (Only Android -when reading from pck- and iOS use this.) if (!OS::get_singleton()->get_resource_dir().is_empty()) { - // OS will call ProjectSettings->get_resource_path which will be empty if not overridden! - // If the OS would rather use a specific location, then it will not be empty. - resource_path = OS::get_singleton()->get_resource_dir().replace("\\", "/"); - if (!resource_path.is_empty() && resource_path[resource_path.length() - 1] == '/') { - resource_path = resource_path.substr(0, resource_path.length() - 1); // Chop end. - } - Error err = _load_settings_text_or_binary("res://project.godot", "res://project.binary"); if (err == OK && !p_ignore_override) { // Optional, we don't mind if it fails. @@ -554,10 +556,10 @@ Error ProjectSettings::_setup(const String &p_path, const String &p_main_pack, b // Set the resource path early so things can be resolved when loading. resource_path = current_dir; resource_path = resource_path.replace("\\", "/"); // Windows path to Unix path just in case. - err = _load_settings_text_or_binary(current_dir.plus_file("project.godot"), current_dir.plus_file("project.binary")); + err = _load_settings_text_or_binary(current_dir.path_join("project.godot"), current_dir.path_join("project.binary")); if (err == OK && !p_ignore_override) { // Optional, we don't mind if it fails. - _load_settings_text(current_dir.plus_file("override.cfg")); + _load_settings_text(current_dir.path_join("override.cfg")); found = true; break; } @@ -683,7 +685,7 @@ Error ProjectSettings::_load_settings_text(const String &p_path) { // If we're loading a project.godot from source code, we can operate some // ProjectSettings conversions if need be. _convert_to_last_version(config_version); - last_save_time = FileAccess::get_modified_time(get_resource_path().plus_file("project.godot")); + 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."); @@ -762,9 +764,9 @@ void ProjectSettings::clear(const String &p_name) { } Error ProjectSettings::save() { - Error error = save_custom(get_resource_path().plus_file("project.godot")); + Error error = save_custom(get_resource_path().path_join("project.godot")); if (error == OK) { - last_save_time = FileAccess::get_modified_time(get_resource_path().plus_file("project.godot")); + last_save_time = FileAccess::get_modified_time(get_resource_path().path_join("project.godot")); } return error; } @@ -909,7 +911,7 @@ Error ProjectSettings::save_custom(const String &p_path, const CustomMap &p_cust } } // Check for the existence of a csproj file. - if (FileAccess::exists(get_resource_path().plus_file(get_safe_project_name() + ".csproj"))) { + if (FileAccess::exists(get_resource_path().path_join(get_safe_project_name() + ".csproj"))) { // If there is a csproj file, add the C# feature if it doesn't already exist. if (!project_features.has("C#")) { project_features.append("C#"); |