JoinSessionScreen.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. //-----------------------------------------------------------------------------
  2. // JoinSessionScreen.cs
  3. //
  4. // Microsoft XNA Community Game Platform
  5. // Copyright (C) Microsoft Corporation. All rights reserved.
  6. //-----------------------------------------------------------------------------
  7. using System;
  8. using Microsoft.Xna.Framework;
  9. using Microsoft.Xna.Framework.Net;
  10. using Microsoft.Xna.Framework.GamerServices;
  11. namespace NetworkStateManagement
  12. {
  13. /// <summary>
  14. /// This menu screen displays a list of available network sessions,
  15. /// and lets the user choose which one to join.
  16. /// </summary>
  17. class JoinSessionScreen : MenuScreen
  18. {
  19. const int MaxSearchResults = 8;
  20. AvailableNetworkSessionCollection availableSessions;
  21. /// <summary>
  22. /// Constructs a menu screen listing the available network sessions.
  23. /// </summary>
  24. public JoinSessionScreen(AvailableNetworkSessionCollection availableSessions)
  25. : base(Resources.JoinSession)
  26. {
  27. this.availableSessions = availableSessions;
  28. foreach (AvailableNetworkSession availableSession in availableSessions)
  29. {
  30. // Create menu entries for each available session.
  31. MenuEntry menuEntry = new AvailableSessionMenuEntry(availableSession);
  32. menuEntry.Selected += AvailableSessionMenuEntrySelected;
  33. MenuEntries.Add(menuEntry);
  34. // Matchmaking can return up to 25 available sessions at a time, but
  35. // we don't have room to fit that many on the screen. In a perfect
  36. // world we should make the menu scroll if there are too many, but it
  37. // is easier to just not bother displaying more than we have room for.
  38. if (MenuEntries.Count >= MaxSearchResults)
  39. break;
  40. }
  41. // Add the Back menu entry.
  42. MenuEntry backMenuEntry = new MenuEntry(Resources.Back);
  43. backMenuEntry.Selected += BackMenuEntrySelected;
  44. MenuEntries.Add(backMenuEntry);
  45. }
  46. /// <summary>
  47. /// Event handler for when an available session menu entry is selected.
  48. /// </summary>
  49. void AvailableSessionMenuEntrySelected(object sender, PlayerIndexEventArgs e)
  50. {
  51. // Which menu entry was selected?
  52. AvailableSessionMenuEntry menuEntry = (AvailableSessionMenuEntry)sender;
  53. AvailableNetworkSession availableSession = menuEntry.AvailableSession;
  54. try
  55. {
  56. // Begin an asynchronous join network session operation.
  57. var networkSession = NetworkSession.JoinAsync(availableSession);
  58. // Activate the network busy screen, which will display
  59. // an animation until this operation has completed.
  60. NetworkBusyScreen busyScreen = new NetworkBusyScreen(networkSession);
  61. busyScreen.OperationCompleted += JoinSessionOperationCompleted;
  62. ScreenManager.AddScreen(busyScreen, ControllingPlayer);
  63. }
  64. catch (Exception exception)
  65. {
  66. NetworkErrorScreen errorScreen = new NetworkErrorScreen(exception);
  67. ScreenManager.AddScreen(errorScreen, ControllingPlayer);
  68. }
  69. }
  70. /// <summary>
  71. /// Event handler for when the asynchronous join network session
  72. /// operation has completed.
  73. /// </summary>
  74. void JoinSessionOperationCompleted(object sender, OperationCompletedEventArgs e)
  75. {
  76. try
  77. {
  78. // Use the result directly from the event args.
  79. NetworkSession networkSession = e.Result as NetworkSession;
  80. if (networkSession == null)
  81. throw new InvalidOperationException("NetworkSession result was null or invalid.");
  82. // Create a component that will manage the session we just joined.
  83. NetworkSessionComponent.Create(ScreenManager, networkSession);
  84. // Go to the lobby screen. We pass null as the controlling player,
  85. // because the lobby screen accepts input from all local players
  86. // who are in the session, not just a single controlling player.
  87. ScreenManager.AddScreen(new LobbyScreen(networkSession), null);
  88. availableSessions.Dispose();
  89. }
  90. catch (Exception exception)
  91. {
  92. NetworkErrorScreen errorScreen = new NetworkErrorScreen(exception);
  93. ScreenManager.AddScreen(errorScreen, ControllingPlayer);
  94. }
  95. }
  96. /// <summary>
  97. /// Event handler for when the Back menu entry is selected.
  98. /// </summary>
  99. void BackMenuEntrySelected(object sender, PlayerIndexEventArgs e)
  100. {
  101. availableSessions.Dispose();
  102. ExitScreen();
  103. }
  104. }
  105. }