The game now launches in the Menu state and loads the corresponding bundle of Nifty GUI designs that take you through the various UI menus to set up a new game, load a game, set options, etc. Upon loading/starting a game, the state machine:
1) initiates a shutDown() method in the current state (Menu) which de-registers all of its listeners from the event manager system
2) confirms shutDown() is complete
3) swaps to the Strategy state (the main game-playing state where you view the stars and everything else) and passes this state the game settings
4) runs a startUp() method for the Strategy state, which registers all of its listeners to the event manager if the state already exists or creates a new Strategy state (generates a new galaxy, stars, etc.).
5) sends an event that tells the elements of the Strategy state (stars, etc.) to enter their default views.
6) and then goes from there.
There's also a Combat state that remains to be implemented and which is only accessible via the Strategy state.
I've made a small modification to my event manager as well. The normal system receives an event and broadcasts it to all the listeners registered for that event. However, there are certain events for which there may be many listeners, only a few of which are affected. For example, adding a new planet to a star system is a possible event in the game and is an action that all star systems listen for. In a 3000 star game, the event manager would have dispatch this event to all 3000 of them so they can figure out if they're the one adding the star or not.
One way around this is to directly access the star that is getting the new planet, circumventing the event manager entirely. But I'm trying to maintain very loose coupling between systems and this violates that rule and opens up the possibility for more problems down the road as the code gets more complex.
As an alternative, I've added in the ability to specify an optional target for an event message. Every game object (physical--planets, stars, etc--and social--empires, religions, etc.) has a long int identifier associated with it, so an event may specify the identifier or a particular object. The event manager will test for an identifier before doing anything and, if it finds one, will send the event directly to the correct target. The tradeoff is maintaining an extra hashmap in the event manager class that links the identifier to an object, but the boost in performance will be worth it for these "many listener" events. Adding stars to a new 3000 star galaxy went from taking 6 seconds to less than 1 second after this change.
Next up, I'm designing planets and other habitable objects.