// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 // Standard Library using System; using System.Collections.Generic; // GameKit using AWS.GameKit.Common.Models; using AWS.GameKit.Runtime.Features.GameKitUserGameplayData; using AWS.GameKit.Runtime.Features.GameKitGameSaving; using AWS.GameKit.Runtime.Features.GameKitAchievements; using AWS.GameKit.Runtime.Features.GameKitIdentity; using AWS.GameKit.Runtime.FeatureUtils; using AWS.GameKit.Runtime.Utils; namespace AWS.GameKit.Runtime.Core { /// /// Manager for all GameKit features. /// public class GameKitManager : IDisposable { /// /// The count of how many features are currently being managed by the GameKitManager. /// public int FeatureCount => _features.Count; protected List _features = new List(); private SessionManager _sessionManager = SessionManager.Get(); private bool _disposedValue = false; private bool _isInitialized = false; /// /// Constructs a GameKitManager object. /// /// /// This should only be called from within Unity's main game thread. /// public GameKitManager() { AddFeatures(); } ~GameKitManager() => Dispose(); /// /// Public initializer used to manually initialize feature where required. /// /// When true, forces reinitialization of all features even if they are already initialized. public void EnsureFeaturesAreInitialized(bool reinitialize = false) { if (!_isInitialized || reinitialize) { Logging.LogInfo("GameKitManager: initializing features."); ReloadConfigFile(); // initialize all of the features in list order _features.ForEach(feature => feature.OnInitialize()); _isInitialized = true; } } /// /// Public implementation of Dispose pattern callable by consumers. Used to manually cleanup the GameKitManager. /// public void Dispose() { if (!_disposedValue) { Logging.LogInfo("GameKitManager: cleaning up features."); // cleanup each of the features in reverse list order try { for (int i = _features.Count - 1; i >= 0; --i) { _features[i].OnDispose(); } } finally { _isInitialized = false; } // release the session manager's instance _sessionManager.Release(); _disposedValue = true; } GC.SuppressFinalize(this); } /// /// Public OnApplicationPause method for the GameKitManager, this is intended to be called from a Monbehavior OnApplicationPauseMethod. /// This can be used to notify features that a game instance has been paused or unpaused. /// True if the application is paused, else False. /// public void OnApplicationPause(bool isPaused) { // Notify all features that the application pause status has been changed _features.ForEach(feature => feature.OnApplicationPause(isPaused)); } /// /// Public OnApplicationQuit method for the GameKitManager, this is intended to be called from a Monbehavior OnApplicationQuit. /// This can be used to notify features that a game instance has been quit. /// /// OnApplicationQuit is called in both Standalone and Editor mode unlike Dispose which is only called in Standalone. /// public void OnApplicationQuit() { // Notify all features that the application has been quit _features.ForEach(feature => feature.OnApplicationQuit()); } /// /// Public update method for the GameKitManager, this is intended to only be called during a Monobehavior update or editor update. /// public void Update() { // update each feature _features.ForEach(feature => feature.Update()); } /// /// See SessionManager.ReloadConfig(). /// /// /// This method must be called before using any GameKit feature APIs. /// /// True if every feature's settings are loaded in memory from the "awsGameKitClientConfig.yml" file, false otherwise. public bool ReloadConfigFile() { #if (UNITY_ANDROID || UNITY_IPHONE || UNITY_IOS) && !UNITY_EDITOR _sessionManager.ReloadConfigMobile(); #else _sessionManager.ReloadConfig(); #endif return AreAllFeatureSettingsLoaded(); } /// /// Return true if every feature's settings are loaded in memory from the config file, false otherwise. /// public bool AreAllFeatureSettingsLoaded() { bool result = false; _features.ForEach(feature => { result &= AreFeatureSettingsLoaded(feature.FeatureType); }); return result; } /// /// See SessionManager.AreSettingsLoaded(). /// /// /// These settings are found in file "awsGameKitClientConfig.yml" which is generated by GameKit each time you deploy or re-deploy a feature. /// The file is loaded by calling either SessionManagerWrapper.Create() or SessionManagerWrapper.ReloadConfigFile(). /// /// FeatureType enum that is being checked /// True if the settings for the feature are loaded, false otherwise. public bool AreFeatureSettingsLoaded(FeatureType type) { return _sessionManager.AreSettingsLoaded(type); } #if UNITY_EDITOR /// /// See SessionManager.CopyAndReloadConfig(). /// /// The game's alias, ex: "mygame". /// The environment to copy the config from, ex: "dev". /// True if the "awsGameKitClientConfig.yml" was reloaded successfully, false otherwise. public void CopyAndReloadConfigFile(string gameAlias, string environmentCode) { _sessionManager.CopyAndReloadConfig(gameAlias, environmentCode); #if UNITY_ANDROID _sessionManager.CopyConfigToMobileAssets(gameAlias, environmentCode); #endif } /// /// See SessionManager.DoesConfigFileExist(). /// /// The game's alias, ex: "mygame". /// The environment to copy the config from, ex: "dev". public bool DoesConfigFileExist(string gameAlias, string environmentCode) { return _sessionManager.DoesConfigFileExist(gameAlias, environmentCode); } #endif #if UNITY_EDITOR /// /// Add a feature which is only used inside the Unity editor. This method should only be called by AWS GameKit. Game developers don't need to call this method. /// public void AddEditorOnlyFeature(GameKitFeatureBase feature) { _features.Add(feature); EnsureFeaturesAreInitialized(reinitialize: true); } #endif protected virtual void AddFeatures() { // add features that need to be initialized first _features.Add(Identity.Get()); // add all features, if a feature is not wanted and the DLLs are removed then it should be commented out here as well _features.Add(Achievements.Get()); _features.Add(UserGameplayData.Get()); _features.Add(GameSaving.Get()); } protected void SetSessionManager(SessionManager sessionManager) { _sessionManager = sessionManager; } } }