I use the composite state for big things like total game state where the collection of app states between those major game states (major being like the difference between single and multi-player) need to be kept and managed together. There are occasionally times where I guess I might use them to group nested app states together, too, but I can’t think of a case off the top of my head.
Normally, composite app state is very straight-forward:
-attached: all children are attached (note: this is not the same as initialized()… the state manager will call that as appropriate… which means the parent always gets initialized first because it was attached first)
-detached: all children are detached
-enabled: by default, all children are enabled
-disabled: by default, all children are disabled.
Children can optionally be added in such a way that their own enabled/disabled state is SOMEWHAT independent of the parent’s. If the parent is enabled then the child can be enabled/disabled independently. If the parent is disabled, all children are always disabled… but the ‘independent’ ones will remember their enabled/disabled state for the next time the parent is enabled.
Basically, if you have a child that will want to be disabled and enabled while the parent is active then you then you can call: setOverrideEnabled( AppState state, boolean override ) with ‘true’. Or you can add the child overridden with: addChild( T state, boolean overrideEnable ).
CompositeAppState is part of my SiO2 library and so is available to anyone.
You can see in the examples that I use this feature in several cases like in GameSessionState:
addChild(new InGameMenuState(false), true);
addChild(new CommandConsoleState(), true);
// For popping up a time sync debug panel
addChild(new TimeSequenceState(), true);
addChild(new HelpState(), true);
addChild(new PlayerListState(), true);
Where all of the various in-game popups have their enabled state managed separately.
Whether you choose to enable/disable a state or attach/detach it is really up to you, though. Mostly, if a state is going to cache some stuff (like UI panels, etc.) then it’s better to let it stay attached for as long a life as makes sense and then use enable/disable to activate it. And if your intent is to hook it to a hot-key then that’s kind of vital. initialize/cleanup can be used to register a mapping to enable/disable on the hot key.