The application is built with a classical MVVM approach in mind. The three layers are packed in three folders and will soon be moved to separate DLLs: (The “Data” folder contains serialized data (XMLs) that will be loaded by the application during start up – list of computer models, list of names etc.)
Since I have a couple of other games of the same style in mind, I would like to reuse as much as possible from this game: The idea of a central “system”, the model object, view model object, the idea of “managers” handling a list of model objects, are all pretty generic concepts.
This is the basic model system that shall serve as a basis for games of this kind:
The model is self-contained, that means that it can exist and run without the view model layer.
The central part of the system is ModelSystem. It contains a List of SystemManagers which in turn contain lists (ObservableCollections) of ModelObjects. ModelSystem itself does not create any managers – that’s done by derived (specialized) manager classes – but it forwards calls to the managers (Update(), Init() etc.).
(Visual Studio is not able to display generic classes properly. There should actually be a line drawn from the SystemManager<T> class to the ModelObject class because SystemManager<T> actually contains an ObservableCollection<T> of model objects named Objects. It also contains a second list with the same type named ActiveObjects that holds the objects that are currently active in the game, while the Objects list holds all objects, even those that will be activated later and are not present in the game yet.)
The ObservableObject class implements INotifyPropertyChanged and contains the PropertyChanged handling and a generic SetProperty<T>() method to handle the setting of properties and the notifications.
ModelObject is the base class for (almost) all model objects and it derives from ObservableObject, inheriting the ability to send notifications when properties change.
ViewModelObject (which is in another layer) also derives from ObservableObject and uses the same mechanism for notifications. ViewModelObject also holds an (optional) reference to a model object that it works with. A lot of view models operate on exactly one model object; the view model to display a computer model for example operates on the model object ComputerModel; the view model basically transfers model properties from ComputerModel to the view (formatting them on the way) and almost all properties are actually “passthrough properties”. (There should be a simple mechanism to declare view model properties as “get the value from the corresponding model property” without having to do all this manually.)
The ModelSystem class also contains a localizer object that is mainly responsible for formatting values from the model (numbers, date etc.) into the required representation for the specified language. This object is set from the derived model system class (ATBModelSystem in this case) via the constructor (dependency injection):
public ATBModelSystem(IModelMessage modelMessageHandler, bool createTestData)
: base(modelMessageHandler, new LocalizerEN())
Last but not least the ModelSystem class gets an IModelMessage implementation that allows it to send messages to the view model without knowing of it. (The view model system class is actually the implementation of the interface allowing the view model to intercept messages from the model.) For now I’m not using normal events for other notifications than PropertyChanged events; if not used properly they tend to cause memory leaks in the long run.
(As I already stated: I’m trying different concepts to see what advantages and disadvantages they have. Creating an architecture without using ordinary C# events – except PropertyChanged – is at least worth a try…)
The game’s main page you can find here: All Those Bugs Page