// 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;
}
}
}