UiGameLiftFlexMatchConnect.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <Components/UI/UiGameLiftFlexMatchConnect.h>
  9. #include <AzCore/Serialization/SerializeContext.h>
  10. #include <AzCore/Serialization/EditContext.h>
  11. #include <LyShine/Bus/UiButtonBus.h>
  12. #include <LyShine/Bus/UiCursorBus.h>
  13. #include <LyShine/Bus/UiElementBus.h>
  14. #include <LyShine/Bus/UiTextBus.h>
  15. #include <LyShine/Bus/UiTextInputBus.h>
  16. #include <LyShine/Bus/UiInteractableBus.h>
  17. #include <Multiplayer/Session/SessionRequests.h>
  18. #include <Request/AWSGameLiftRequestBus.h>
  19. #include <Request/AWSGameLiftSessionRequestBus.h>
  20. #include <AzCore/Jobs/JobContext.h>
  21. #include <AzCore/Jobs/JobFunction.h>
  22. #include <Multiplayer/Session/ISessionHandlingRequests.h>
  23. namespace MPSGameLift
  24. {
  25. void UiGameLiftFlexMatchConnect::Reflect(AZ::ReflectContext* context)
  26. {
  27. if (const auto serializeContext = azrtti_cast<AZ::SerializeContext*>(context))
  28. {
  29. serializeContext->Class<UiGameLiftFlexMatchConnect, AZ::Component>()
  30. ->Version(1)
  31. ->Field("ConnectButton", &UiGameLiftFlexMatchConnect::m_connectButtonUi)
  32. ->Field("MatchmakingStatusTextUi", &UiGameLiftFlexMatchConnect::m_matchmakingStatusTextUi)
  33. ->Field("ExitButton", &UiGameLiftFlexMatchConnect::m_quitButtonUi)
  34. ->Field("AttemptConnectionBlockerUi", &UiGameLiftFlexMatchConnect::m_attemptConnectionBlockerUi)
  35. ->Field("ConnectToHostFailedUi", &UiGameLiftFlexMatchConnect::m_connectToHostFailedUi)
  36. ;
  37. if (AZ::EditContext* editContext = serializeContext->GetEditContext())
  38. {
  39. editContext->Class<UiGameLiftFlexMatchConnect>("UiGameLiftFlexMatchConnect", "Component to setup the start menu")
  40. ->ClassElement(AZ::Edit::ClassElements::EditorData, "")
  41. ->Attribute(AZ::Edit::Attributes::Category, "Multiplayer Sample UI")
  42. ->Attribute(AZ::Edit::Attributes::Icon, "Icons/Components/Component_Placeholder.svg")
  43. ->Attribute(AZ::Edit::Attributes::AppearsInAddComponentMenu, AZ_CRC_CE("CanvasUI"))
  44. ->DataElement(AZ::Edit::UIHandlers::Default, &UiGameLiftFlexMatchConnect::m_connectButtonUi, "Connect Button", "The UI button hosting a game (only available for unified launchers which can run as a client-host).")
  45. ->DataElement(AZ::Edit::UIHandlers::Default, &UiGameLiftFlexMatchConnect::m_matchmakingStatusTextUi, "Matchmaking Status Text", "The UI text to display the progress of finding a match after the player presses the connect button.")
  46. ->DataElement(AZ::Edit::UIHandlers::Default, &UiGameLiftFlexMatchConnect::m_quitButtonUi, "Quit Button", "The UI button to quit the app.")
  47. ->DataElement(AZ::Edit::UIHandlers::Default, &UiGameLiftFlexMatchConnect::m_attemptConnectionBlockerUi, "Attempt Connection Blocker", "Fullscreen UI for blocking user input while the client tries to connect.")
  48. ->DataElement(AZ::Edit::UIHandlers::Default, &UiGameLiftFlexMatchConnect::m_connectToHostFailedUi, "Connection To Host Failed", "UI to inform the user that connecting to the host failed.")
  49. ;
  50. }
  51. }
  52. }
  53. void UiGameLiftFlexMatchConnect::Activate()
  54. {
  55. UiCursorBus::Broadcast(&UiCursorInterface::IncrementVisibleCounter);
  56. // Listen for button presses
  57. UiButtonBus::Event(m_quitButtonUi, &UiButtonInterface::SetOnClickCallback, [this](AZ::EntityId buttonEntityId, [[maybe_unused]] AZ::Vector2 position) { OnButtonClicked(buttonEntityId); });
  58. UiButtonBus::Event(m_connectButtonUi, &UiButtonInterface::SetOnClickCallback, [this](AZ::EntityId buttonEntityId, [[maybe_unused]] AZ::Vector2 position) { OnButtonClicked(buttonEntityId); });
  59. UiButtonBus::Event(m_connectToHostFailedUi, &UiButtonInterface::SetOnClickCallback, [this](AZ::EntityId buttonEntityId, [[maybe_unused]] AZ::Vector2 position) { OnButtonClicked(buttonEntityId); });
  60. // Hide the attempting connection ui until the player tries to connect
  61. UiElementBus::Event(m_attemptConnectionBlockerUi, &UiElementInterface::SetIsEnabled, false);
  62. // Listen for disconnect events to know if connecting to the host server failed
  63. AZ::Interface<Multiplayer::IMultiplayer>::Get()->AddEndpointDisconnectedHandler(m_onConnectToHostFailed);
  64. AZ::Interface<IRegionalLatencyFinder>::Get()->AddRequestLatenciesCompleteEventHandler(m_requestLatenciesComplete);
  65. }
  66. void UiGameLiftFlexMatchConnect::Deactivate()
  67. {
  68. m_onConnectToHostFailed.Disconnect();
  69. UiCursorBus::Broadcast(&UiCursorInterface::DecrementVisibleCounter);
  70. }
  71. void UiGameLiftFlexMatchConnect::OnButtonClicked(AZ::EntityId buttonEntityId) const
  72. {
  73. const auto console = AZ::Interface<AZ::IConsole>::Get();
  74. if (!console)
  75. {
  76. AZ_Assert(false, "UiGameLiftFlexMatchConnect attempting to use console commands before AZ::Console is available.");
  77. return;
  78. }
  79. if (buttonEntityId == m_quitButtonUi)
  80. {
  81. console->PerformCommand("quit");
  82. return;
  83. }
  84. if (buttonEntityId == m_connectButtonUi)
  85. {
  86. // Enable blocker ui while we attempt connection
  87. UiElementBus::Event(m_attemptConnectionBlockerUi, &UiElementInterface::SetIsEnabled, true);
  88. UiTextBus::Event(m_matchmakingStatusTextUi, &UiTextInterface::SetText, "Searching for match...");
  89. AZ::Interface<IRegionalLatencyFinder>::Get()->RequestLatencies();
  90. }
  91. if (buttonEntityId == m_connectToHostFailedUi)
  92. {
  93. // Player acknowledged connection failed. Close the warning popup.
  94. UiElementBus::Event(m_connectToHostFailedUi, &UiElementInterface::SetIsEnabled, false);
  95. }
  96. }
  97. void UiGameLiftFlexMatchConnect::OnRequestLatenciesComplete(const RegionalLatencies& regionLatencies)
  98. {
  99. UiTextBus::Event(m_matchmakingStatusTextUi, &UiTextInterface::SetText, "Latencies found...");
  100. AZStd::string latencyPrint;
  101. for (const auto latency : regionLatencies)
  102. {
  103. latencyPrint += AZStd::string::format("%s: %ims\n", latency.first.c_str(), static_cast<uint32_t>(latency.second.count()));
  104. }
  105. UiTextBus::Event(m_matchmakingStatusTextUi, &UiTextInterface::SetText, latencyPrint.c_str());
  106. }
  107. void UiGameLiftFlexMatchConnect::OnConnectToHostFailed()
  108. {
  109. UiElementBus::Event(m_attemptConnectionBlockerUi, &UiElementInterface::SetIsEnabled, false);
  110. UiElementBus::Event(m_connectToHostFailedUi, &UiElementInterface::SetIsEnabled, true);
  111. }
  112. } // namespace MultiplayerSample