I'm developing a game that maintains its information in a class called WorldState
. Each GameObject in the world (trees, zombies, the player, health packs, etc) is composed of three objects: GameObjectController
, GameObjectModel
, and GameObjectView
. (These classes may be extended if the GameObject requires additional functionality.)
WorldState
has a reference to an implementation of the interface IPersistentState
, which is used to load and save GameObjects. Right now, the implementation of IPersistentState
is ReadWriteXML
, which uses XML. I fear that the IPersistentState
interface is too coupled to using XML - if I were to switch to using a database, or csv, or whatever, it would probably be necessary to change it. I don't think I'm creating enough of an abstraction.
The IPersistentState
interface:
/// <summary>
/// Used to read and write from persistent memory.
///
/// When dictionaries are returned, they are key-value pairs:
/// dict["key"] == value
///
/// Reading is done from whatever the current URI is.
/// </summary>
// This is too hard coded to XML.
public interface IPersistentState
{
/// <summary>
/// Gets the KV for every object of element `elementName`.
/// Really this is just a convenience/wrapper method for `GetAllOfTypeIn()`
/// where the ancestor is the root.
/// </summary>
/// <param name="elementName">the element of object to get, like "zombie" or "point"</param>
/// <returns>(See interface summary)
/// For Zombie, it could look like this:
///
/// dict["positionX"] == "23"
/// dict["positionY"] == "4"
///
/// etc
/// </returns>
ICollection<IDictionary<string, string>> GetAllOfType(string elementName);
/// <summary>
/// Creates or overwrites the file `fileName`, filling it with the data in `dicts`.
/// The root of the data is `rootName`.
/// </summary>
/// <param name="dicts"></param>
/// <param name="rootName"></param>
/// <param name="fileName"></param>
void Write(ICollection<IDictionary<string, string>> dicts, string rootName, string fileName);
/// <summary>
/// Appends the information in `dict` to the end of the current file, under the element `elementName`.
/// </summary>
/// <param name="dict">The key-value pairs to append to the file identified by the current URI</param>
/// <param name="elementName">The root of the key-value pairs to append</param>
void Append(IDictionary<string, string> dict, string elementName);
/// <summary>
/// Sets the current URI from which to read.
/// </summary>
/// <param name="uri">Presumed to be in the Data/ directory.</param>
// not generic?
void SetURI(string uri);
/// <summary>
/// Gets the KV for every object of element `elementName`.
/// The search is constrainted to within `ancestor`.
/// </summary>
/// <param name="elementName">The element to look for</param>
/// <param name="ancestor">The element in which to search</param>
/// <returns>(See GetAllOfType)</returns>
ICollection<IDictionary<string, string>> GetAllTypeIn(string elementName, string ancestor);
}
Here is example usage from a WorldState
loading method:
persistentState.SetURI(configURI);
ICollection<IDictionary<string, string>> levelVariantURIDicts = persistentState.GetAllOfType("levelVariant");
// OH YEAH LINQ!!
levelVariantURIs = levelVariantURIDicts.Select(dict => dict["filePath"]).Distinct().ToList();
configURI points here:
<config>
<levelVariant>
<filePath>SampleVariant</filePath>
</levelVariant>
<levelVariant>
<filePath>LegendaryMode</filePath>
</levelVariant>
<levelVariant>
<filePath>AmazingMode</filePath>
</levelVariant>
</config>
What do you think about this? Perhaps the abstraction won't work for a database, but it would for different file types? Maybe I should just hope that the project always uses XML? How can I change this to make it more generic?