Being able to load settings into a game is a must. There are a number of ways to accomplish this. My current method works well enough for now, although it needs a bit of work in a few areas. I accomplish this by creating a series of settings classes that can be serialized into XML and back again at run time using my simple serializer.
Settings Manager
public class SettingsManager { const string Extension = ".xml"; const string Directory = "Content\\Settings\\"; /// <summary> /// Loaded settings - Not currently implemented /// </summary> //SerializableDictionary<string, SettingsBase> _settings; /// <summary> /// Constructor /// </summary> public SettingsManager() { } /// <summary> /// Load a settings file /// </summary> public T Load<T>() { Type t = typeof(T); return Load<T>(t.Name); } /// <summary> /// Attempt to load a settings file. If not found, it will /// load a new, default instance of the settings class. /// </summary> public T Load<T>(string name) { try { return Serializer.Read<T>( SettingsManager.Directory + name + SettingsManager.Extension); } catch (Exception e) { e = null; Type t = typeof(T); return (T)Activator.CreateInstance(t); } } /// <summary> /// Save a settings object /// </summary> /// <typeparam name="T"></typeparam> public void Save<T>(T o) { Type t = typeof(T); Save<T>(o, t.Name); } /// <summary> /// Save a settings object /// </summary> /// <typeparam name="T"></typeparam> /// <param name="file_name"></param> public void Save<T>(T o, string name) { Serializer.Write<T>( o, SettingsManager.Directory + name + SettingsManager.Extension); } }
The basic idea is that we can load and save settings files either based on an arbitrary name or, for simplicity, the settings class Type.Name. This is still a rough class - it assumes a lot about the settings files being loaded such as the files being serializable. I currently have a simple class that settings files inherit from:
Settings Base
[Serializable] public abstract class SettingsBase { }
More functionality could be added here such as a Save() function that allowed settings objects to save themselves via the SettingsManager. The only special thing in this class is adding the [Serializable] tag at the top to ensure that all inheriting objects get this.
Simple Settings Example
public class PlayerSettings : SettingsBase { public int Id; public string Name; public PlayerSettings() { Id = 1; Name = "Spartacus"; } }
Now, the settings manager can be used to load/save this.
// Load default settings PlayerSettings ps = settingsManager.Load<PlayerSettings>(); // Change something ps.Name = "Hercules"; // Save with default name settingsManager.Save<PlayerSettings>(ps);
Future Improvements
- SettingsManager does not ensure that loaded files inherit from SettingsBase at all.
- SettingsManager does not track previously loaded settings files. Tracking and storing loaded files would prevent costly file IO, deserialization and reflection.
- Settings classes assume that the constructor will set the default settings.
No comments:
Post a Comment