#region File Description //----------------------------------------------------------------------------- // JoinSessionScreen.cs // // Microsoft XNA Community Game Platform // Copyright (C) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- #endregion #region Using Statements using System; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Net; using Microsoft.Xna.Framework.GamerServices; #endregion namespace NetworkStateManagement { /// /// This menu screen displays a list of available network sessions, /// and lets the user choose which one to join. /// class JoinSessionScreen : MenuScreen { #region Fields const int MaxSearchResults = 8; AvailableNetworkSessionCollection availableSessions; #endregion #region Initialization /// /// Constructs a menu screen listing the available network sessions. /// public JoinSessionScreen (AvailableNetworkSessionCollection availableSessions) : base(Resources.JoinSession) { this.availableSessions = availableSessions; foreach (AvailableNetworkSession availableSession in availableSessions) { // Create menu entries for each available session. MenuEntry menuEntry = new AvailableSessionMenuEntry (availableSession); menuEntry.Selected += AvailableSessionMenuEntrySelected; MenuEntries.Add (menuEntry); // Matchmaking can return up to 25 available sessions at a time, but // we don't have room to fit that many on the screen. In a perfect // world we should make the menu scroll if there are too many, but it // is easier to just not bother displaying more than we have room for. if (MenuEntries.Count >= MaxSearchResults) break; } // Add the Back menu entry. MenuEntry backMenuEntry = new MenuEntry (Resources.Back); backMenuEntry.Selected += BackMenuEntrySelected; MenuEntries.Add (backMenuEntry); } #endregion #region Event Handlers /// /// Event handler for when an available session menu entry is selected. /// void AvailableSessionMenuEntrySelected (object sender, PlayerIndexEventArgs e) { // Which menu entry was selected? AvailableSessionMenuEntry menuEntry = (AvailableSessionMenuEntry)sender; AvailableNetworkSession availableSession = menuEntry.AvailableSession; try { // Begin an asynchronous join network session operation. IAsyncResult asyncResult = NetworkSession.BeginJoin (availableSession, null, null); // Activate the network busy screen, which will display // an animation until this operation has completed. NetworkBusyScreen busyScreen = new NetworkBusyScreen (asyncResult); busyScreen.OperationCompleted += JoinSessionOperationCompleted; ScreenManager.AddScreen (busyScreen, ControllingPlayer); } catch (Exception exception) { NetworkErrorScreen errorScreen = new NetworkErrorScreen (exception); ScreenManager.AddScreen (errorScreen, ControllingPlayer); } } /// /// Event handler for when the asynchronous join network session /// operation has completed. /// void JoinSessionOperationCompleted (object sender, OperationCompletedEventArgs e) { try { // End the asynchronous join network session operation. NetworkSession networkSession = NetworkSession.EndJoin (e.AsyncResult); // Create a component that will manage the session we just joined. NetworkSessionComponent.Create (ScreenManager, networkSession); // Go to the lobby screen. We pass null as the controlling player, // because the lobby screen accepts input from all local players // who are in the session, not just a single controlling player. ScreenManager.AddScreen (new LobbyScreen (networkSession), null); availableSessions.Dispose (); } catch (Exception exception) { NetworkErrorScreen errorScreen = new NetworkErrorScreen (exception); ScreenManager.AddScreen (errorScreen, ControllingPlayer); } } /// /// Event handler for when the Back menu entry is selected. /// void BackMenuEntrySelected (object sender, PlayerIndexEventArgs e) { availableSessions.Dispose (); ExitScreen (); } #endregion } }