Ion Core Game and Render Engine Documentation
Comments are questions? Discord
Application

The Application class manages all Resources, ServiceLocator, Windows
and Scenes.
The main game loop is also run by this class but does nothing more
than handling Windows messages. The parts of the traditional game
loop are run in independent threads handled by the scene class.
ResourceManager

The ResourceManager holds all resources and makes sure you don't
load a resource twice in memory. It also keeps a counter on the
usage.
I'm thinking on adding a ResourceManager to a Scene instance (now
it's only per Application) and maybe also per Cube, so if you remove
a scene/cube all of it's resources are removed as well.
Scene

Multiple Scenes can run at the same time.
Scene holds all SceneThreads. They are the gameloop contents and run
"independent" and timing can be set per SceneThread.
As the different SceneThreads are working on the same data, mutexes
are used to protect data (from inconsistent read/write). More
details on that later
A scene has all the objects:
Object (or ComponentManager)

Objects belong to a scene and are just a container of components.
They can have parent/child objects but this should be avoided if
possible as it will impact performance.
There is a split in the traditional component model (Model, View,
Controller), because they are accessed separately in the
SceneThreads.
A direct link to TransformMC is kept for performance reasons (I
might be guilty against the "Premature optimization is the root of
all evil" rule).
The full hierarchical model of Components:
Component hierarchy

Try not to get confused on ModelC and MeshModelVC, the first one
refers to Model in the Model-View-Controller design pattern, the
second one is a 3d model/mesh.
Another design pattern here is in ReceiverMC, the Command pattern.
Cubes

"Cubes" are a first and important optimization towards large Scenes,
or even OpenWorld games.
The different Component types have different Cube properties (xyz
size of cube, inactive distance, lod, ...)
Examples:
Render is only for ViewC Cubes in front of the Camera and the
distance from the Camera to the Cube is passed to the Render
function to be used as LOD.
For ModelC and ControllerC there can be multiple Camera's, which is
taken into account and Update() is only called if for Cube
Components within a certain distance from the Camera's
As there normally are very few objects moving in a Game, I chose for
the std::vector container to store the pointer to the Components in
the Cube and if an Object moves out of a cube the mHasMoved is set
in the old one.
The list of Cubes is actually a std::multimap container. For the
moment this is fast enough. A graph could be used but has it's
disadvantages as well.
Command
Gameloop Threads
ControllerST

ControllerST holds all input & AI. Input needs to be registered
and works with Command pattern.
The Inner loop gets keyboard input (mouse & gamepad will be
added in the near future), then goes over all the Scene Objects,
which in turn calls update() on all it's Controller Components.
It holds a share lock on all Scene Objects while doing this. Other
threads do the same, so they can all run at the same time. The only
exception is the ModelST, which takes an exclusive lock during
Switch() on Model Components. More on that later.
ModelST

ModelST updates your object's data (like TransformMC, which holds
position and rotation).
The inner loop goes over all the Scene Objects, which in turn calls
Update() on all it's Model Components.
It holds a share lock on all Scene Objects while doing this.
Then it goes over all objects again and calls Switch(), which
switches the buffer of the ModelC (More on double buffering later).
For this it holds an exclusive lock on all objects.
ViewST

The ViewST inner loop works somewhat different.
It first does an Update() on all ViewC's belonging to a
Canvas/Material (Rendered Cubes only)
For the actual Rendering, it calls the Scene Render().
The Scene Render() sends a signal using a condition variable to the
Canvas to start Rendering. So multiple Canvases render
simultaneously.
The Canvas Render Thread goes over all Materials. The material has a
list of ViewCCubes. Only the Cubes in front of the Camera are being
Rendered (ViewC's Render() function)
The rendering could be reworked to a render thread pool which
processes these Cubes.
If a component needs information from another component of the same
object, the component has a reference to the object and can thus ask
for that information.
mpObject->GetModelC<TransformMC>()->GetWorld()
ServiceLocator

Audio is not implemented in the engine because of license
restrictions. There's an example though in the Test project.
StatsWriter is still work in progress.
More coming soon on materials and shaders, physics, ...