-
Notifications
You must be signed in to change notification settings - Fork 287
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/rethink how duality handles settings #855
Comments
Yeah, this is a design flaw in the serializer API, but a big one to fix properly. We should skip this for now and just assume the serializer API to be as-is for now. We should track this it in a separate issue though, because it is worth improving here.
If we use the regular serializer in all cases, we don't need an API or interface for this, but we could still provide one to avoid requiring that knowledge. Maybe have an abstract
Yeah, let's switch this to use Duality serializers as well and, I don't know, put the DockPanel XML inside a That said, the custom XML approach currently has the advantage that every editor plugin can just read and write arbitrary custom stuff, so when we do switch to Duality serializers, we need to mirror this behavior in a different way. One way would be to have an abstract Alternatively, the plugin classes could themselves be serialized, though that (a) requires the existing-instance thing to be implemented and (b) I'm not sure how I feel about the semantic breach we'd introduce by this. A separate class for containing a plugins settings that is serialized as a whole would be a clear separation. Besides all of this, as briefly mentioned in #852, it could make sense to rename and / or regroup all existing Duality settings. It might make sense to do this separately of any internal API / serialization changes. So right now we have:
I'd propose to rename them like this going forward, in order to provide better hints regarding their contents:
In this naming scheme, I've chosen "Options" to represent things users can adjust as they want, and "Settings" to represent something global, shared, that is not meant for everyone to adjust as they want. "System" also hints at internals not meant to be touched by players and suggests that it's the engine that is configured here, which is exactly what it does. "Project" sets the context of working on something and hints towards editor usage that way. Or, in a different form:
Thoughts? |
Agree.
We could also use composition: public class SettingsContainer<TSettings>
where TSettings : class, new()
{
public event EventHandler Changed;
public TSettings Value { get; private set; }
private readonly string path;
public SettingsContainer(string path)
{
this.path = path;
}
public void Load()
{
this.Value = Serializer.TryReadObject<TSettings>(this.path) ?? new TSettings();
Changed?.Invoke(this, EventArgs.Empty); //OnLoaded/OnLoading migth be a better name though
}
public void Save()
{
Serializer.WriteObject(this.Value, this.path, typeof(XmlSerializer));
}
} The settings class itself will just be a POCO and be wrapped by this class.
I think thats a good idea to always have. Weakly typed settings are just a pain to deal with. Steering users this way is only a good thing.
I would go for the separate class approach because thats easier to do but also like you already pointed out separating these would ensure a clear separation of concerns.
One problem with this naming I see is that its not immediately clear where these settings are used. Is
This makes it clear which one is used by the game and which one is used by the editor and just feels more consistent. EDIT: Worked out the settingscontainer idea into a draft PR #856 |
Could you give an example what the advantage of this design would be? Because it seems more complex / harder to understand than just deriving from a base class.
The same thought crossed my mind, but now we have the problem that options and settings are used pretty much synonymously - and I couldn't give an exact definition on when to use each myself. I think we need something else. How about |
Some advantages:
Composition is not that hard of a pattern to grasp and widely used. It really is nothing more than wrapping a class with a class (doesn't necessarily need to be a class though) actually as you can see in the draft PR I made. Duality actually already uses composition with for instance
But the term 'Project' really only makes sense in a editor context (which is probably the reason for your first proposal?). Shipping a Maybe we should just stick to the AppData/UserAppData naming scheme. I mean that is a quite standard way of naming this. |
Hmm.. honestly, the first two arguments don't sound super convincing to me 😄 It's a design among others, but I don't see an inherent advantage there? But you got me with the third one. Since we can't deserialize into an existing settings instance, this is a spot where it could really help.
Yeah, though you gotta admit, Anyway, you're solving an actual issue with this, so I'll stop with the design philosophy right here. Can still revisit this at some point later on when other alternatives present themselves.
Alright, let's establish this as a baseline then:
...and we can just all keep in mind that if anyone comes up with something better, we can reconsider this later. |
For usability reasons I do think we should stick with |
In that case, the code that serializes any of these settings should choose the XmlSerializer specifically via |
Note: As far as I can see from #856, the file extension change to @Barsonax Depending on your plans for that, this could either be done as part of #860, or with a separate PR. Where are we on this overall, and where can others (including me) step in and contribute towards the implementation of this issue? |
Progress
ToDo
|
Worked on the API a bit while looking into #868 and I think we should keep in mind a slight design trap we might fall into:
|
Agree this will make things cleaner with less steps in between. I just didn't went that far for a first itteration. |
Fixed some behavior that was broken during the
Both of them can be simplified away in an "abstract settings base class" scenario as opposed to a container design, which we didn't implement before due to the serializers inability to update an existing instance. However, I think we should reconsider this as soon as #877 is addressed. Edit: Actually, #877 has a workaround that could be applied right now - could be enough to do a quick base class design prototype. Will see if / when I get around to it. |
Progress
ToDo
|
Hey, im interessted how far you guys pushed Duality to bring it closer to 4.0 version, Well done, how far did you come with the settings change tho? |
I'm currently more or less in hibernation mode due to daily workload in non-OSS domains, but current progress and ToDo as documented here should be up-to-date. @Barsonax might know more, in case there are more recent changes, if any. |
Summary
There are some things that might be improved in the settings department of duality:
First it seems that duality uses 2 approaches to storing settings.
EditorUserData.xml
seems to use a completely separate code flow for writing to the settings file inDualityEditorApp.SaveUserData()
. The file itself also has 2<?xml version="1.0" encoding="utf-8"?>
which I have never seen before in a single file. Maybe some hack around dockpanel behavior?Serializer
class to write to the files. They also use the.dat
file extension instead of.xml
Second there's not a clear location for where saving and loading is implemented. Sometimes it happens in
DualityApp
orDualityEditorApp
and other times it happens in the settings class itself. I think we might benefit from making a interface with Save and Load methods where these are implemented on the class itself as that would allow us to treat settings in a more generic way (such as here https://github.com/AdamsLair/duality/blob/master/Source/Editor/DualityEditor/DualityEditorApp.cs#L1012) and also clean up some code from the already bigDualityApp
andDualityEditorApp
classes.Thirdly because of how the serializer api works atm it always creates a new instance. This makes it impossible to put change events on the settings class itself because then you would also have to resubscribe to those events which kinda defeats the purpose. It might be beneficial if the serializer api could take a already existing instance and update that instance.
The text was updated successfully, but these errors were encountered: