mono/MonoGame — pull request #178 by kungfubanana (2011-12-27 03:22:17+00:00)
Title: Unified Game class (and other things)

### Goals

1. Consolidate duplicated logic in platform-specific Game classes into a single class.
2. Abstract platform-specific details into a new GamePlatform class with per-platform implementations (see: [Strategy Pattern](http://en.wikipedia.org/wiki/Strategy_pattern))
3. Full support for IDrawable.DrawOrder and IUpdateable.UpdateOrder.
4. Full support for adding and removing GameComponents during an Update cycle.
5. More robust support for platforms that prefer asynchronous run loops (all platforms but Windows).

### Rationale

The desire for these changes arose primarily out of a need for (3) and (4). However, the complexity involved in creating a robust and efficient mechanism led to a desire to reduce existing logic duplication and avoid introducing new duplicated logic, thus (1) and (2).

### Details

A great deal of shared functionality between the per-platform Game classes has now been consolidated into a single, shared Game class. Hooks into platform-specific functionality are provided via per-platform implementations of the GamePlatform abstract base class.

A specialized collection, SortingFilteringCollection\, has been introduced to the Game class to manage and synchronize typed lists (IDrawable and IUpdateable) of components. This collection class processes adds and removes via journaling to allow simultaneous enumeration of "last frame's" items and modification of "next frame's" items.

Game.Run has been overloaded with an out-of-XNA-API version that takes a GameRunBehavior (Asynchronous or Synchronous) to specify which type of run loop should be executed. The normal, zero-argument version of Game.Run, queries GamePlatform for the default run loop behavior of that platform. Currently, all platforms except Windows are asynchronous-only and Windows is synchronous-only. But in principal, most platforms could be extended to support both modes.

### Caveats

1. This is a large patch. In the end, it seemed easier to get the unification effort over with in one shot, rather than try to break it up artificially. Still, the size seems regrettable.
2. As with any sweeping change, regressions have undoubtedly been introduced. We'll be working through these issues as they are discovered, of course, and adding automated tests to help with new regressions in the future.
3. There is a known regression with window/viewport initialization and size changes. More work needs to be done to ensure that the GraphicsDevice parameters and the actual size of the render surface are kept synchronized.
4. More work can be done to reduce some awkwardness that remains in the Game/GamePlatform interaction.
5. Game can be Disposed prematurely, especially on asynchronous platforms, but it does not yet provide any feedback that it is being used after having been Disposed. This is noticeable when running samples from the [sample project](https://github.com/CartBlanche/MonoGame-Samples). (This issue was present before, but the effects are now more pronounced.)

### Miscellany

In the process of doing tests against the [sample project](https://github.com/CartBlanche/MonoGame-Samples), a number of possibly-unrelated changes have been made. Briefly:

1. iOS VideoPlayer now presents itself using a parent view controller. There may be backward-compatibility ramifications here.
2. Linux EffectPass now checks for shader4 support in EXT and ARB before calling the plain-GL version (which still may result in an exception if support is not available)
3. Added an 80-column copy of the Ms-PL to the root of the project, for reference and ease of duplication.