Speed of calls
Tutorial framework's SceneNode object inherits from Mesh, Texture and other objects. This intuitively seems like a bad idea as one has to make sure different classes don't share member names.
It should speed things up, though, as it doesn't have to make pointer calls to owned Material object.
Solution: elements contain local non-pointer Material object member and copy the passed Material's data.
This can then be called from inside the game loop for real-time material changes.
This does make objects larger, however, whereas before they would simply contain a reference to the same material object and could be all changed by changing the material. This way they'd all have to be set individually.
Composition versus Inheritance
Apparently inheritance of implementation-only things is bad, and composition should be used.
i.e. TestWorld invokes GameEngine object. Is this composition, and is it good?
In my case, I don't think I can get away from efficient custom input callbacks being tied to GLFW as of now, so my inheritance is currently useful and not too complicated. It is a very tight coupling for a reason, I think.
What is composition?
Composition: embedding a member object within a class.
Could have GameEngine take TestGame as a parameter and run it.
Worth a try: GameEngine(GameWorld)
Or rather: GameLoop(GameWorld)
Where GameLoop abstracts away windowing and GameWorld provides the scene, logic and inputs.
GameWorld is virtual and contains Renderer, SceneGraph, ResMan, etc, plus update_all and render_all.
TestWorld inherits GameWorld defines SceneGraph and specific Update stuff.
i.e. "Gameloop has-a world"
In theory GameWorld could composite with TestWorld... Speed is worrisome. This is creating more class-function calls rather than internal methods. Must speed test.
Materials should still use inheritance because it is legitimately combining public properties as an interface. getProgram() is a good base method, but descendants can add extra properties such as colouration and texturing and so on.
i.e. "NewMaterial is-a Material"
"TestWorld is-a GameWorld" - So I reckon inheritance is OK here?
Better: "GameWorld has-a SceneGraph" and TestWorld can use that SceneGraph when it inherits from GameWorld.
How would the scene nodes access the GameWorld key states?
An obvious approach is to pass all key states through scene graph. This would seem unnecessary if only one object is going to handle keys...
So: create keyboard handling object and pass it to interactive object at time of creation. It can access the stuff along with host object GameWorld.
This necessitates the need for a node type which accepts the input object as part of its initialiser list, say: InteractiveNode.
Input Class design:
- Handles keyboard and mouse states.
- GameWorld keeps a copy for the current state to be set by GameLoop.
- GameWorld distributes reference to interactive objects (at object initialisation)
- Objects access reference and perform their own handling.
GameLoop game(GameEnvironment); -> GameLoop needs an environment to loop.
GameEnvironment -> Contains Renderer, Input, SceneGraph objects, as well as Update, Render, Init methods, etc.
Inheritance yields better performance (Composition vs. Inheritance).
Looking at class composition via "delegation" and "method forwarding"
Turns out I was using a sort of "private inheritance" technique for implementation code-reuse. It still may be good for SPEED. Should benchmark.
What I want to do (with regards to composition and delegation) may in fact be known as 'pimpl' (pointer to implementation) or the Chesire Cat idiom.
Looking at the "handle class".
These are good for inherent deconstruction and can be put on stack more efficiently than big objects.