123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- #include <GameState/GameStateRequestBus.h>
- #include <GameStateSamples/GameStateLevelLoading.h>
- #include <GameStateSamples/GameStateLevelPaused.h>
- #include <GameStateSamples/GameStateLevelRunning.h>
- #include <GameStateSamples/GameStatePrimaryControllerDisconnected.h>
- #include <GameStateSamples/GameStatePrimaryUserMonitor.h>
- #include <GameStateSamples/GameStatePrimaryUserSignedOut.h>
- #include <LocalUser/LocalUserRequestBus.h>
- ////////////////////////////////////////////////////////////////////////////////////////////////////
- namespace GameStateSamples
- {
- ////////////////////////////////////////////////////////////////////////////////////////////////
- inline void GameStatePrimaryUserMonitor::OnPushed()
- {
- m_primaryControllerDisconnectedWhileLevelLoading = false;
- m_primaryUserSignedOutWhileLevelLoading = false;
- GameState::GameStateNotificationBus::Handler::BusConnect();
- AzFramework::InputDeviceNotificationBus::Handler::BusConnect();
- AzFramework::ApplicationLifecycleEvents::Bus::Handler::BusConnect();
- LocalUser::LocalUserNotificationBus::Handler::BusConnect();
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- inline void GameStatePrimaryUserMonitor::OnPopped()
- {
- LocalUser::LocalUserNotificationBus::Handler::BusDisconnect();
- AzFramework::ApplicationLifecycleEvents::Bus::Handler::BusDisconnect();
- AzFramework::InputDeviceNotificationBus::Handler::BusDisconnect();
- GameState::GameStateNotificationBus::Handler::BusDisconnect();
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- inline void GameStatePrimaryUserMonitor::OnActiveGameStateChanged(AZStd::shared_ptr<IGameState> oldGameState,
- [[maybe_unused]] AZStd::shared_ptr<IGameState> newGameState)
- {
- if (m_primaryUserSignedOutWhileLevelLoading &&
- azrtti_istypeof<GameStateLevelLoading>(oldGameState.get()))
- {
- // The primary user signed out while a level was loading,
- // we had to wait until the level finished loading before
- // transitioning to the primary user signed out game state.
- m_primaryUserSignedOutWhileLevelLoading = false;
- m_primaryControllerDisconnectedWhileLevelLoading = false;
- PushPrimaryUserSignedOutGameState();
- return;
- }
- if (m_primaryControllerDisconnectedWhileLevelLoading &&
- azrtti_istypeof<GameStateLevelLoading>(oldGameState.get()))
- {
- // The controller disconnected while a level was loading,
- // we had to wait until the level finished loading before
- // transitioning to the controller disconnected game state.
- m_primaryControllerDisconnectedWhileLevelLoading = false;
- PushPrimaryControllerDisconnectedGameState();
- return;
- }
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- inline void GameStatePrimaryUserMonitor::OnInputDeviceConnectedEvent(const AzFramework::InputDevice& inputDevice)
- {
- const AzFramework::LocalUserId primaryLocalUserId = LocalUser::LocalUserRequests::GetPrimaryLocalUserId();
- if (m_primaryControllerDisconnectedWhileLevelLoading &&
- primaryLocalUserId == inputDevice.GetAssignedLocalUserId())
- {
- // The controller disconnected while a level was loading,
- // but was reconnected before the level finished loading.
- m_primaryControllerDisconnectedWhileLevelLoading = false;
- }
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- inline void GameStatePrimaryUserMonitor::OnInputDeviceDisconnectedEvent(const AzFramework::InputDevice& inputDevice)
- {
- const AzFramework::LocalUserId primaryLocalUserId = LocalUser::LocalUserRequests::GetPrimaryLocalUserId();
- if (primaryLocalUserId != inputDevice.GetAssignedLocalUserId() ||
- primaryLocalUserId == AzFramework::LocalUserIdNone)
- {
- // The disconnected controller does not belong to the primary user,
- // or the primary user has not yet been set.
- return;
- }
- if (GameState::GameStateRequests::IsActiveGameStateOfType<GameStateLevelLoading>())
- {
- // The controller disconnected while a level is loading;
- // we have to wait until the level has finished loading.
- m_primaryControllerDisconnectedWhileLevelLoading = true;
- return;
- }
- PushPrimaryControllerDisconnectedGameState();
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- inline void GameStatePrimaryUserMonitor::OnApplicationUnconstrained(AzFramework::ApplicationLifecycleEvents::Event /*lastEvent*/)
- {
- const AzFramework::LocalUserId primaryLocalUserId = LocalUser::LocalUserRequests::GetPrimaryLocalUserId();
- if (primaryLocalUserId == AzFramework::LocalUserIdNone)
- {
- // The primary user has yet to be set
- m_primaryUserSignedOutWhileLevelLoading = false;
- return;
- }
- bool isPrimaryLocalUserSignedIn = false;
- LocalUser::LocalUserRequestBus::BroadcastResult(isPrimaryLocalUserSignedIn,
- &LocalUser::LocalUserRequests::IsLocalUserSignedIn,
- primaryLocalUserId);
- if (isPrimaryLocalUserSignedIn)
- {
- // The primary user is still signed in
- m_primaryUserSignedOutWhileLevelLoading = false;
- return;
- }
- if (GameState::GameStateRequests::IsActiveGameStateOfType<GameStateLevelLoading>())
- {
- // The primary user signed out while a level is loading;
- // we have to wait until the level has finished loading.
- m_primaryUserSignedOutWhileLevelLoading = true;
- return;
- }
- PushPrimaryUserSignedOutGameState();
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- inline void GameStatePrimaryUserMonitor::OnLocalUserSignedIn(AzFramework::LocalUserId localUserId)
- {
- const AzFramework::LocalUserId primaryLocalUserId = LocalUser::LocalUserRequests::GetPrimaryLocalUserId();
- if (m_primaryUserSignedOutWhileLevelLoading &&
- primaryLocalUserId == localUserId)
- {
- // The primary user signed out while a level was loading,
- // but signed in again before the level finished loading.
- m_primaryUserSignedOutWhileLevelLoading = false;
- }
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- inline void GameStatePrimaryUserMonitor::OnLocalUserSignedOut(AzFramework::LocalUserId localUserId)
- {
- const AzFramework::LocalUserId primaryLocalUserId = LocalUser::LocalUserRequests::GetPrimaryLocalUserId();
- if (primaryLocalUserId != localUserId ||
- primaryLocalUserId == AzFramework::LocalUserIdNone)
- {
- // The user that signed out is not the primary user,
- // or the primary user has not yet been set.
- return;
- }
- if (GameState::GameStateRequests::IsActiveGameStateOfType<GameStateLevelLoading>())
- {
- // The primary user signed out while a level is loading;
- // we have to wait until the level has finished loading.
- m_primaryUserSignedOutWhileLevelLoading = true;
- return;
- }
- PushPrimaryUserSignedOutGameState();
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- inline void GameStatePrimaryUserMonitor::PushPrimaryControllerDisconnectedGameState()
- {
- if (GameState::GameStateRequests::DoesStackContainGameStateOfType<GameStatePrimaryControllerDisconnected>() ||
- GameState::GameStateRequests::DoesStackContainGameStateOfType<GameStatePrimaryUserSignedOut>())
- {
- // The controller disconnection has already been detected,
- // or the primary user signed out (which takes precedence).
- return;
- }
- // Ensure the game is paused if needed before pushing the controller disconnected game state
- TryPushLevelPausedGameState();
- GameState::GameStateRequests::CreateAndPushNewOverridableGameStateOfType<GameStatePrimaryControllerDisconnected>();
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- inline void GameStatePrimaryUserMonitor::PushPrimaryUserSignedOutGameState()
- {
- if (GameState::GameStateRequests::DoesStackContainGameStateOfType<GameStatePrimaryUserSignedOut>())
- {
- // The primary user sign out has already been detected
- return;
- }
- if (GameState::GameStateRequests::IsActiveGameStateOfType<GameStatePrimaryControllerDisconnected>())
- {
- // The primary user signing out takes precedence over their controller being disconnected
- GameState::GameStateRequestBus::Broadcast(&GameState::GameStateRequests::PopActiveGameState);
- }
- // Ensure the game is paused if needed before pushing the primary user signed out game state
- TryPushLevelPausedGameState();
- GameState::GameStateRequests::CreateAndPushNewOverridableGameStateOfType<GameStatePrimaryUserSignedOut>();
- }
- ////////////////////////////////////////////////////////////////////////////////////////////////
- inline void GameStatePrimaryUserMonitor::TryPushLevelPausedGameState()
- {
- if (GameState::GameStateRequests::DoesStackContainGameStateOfType<GameStateLevelPaused>() ||
- !GameState::GameStateRequests::DoesStackContainGameStateOfType<GameStateLevelRunning>())
- {
- // The game has already been paused or is not actively running yet
- return;
- }
- GameState::GameStateRequests::CreateAndPushNewOverridableGameStateOfType<GameStateLevelPaused>();
- }
- }
|