Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor ProjectSetting overrides #71325

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 32 additions & 21 deletions core/config/project_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
reduz marked this conversation as resolved.
Show resolved Hide resolved
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++);
}
Expand All @@ -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;
}
}
}
reduz marked this conversation as resolved.
Show resolved Hide resolved
}

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 {
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down
9 changes: 4 additions & 5 deletions core/config/project_settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -69,7 +70,6 @@ class ProjectSettings : public Object {
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;
Expand All @@ -91,12 +91,11 @@ class ProjectSettings : public Object {
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;

Expand Down Expand Up @@ -181,7 +180,7 @@ class ProjectSettings : public Object {

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;

Expand All @@ -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)
Expand Down
19 changes: 19 additions & 0 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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">
Expand Down
1 change: 0 additions & 1 deletion main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion modules/mono/csharp_script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
4 changes: 2 additions & 2 deletions modules/mono/mono_gd/gd_mono.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion modules/text_server_adv/text_server_adv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion modules/text_server_fb/text_server_fb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions platform/web/export/export_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,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);
Expand Down Expand Up @@ -193,7 +193,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";
}
Expand Down