The main engine contains a stack of modes which use an abstract interface to implement stuff like Physics, Render, OnKeyDown etc. The engine can push and pop modes on this stack and calls the Physics and Render methods etc of the top mode at the appropriate times.
This has moved all the messy timing code out of the modes, plus it keeps the different modes very seperate which I hope will pay off in the long run.
There is also a global std::list of messages available to the engine and all the different modes. Any part of the program can enqueue a message into this list. Each message has a type and a delay.
Each physics step, outside of the modes in the main engine loop, the physics delta is subtracted from all waiting messages' delay value. When a message becomes due for action, the engine examines its type and either acts upon it or passes it back down to the current mode. It also then marks the message as invalid.
After each of these runs through the message list, the engine then runs through and deletes any that have been marked invalid. The point of this system is that during response to a message, it may be needed to invalidate either some or all of the messages in the list. Trying to clear the list from within a stack of functions that have been called during an iteration through the list is a nightmare. This system avoids any complexity in that respect at the cost of having two iterations through the list instead of one. I wouldn't expect there to be ever more than 10-15 messages in the list at any time.
The actual mode stack is implemented by giving the base mode a Next pointer. Don't swear at me, there is method to my madness:
Firstly, there is no real need for an external container to manage the mode stack since the only operations ever performed externally are push and pop (and clear, but that is just a sequence of pops really).
Secondly, this method means each mode can "see" its parent node via its own Next pointer.
The idea is that I can exploit this relationship. the TitleMode and GameMode modes will not reference their parents. However, the MenuMode will be able to be pushed on top of either the TitleMode or the GameMode. So at the start of MenuMode's Render call, it can just call Next->Render(...) before it Renders itself. Same with the Physics() call. This gives each Mode the ability to decide for itself whether to allow physics or rendering for its parent Mode.
This is a bit experimental and I'm not sure how well it will work but I think the principle is quite sound.
The nice thing about the mode stack and the delayed messaging system is that during, say, the GameMode, you can at any point do:
and then forget all about it and carry on with normal execution. Three seconds later, the game mode will pop off the stack, the mode underneath is given the opportunity to restore itself and then becomes the current mode for physics and rendering. None of this interferes in any way with the normal flow of execution during the rest of the GameMode.
Hopefully it will work as well as I imagine. We shall see.