   Parallel menu manager
  I'm making a coop game and I'm starting with the menu system.Here is what I have so far:- Every frame the InputManager pool the 4 xbox360 controllers, when the state of a button changes, I add the event to a list.- I have a FocusManager that stores in a stack InputEventHandlers. For example: I have a menu that reacts when I 'Press' 'DPadUp' and I should call it's 'MoveUp' method. Also one of the menu's item reacts to the 'Press' of button 'A' to do something.- When an object (inherits from BaseFocusable) receive the focus, it pushes it's InputEventHandlers to the FocusManager's stack. For example: if I focus my menu, it will push MoveUp and MoveDown and will automatically give the focus to it's first menu item, witch would push an InputEventHandler for the A button.- When an object lose the focus, I pop all InputEventHandlers from the top of the stack to the item that lost the focus. So if I unfocus a menu, any child menu item will be unfocused.- Every frame I update the FocusManager and look from the top of the stack (it's actually only a List<>) if I can find something that match the Button and ButtonState from the events the InputManager generated and call the handler.This all work great. But at the beginning of a match, both players will be able to choose their character, their loadout from a set of unlocked weapons, spells and armors, change some player specific options, like the controller options...Most game I have seen work like the first to press a button controls the menu, while the other players have to wait. I'd like to have a menu system that can manage parallel paths. So I could push/pop screens for all players or a single one. I thought of a stack that can split into branches like a tree where the key of a node would be a bitfield of controller index. It looks a bit complex to implement properly.How would you implement something like this?Any help would be appreciated.[Edited by - Iarus on July 29, 2009 5:17:20 PM]
  Before you implement, you have to design. For instance, what do you want to happen if player A clicks on "Select weapon" and player B clicks on "Select character" ? Do you show the weapon selection screen ? The character selection screen ? Both as split-screen ? Do you prevent multiple players from acting on menus where sub-menus exist ? Your decision impacts how the menus will be implemented.   ;  short answer : split screenIf player A has the controller 1 and player B the controller 2Main Menu {1,2,3,4}  [Play] => goto Select Map  [Non-Player Specific Options]  [Quit]Select Map {1,2,3,4}  [Map 1] \    [Map 2] -=> goto Lobby  [Map n] /Lobby (split screen)(Screen of the player  | (Screen for an other player) who selected the map) |{1}|   {2,3,4}  [Select Character]   |   [Join] => goto Select Character,   [Select Weapon] |   Weapon, ... and is now controlled by {2}  [Select other stuff] |  [Player Specific Options] |  [Ready]    | Info   |  - Current Character  |  - Current Primary Weapon  |  - Current Secondary Weapon|  - ... |When a player select 'Select Character', that screen would be pushed on that player's stack, while the other can join, unjoin, select his weapons, do whatever he wants. So I could have this :   Lobby Player A| Player B Select Weapon| Select Character   [Weapon 1] |   [Char 1]   [Weapon 2] |   [Char 2]   [Weapon n] |   [Char n]From there if a player press (B) their screen be popped and he'll go back to the LobbyIf player A is in the Lobby and he presses back, both players will be brought back to the 'Select Map' screen   ;  It sounds like you're putting a lot more effort into something that should remain as simple as possible.Assuming you have all 4 players connected all you need to do is have 4 screens visible in their own areas of the monitor. During each update the core program calls the update on each of these screens. Each screen can then check its appropriate controller for whether a button is pressed and perform the necessary action or call a function in another class to perform the event.I'm not sure if you're using XNA, I would assume you would as you're developing for the 360, if not then my first step would be to try and make a system where you can do the above. I'd question the need for all these event lists when the screen themselves could do all the work for you.I've recently created my own little windows based gui system for xna which is very simple and quick to setup a new screen and define new actions in.You start off with a base Screen class along with a Screen Manager, the SM determines which screens are active. Each individual screen inherits the base Screen class and sets the buttons, drop down boxes, images etc of the parent in the child constructor. The parent runs through its list of buttons etc and then calls a DoAction(string ID) method which takes the ID of the button and uses a switch statement to find the correct action for it. The DoAction method is overridden in each child so each screen can specify different actions for different events. Each child screen also has its own update method which is called from the base update method which can look out for things like controller pad buttons being pressed and so on.I mightn't be explaining it great atm, it's 3.30am but it really is very simple and easy to work with once you get it done.   ;  flexible and complex are cool, but simple is better...I've implemented a solution that is simple and works well using what I already had.So I have a ScreenManager that can push and pop Screens to it's stack. And a Screen holds a reference to it's parent ScreenManager.I've created a LobbyScreen that has 2 ScreenManagers, and I push a screen in each of them. Now it looks like my screen stack has 2 sub stacks.When one player wants to exit the first screen from their "own private" ScreenManager, instead of poping just that one screen, I tell the lobby screen to pop all screens from both sub-ScreenManager, then I pop the lobby from the main ScreenManager.Instead of 2 ScreenManagers, I could have a List of ScreenManager for more flexibility.For the input events, I still use the FocusManager, and like with the ScreenManager, the lobby owns 2 FocusManagers and 2 bitfields that holds info about witch controllers those sub-FocusManagers should care about.When I enter the lobby, I tell the main FocusManager to redirect events to the others if the controller index of the event match the bitfield.When I exit the lobby, I tell the main FocusManager to stop redirecting events.   