diff options
author | Rémi Verschelde <rverschelde@gmail.com> | 2023-01-13 18:03:15 +0100 |
---|---|---|
committer | Rémi Verschelde <rverschelde@gmail.com> | 2023-01-13 18:03:15 +0100 |
commit | 8716c12eadc571b38bb571d4b7a3c781593a9b5b (patch) | |
tree | 144592c02a2921190e537feeedd32b561020fe67 | |
parent | ef01b492275e2ebdc3769f3e4ffa925884c1e4b1 (diff) | |
parent | 6f0e210093dbd3f20bec34a4e60861dcceabd484 (diff) |
Merge pull request #71325 from reduz/refactor-project-setting-overrides
Refactor ProjectSetting overrides
-rw-r--r-- | core/config/project_settings.cpp | 53 | ||||
-rw-r--r-- | core/config/project_settings.h | 9 | ||||
-rw-r--r-- | doc/classes/ProjectSettings.xml | 19 | ||||
-rw-r--r-- | main/main.cpp | 1 | ||||
-rw-r--r-- | modules/mono/csharp_script.cpp | 2 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono.cpp | 4 | ||||
-rw-r--r-- | modules/text_server_adv/text_server_adv.cpp | 2 | ||||
-rw-r--r-- | modules/text_server_fb/text_server_fb.cpp | 2 | ||||
-rw-r--r-- | platform/web/export/export_plugin.cpp | 4 |
9 files changed, 62 insertions, 34 deletions
diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index 0bf7430d84..73d7d7420f 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -291,31 +291,26 @@ bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) { return true; } - if (!disable_feature_overrides) { + { // Feature overrides. int dot = p_name.operator String().find("."); if (dot != -1) { Vector<String> s = p_name.operator String().split("."); - bool override_valid = false; for (int i = 1; i < s.size(); i++) { String feature = s[i].strip_edges(); - if (OS::get_singleton()->has_feature(feature) || custom_features.has(feature)) { - override_valid = true; - break; + Pair<StringName, StringName> fo(feature, p_name); + + if (!feature_overrides.has(s[0])) { + feature_overrides[s[0]] = LocalVector<Pair<StringName, StringName>>(); } - } - if (override_valid) { - feature_overrides[s[0]] = p_name; + feature_overrides[s[0]].push_back(fo); } } } if (props.has(p_name)) { - if (!props[p_name].overridden) { - props[p_name].variant = p_value; - } - + props[p_name].variant = p_value; } else { props[p_name] = VariantContainer(p_value, last_order++); } @@ -340,16 +335,35 @@ bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) { bool ProjectSettings::_get(const StringName &p_name, Variant &r_ret) const { _THREAD_SAFE_METHOD_ + if (!props.has(p_name)) { + WARN_PRINT("Property not found: " + String(p_name)); + return false; + } + r_ret = props[p_name].variant; + return true; +} + +Variant ProjectSettings::get_setting_with_override(const StringName &p_name) const { + _THREAD_SAFE_METHOD_ + StringName name = p_name; - if (!disable_feature_overrides && feature_overrides.has(name)) { - name = feature_overrides[name]; + if (feature_overrides.has(name)) { + const LocalVector<Pair<StringName, StringName>> &overrides = feature_overrides[name]; + for (uint32_t i = 0; i < overrides.size(); i++) { + if (OS::get_singleton()->has_feature(overrides[i].first)) { // Custom features are checked in OS.has_feature() already. No need to check twice. + if (props.has(overrides[i].second)) { + name = overrides[i].second; + break; + } + } + } } + if (!props.has(name)) { WARN_PRINT("Property not found: " + String(name)); - return false; + return Variant(); } - r_ret = props[name].variant; - return true; + return props[name].variant; } struct _VCSort { @@ -1101,10 +1115,6 @@ const HashMap<StringName, PropertyInfo> &ProjectSettings::get_custom_property_in return custom_prop_info; } -void ProjectSettings::set_disable_feature_overrides(bool p_disable) { - disable_feature_overrides = p_disable; -} - bool ProjectSettings::is_using_datapack() const { return using_datapack; } @@ -1169,6 +1179,7 @@ void ProjectSettings::_bind_methods() { ClassDB::bind_method(D_METHOD("has_setting", "name"), &ProjectSettings::has_setting); ClassDB::bind_method(D_METHOD("set_setting", "name", "value"), &ProjectSettings::set_setting); ClassDB::bind_method(D_METHOD("get_setting", "name", "default_value"), &ProjectSettings::get_setting, DEFVAL(Variant())); + ClassDB::bind_method(D_METHOD("get_setting_with_override", "name"), &ProjectSettings::get_setting_with_override); ClassDB::bind_method(D_METHOD("set_order", "name", "position"), &ProjectSettings::set_order); ClassDB::bind_method(D_METHOD("get_order", "name"), &ProjectSettings::get_order); ClassDB::bind_method(D_METHOD("set_initial_value", "name", "value"), &ProjectSettings::set_initial_value); diff --git a/core/config/project_settings.h b/core/config/project_settings.h index 2aca1e7691..353e298919 100644 --- a/core/config/project_settings.h +++ b/core/config/project_settings.h @@ -34,6 +34,7 @@ #include "core/object/class_db.h" #include "core/os/thread_safe.h" #include "core/templates/hash_map.h" +#include "core/templates/local_vector.h" #include "core/templates/rb_set.h" class ProjectSettings : public Object { @@ -69,7 +70,6 @@ protected: Variant variant; Variant initial; bool hide_from_editor = false; - bool overridden = false; bool restart_if_changed = false; #ifdef DEBUG_METHODS_ENABLED bool ignore_value_in_docs = false; @@ -91,12 +91,11 @@ protected: RBMap<StringName, VariantContainer> props; // NOTE: Key order is used e.g. in the save_custom method. String resource_path; HashMap<StringName, PropertyInfo> custom_prop_info; - bool disable_feature_overrides = false; bool using_datapack = false; List<String> input_presets; HashSet<String> custom_features; - HashMap<StringName, StringName> feature_overrides; + HashMap<StringName, LocalVector<Pair<StringName, StringName>>> feature_overrides; HashMap<StringName, AutoloadInfo> autoloads; @@ -181,7 +180,7 @@ public: List<String> get_input_presets() const { return input_presets; } - void set_disable_feature_overrides(bool p_disable); + Variant get_setting_with_override(const StringName &p_name) const; bool is_using_datapack() const; @@ -205,7 +204,7 @@ Variant _GLOBAL_DEF(const PropertyInfo &p_info, const Variant &p_default, bool p #define GLOBAL_DEF_RST(m_var, m_value) _GLOBAL_DEF(m_var, m_value, true) #define GLOBAL_DEF_NOVAL(m_var, m_value) _GLOBAL_DEF(m_var, m_value, false, true) #define GLOBAL_DEF_RST_NOVAL(m_var, m_value) _GLOBAL_DEF(m_var, m_value, true, true) -#define GLOBAL_GET(m_var) ProjectSettings::get_singleton()->get(m_var) +#define GLOBAL_GET(m_var) ProjectSettings::get_singleton()->get_setting_with_override(m_var) #define GLOBAL_DEF_BASIC(m_var, m_value) _GLOBAL_DEF(m_var, m_value, false, false, true) #define GLOBAL_DEF_RST_BASIC(m_var, m_value) _GLOBAL_DEF(m_var, m_value, true, false, true) diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index cfcfca9880..f954e8bca8 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -84,6 +84,25 @@ GD.Print(ProjectSettings.GetSetting("application/config/custom_description", "No description specified.")); [/csharp] [/codeblocks] + [b]Note:[/b] This method doesn't take potential feature overrides into account automatically. Use [method get_setting_with_override] to handle seamlessly. + </description> + </method> + <method name="get_setting_with_override" qualifiers="const"> + <return type="Variant" /> + <param index="0" name="name" type="StringName" /> + <description> + Similar to [method get_setting], but applies feature tag overrides if any exists and is valid. + [b]Example:[/b] + If the following setting override exists "application/config/name.windows", and the following code is executed: + [codeblocks] + [gdscript] + print(ProjectSettings.get_setting_with_override("application/config/name")) + [/gdscript] + [csharp] + GD.Print(ProjectSettings.GetSettingWithOverride("application/config/name")); + [/csharp] + [/codeblocks] + Then the overridden setting will be returned instead if the project is running on the [i]Windows[/i] operating system. </description> </method> <method name="globalize_path" qualifiers="const"> diff --git a/main/main.cpp b/main/main.cpp index e38669f161..7ba5ffab2a 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1385,7 +1385,6 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph #ifdef TOOLS_ENABLED if (editor) { packed_data->set_disabled(true); - globals->set_disable_feature_overrides(true); Engine::get_singleton()->set_editor_hint(true); main_args.push_back("--editor"); if (!init_windowed) { diff --git a/modules/mono/csharp_script.cpp b/modules/mono/csharp_script.cpp index c45fdda75c..e39127e0a1 100644 --- a/modules/mono/csharp_script.cpp +++ b/modules/mono/csharp_script.cpp @@ -688,7 +688,7 @@ bool CSharpLanguage::is_assembly_reloading_needed() { return false; // Already up to date } } else { - String assembly_name = ProjectSettings::get_singleton()->get_setting("dotnet/project/assembly_name"); + String assembly_name = GLOBAL_GET("dotnet/project/assembly_name"); if (assembly_name.is_empty()) { assembly_name = ProjectSettings::get_singleton()->get_safe_project_name(); diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 6664dfb2dd..86b0e04206 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -289,7 +289,7 @@ godot_plugins_initialize_fn initialize_hostfxr_and_godot_plugins(bool &r_runtime } #else static String get_assembly_name() { - String assembly_name = ProjectSettings::get_singleton()->get_setting("dotnet/project/assembly_name"); + String assembly_name = GLOBAL_GET("dotnet/project/assembly_name"); if (assembly_name.is_empty()) { assembly_name = ProjectSettings::get_singleton()->get_safe_project_name(); @@ -466,7 +466,7 @@ void GDMono::_init_godot_api_hashes() { #ifdef TOOLS_ENABLED bool GDMono::_load_project_assembly() { - String assembly_name = ProjectSettings::get_singleton()->get_setting("dotnet/project/assembly_name"); + String assembly_name = GLOBAL_GET("dotnet/project/assembly_name"); if (assembly_name.is_empty()) { assembly_name = ProjectSettings::get_singleton()->get_safe_project_name(); diff --git a/modules/text_server_adv/text_server_adv.cpp b/modules/text_server_adv/text_server_adv.cpp index 44a2c76727..e52b87741e 100644 --- a/modules/text_server_adv/text_server_adv.cpp +++ b/modules/text_server_adv/text_server_adv.cpp @@ -42,7 +42,7 @@ using namespace godot; -#define GLOBAL_GET(m_var) ProjectSettings::get_singleton()->get(m_var) +#define GLOBAL_GET(m_var) ProjectSettings::get_singleton()->get_setting_with_override(m_var) #else // Headers for building as built-in module. diff --git a/modules/text_server_fb/text_server_fb.cpp b/modules/text_server_fb/text_server_fb.cpp index 809bfbe41a..034f88e387 100644 --- a/modules/text_server_fb/text_server_fb.cpp +++ b/modules/text_server_fb/text_server_fb.cpp @@ -42,7 +42,7 @@ using namespace godot; -#define GLOBAL_GET(m_var) ProjectSettings::get_singleton()->get(m_var) +#define GLOBAL_GET(m_var) ProjectSettings::get_singleton()->get_setting_with_override(m_var) #else // Headers for building as built-in module. diff --git a/platform/web/export/export_plugin.cpp b/platform/web/export/export_plugin.cpp index 9c31ca1268..d8e04904c7 100644 --- a/platform/web/export/export_plugin.cpp +++ b/platform/web/export/export_plugin.cpp @@ -161,7 +161,7 @@ void EditorExportPlatformWeb::_fix_html(Vector<uint8_t> &p_html, const Ref<Edito const String custom_head_include = p_preset->get("html/head_include"); HashMap<String, String> replaces; replaces["$GODOT_URL"] = p_name + ".js"; - replaces["$GODOT_PROJECT_NAME"] = ProjectSettings::get_singleton()->get_setting("application/config/name"); + replaces["$GODOT_PROJECT_NAME"] = GLOBAL_GET("application/config/name"); replaces["$GODOT_HEAD_INCLUDE"] = head_include + custom_head_include; replaces["$GODOT_CONFIG"] = str_config; _replace_strings(replaces, p_html); @@ -201,7 +201,7 @@ Error EditorExportPlatformWeb::_add_manifest_icon(const String &p_path, const St } Error EditorExportPlatformWeb::_build_pwa(const Ref<EditorExportPreset> &p_preset, const String p_path, const Vector<SharedObject> &p_shared_objects) { - String proj_name = ProjectSettings::get_singleton()->get_setting("application/config/name"); + String proj_name = GLOBAL_GET("application/config/name"); if (proj_name.is_empty()) { proj_name = "Godot Game"; } |