-
Notifications
You must be signed in to change notification settings - Fork 43
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
Settings - Implement Settings Backend #396
Comments
Related: #308 |
Should use source generators instead of reflection to auto-generate the settings panel. |
From discussion in meeting:
I'll add a list of setting types below, might not be exhaustive, so please contribute to it if you see something missing or something that is excessive. |
Types of settings that I can think of and possible ui:
Additional info for each setting:
|
Other Design question:
An extension could add a setting that semantically goes into a specific section (e.g. Downloads) but it's from an Extension which could be it's own section. VS Code does this by having a separate section for each extension, under which there are nested sections for the actual sections (e.g. SomeExtensionSection > Downloads > actualSetting). I don't know if this is the best idea, but potentially we might need nested sections (more than just one level). |
Settings that need adding:
|
@Greg-Nexus for this ticket, is it just the above two settings? |
Handover documentation complete Demo settings-demo.mp4 |
We should try to simplify paths to KnownPaths + relative path.
Also we probably want validators around config options. |
@captainsandypants We need Design for displaying settings with a Warning, such as Experimental or Not Recommended. This came up in the context of offering an option to not Backup the game files when managing the game for the first time, which exposes the users to potential issues if the game updates, since we don't have the backups of the old files if the user wants to rollback. |
Changed this issue to refer only to the backend part of the Settings, UI is in #920. Implementing backend for settings will allow us to have a standard way to add configuration as we build various components. Without this, if we need to add a setting as we develop components, we would ether:
Allowing users to access and change the values from the UI can come at a later point. |
@Al12rs @Sewer56 thoughts on using a builder pattern for configuring how settings are displayed and how they behave? file record MySettings : ISettings
{
public required string Name { get; init; } = "Placeholder";
public required bool EnableCoolFeature { get; init; } = true;
public ISettingsBuilder Configure(ISettingsBuilder settingsBuilder)
{
var sectionId = SectionId.From(Guid.Parse("33dd8d48-124b-4d59-839c-249caed881ea"));
settingsBuilder = settingsBuilder.AddSection(sectionId, "General");
return settingsBuilder.AddSettings<MySettings>(builder => builder
.WithSection(sectionId)
.ConfigureField(x => x.Name, fieldBuilder => fieldBuilder
.WithName("Name")
.WithDescription("This is a cool name that you can change.")
.WithValidation(ValidateName)
)
.ConfigureField(x => x.EnableCoolFeature, fieldBuilder => fieldBuilder
.WithName("Cool Feature")
.WithDescription("This is a very cool feature that you can enable.")
.RequiresRestart("Toggling this cool feature requires a restart!")
)
.Finish()
);
}
private static ValidationResult ValidateName(string name)
{
const int minLength = 5;
const int maxLength = 50;
if (string.IsNullOrWhiteSpace(name))
return ValidationResult.CreateFailed("Name cannot be empty!");
if (name.Length < minLength)
return ValidationResult.CreateFailed($"Name must be at least {minLength} characters long!");
if (name.Length > maxLength)
return ValidationResult.CreateFailed($"Name must be less than {minLength} characters long!");
return ValidationResult.CreateSuccessful();
}
} |
I refactored the API to be easier to understand: return settingsBuilder.AddToUI<MySettings>(uiBuilder => uiBuilder
.AddToSection(SectionId.DefaultValue)
.AddPropertyToUI(x => x.Name, propertyBuilder => propertyBuilder
.WithDisplayName("Cool Name")
.WithDescription("This is a very cool name that you can change!")
.WithValidation(ValidateName)
.RequiresRestart("Changing this very cool name requires a restart!")
)
); |
Using the modern Configuration approach, components in our DI system can require
IOption<MyOptions>
orIOptionMonitor<MyOptions>
to access component-specific configuration without having to deal with loading, saving and updating them. The monitor is especially useful as it's fully reactive and allows for changes to be applied immediately (see #362 for an example).These settings/options should be saved to disk as JSON to be persistent, but should also be presented to the user in some capacity. Such a system would provide implementations of
IOptionMonitor<T>
and serve as a configuration provider.The text was updated successfully, but these errors were encountered: