-
Notifications
You must be signed in to change notification settings - Fork 19
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
Configuration store #96
base: master
Are you sure you want to change the base?
Conversation
This was chosen over Microsoft.Data.SQLite because the latter has a ton of additional dependencies.
ESetting was limited in two main ways: - Each get and set call had to define the value type itself. - Convert.ChangeType(...) does not support converting from strings to user-defined types. ISetting<T> resolves both of these problems, at the expense of enumerated type semantics.
This will help split up a monolithic settings scope into smaller, more focused sub-scopes.
This is the root scope for ISetting<T> constants.
Hi @aoki-marika , Thanks for the contribution,
|
I definitely agree with a lot of your points, with hindsight and more recent experience with SQLite I can see a few oversights I made here. First pointI intended this to be used exclusively for in-game configurable settings. There shouldn't be any hidden "settings" which are only used by the game present, like On the topic of the interface, it wasn't really much of a thought at the time, but it definitely should've been. new CIntSetting(ECategory.System, @"MySetting")
{
strName = "My Integer Setting",
strDescription = "My integer setting which changes something arbitrary.",
nMinValue = 0,
nMaxValue = 10,
nDefault = 0,
}; However for new CEnumSetting<EMyEnum>(ECategory.System, @"MyEnumSetting")
{
strName = "My Enumerated Setting",
strDescription = "My enumerated setting which changes something arbitrary.",
strValueDescriptions = new Dictionary<EMyEnum, string>()
{
{ EMyEnum.One: "Show 1" },
{ EMyEnum.Two: "Show 2" },
{ EMyEnum.Three: "Show 3" },
},
eDefault = EMyEnum.One,
}; Unsure on that one though, that's just off the top of my head. Localisation may also be something to consider, but I don't know how that is currently being handled by other parts of the codebase. I'm unsure on what you specifically mean by "where in the menu it is displayed". If you mean by the position within the list that it is placed, then I don't think Second pointI'm unsure what you mean by "per-user" and "per-profile"; are these not the same thing? Also "associate a profile to a box.def folder", again unsure. To clarify, I consider profiles to be a single player on the same machine, such as two friends both playing on the same setup. Are you perhaps referring to something else? Game storage should, in my opinion, definitely not be per-profile. There should be a single database with a I intended to move this to a more generic storage class in the profiles PR, but there's no reason not to implement it here. My current plan is to have a public class CDatabaseContext : IDisposable
{
private readonly SQLiteConnection connection;
public CDatabaseContext(string strConnection)
{
connection = new SQLiteConnection(strConnection);
connection.Open();
}
public void Dispose()
{
connection?.Close();
connection?.Dispose();
connection = null;
}
// execute, query, etc. methods...
}
public class CDatabaseContextFactory
{
private const string str_filename = @"game.db";
public CDatabaseContext tGetContext() => new CDatabaseContext($@"Data Source={str_filename};Version=3;");
}
public class CConfigurationStore
{
private readonly CDatabaseContextFactory contextFactory;
public CConfigurationStore(CDatabaseContextFactory contextFactory)
{
this.contextFactory = contextFactory;
}
public T tGet<T>(ISetting<T> setting)
{
using (var context = contextFactory.tGetContext())
{
...
}
}
}
Third pointVery much agreed, I should have done some profiling to ensure it's up to snuff. I'll run some tests after the other points are addressed and optimise accordingly. Caching settings is a very simple thing to implement so I'd say it's fine to leave it until then, no point optimising the current code when it seems it will receive a lot of changes. Sorry for the long write-up, just wanted to lay everything out so we could come to conclusions on where this should go. Also I appreciate you taking time out to review, I know this is a busy time of year for everyone. |
Adds
CConfigurationStore
, used for accessing database-backed settings.This PR only adds the infrastructure, it does not replace
CConfigIni
and does not function for the end user. Doing everything in one go makes it near impossible to review, so instead this sets the foundation for future PRs to build upon where they can then migrate individual components to this new system.For quick reference, the general workflow for using settings is as such:
CSetting
:CConfigurationStore.tInitialiseDefaults()
: