Mark Joshwel
872f3f263e
generally found - Awake -> init - OnEnable -> init + register callbacks - Start -> do anything that might call a callback
150 lines
No EOL
5.4 KiB
C#
150 lines
No EOL
5.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
|
|
/// <summary>
|
|
/// singleton for a single source of truth game state and flow management
|
|
/// </summary>
|
|
public class GameManager : MonoBehaviour
|
|
{
|
|
/// <summary>
|
|
/// singleton pattern: define instance field for accessing the singleton elsewhere
|
|
/// </summary>
|
|
public static GameManager Instance;
|
|
|
|
/// <summary>
|
|
/// ui manager object for handling ui state and flow
|
|
/// </summary>
|
|
public UIManager ui;
|
|
|
|
/// <summary>
|
|
/// the local player data object for storing player data
|
|
/// </summary>
|
|
private LocalPlayerData _data;
|
|
|
|
/// <summary>
|
|
/// read-only property for accessing the local player data outside of this class
|
|
/// </summary>
|
|
public LocalPlayerData Data => _data;
|
|
|
|
/// <summary>
|
|
/// list of callbacks to call when the local player data changes
|
|
/// </summary>
|
|
private readonly List<Action<LocalPlayerData>> _onLocalPlayerDataChangeCallbacks = new List<Action<LocalPlayerData>>();
|
|
|
|
/// <summary>
|
|
/// backend object for handling communication with the firebase backend
|
|
/// </summary>
|
|
public Backend Backend;
|
|
|
|
/// <summary>
|
|
/// enforces singleton behaviour; sets doesn't destroy on load and checks for multiple instances
|
|
/// </summary>
|
|
private void Awake()
|
|
{
|
|
// check if instance hasn't been set yet
|
|
if (Instance == null)
|
|
{
|
|
Debug.Log("awake as singleton instance, setting self as the forever-alive instance");
|
|
Instance = this;
|
|
DontDestroyOnLoad(gameObject);
|
|
}
|
|
// check if instance is already set and it's not this instance
|
|
else if (Instance != null && Instance != this)
|
|
{
|
|
Debug.Log("awake as non-singleton instance, destroying self");
|
|
Destroy(gameObject);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// called when the game object is enabled, initialises variables
|
|
/// </summary>
|
|
private void OnEnable()
|
|
{
|
|
ui = UIManager.Instance;
|
|
|
|
// load the local player data and refresh the ui
|
|
_data = new LocalPlayerData();
|
|
|
|
Backend = new Backend();
|
|
Backend.Initialise(status =>
|
|
{
|
|
Debug.Log("initialised backend, setting connection status text");
|
|
|
|
ui.UI.Q<Label>("ConnectionStatusText").text = status switch
|
|
{
|
|
Backend.FirebaseConnectionStatus.Connected => "Status: Connected",
|
|
Backend.FirebaseConnectionStatus.Updating => "Status: Updating... (Retrying in a bit!)",
|
|
Backend.FirebaseConnectionStatus.NotConnected => "Status: Disconnected",
|
|
Backend.FirebaseConnectionStatus.UpdateRequired =>
|
|
"Status: Disconnected (Device Component Update Required)",
|
|
Backend.FirebaseConnectionStatus.ExternalError => "Status: Disconnected (External/Device Error)",
|
|
Backend.FirebaseConnectionStatus.InternalError => "Status: Disconnected (Internal Error)",
|
|
_ => "Status: Disconnected (unknown fcs state, this is unreachable and a bug)"
|
|
};
|
|
|
|
if (status == Backend.FirebaseConnectionStatus.Connected) return;
|
|
|
|
// if we're not connected, hide any online 'features'
|
|
ui.UI.Q<Button>("LeaderboardButton").style.display = DisplayStyle.None;
|
|
ui.UI.Q<Button>("AccountButton").style.display = DisplayStyle.None;
|
|
});
|
|
|
|
// register a callback to refresh the ui when the player signs in
|
|
Backend.RegisterOnSignInCallback(_ =>
|
|
{
|
|
Debug.Log("sign in callback, refreshing GameManager-controlled SideView UI");
|
|
_data.LoadFromTheWorld(FireLocalPlayerDataChangeCallbacks);
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// load in stuff
|
|
/// </summary>
|
|
private void Start()
|
|
{
|
|
Debug.Log("GameManager starts here");
|
|
_data.LoadFromTheWorld(FireLocalPlayerDataChangeCallbacks);
|
|
}
|
|
|
|
/// <summary>
|
|
/// called when the application is quitting, saves the local player data
|
|
/// </summary>
|
|
private void OnApplicationQuit()
|
|
{
|
|
Debug.Log("running deferred cleanup/save functions");
|
|
Backend.Cleanup();
|
|
_data.SaveToTheWorld();
|
|
}
|
|
|
|
/// <summary>
|
|
/// function to register a callback to be called when the local player data changes
|
|
/// </summary>
|
|
/// <param name="callback">callback function that takes a <c>LocalPlayerData</c> object</param>
|
|
public void RegisterOnLocalPlayerDataChangeCallback(Action<LocalPlayerData> callback)
|
|
{
|
|
_onLocalPlayerDataChangeCallbacks.Add(callback);
|
|
Debug.Log($"registering LocalPlayerDataChangeCallback ({_onLocalPlayerDataChangeCallbacks.Count})");
|
|
}
|
|
|
|
/// <summary>
|
|
/// function to fire all local player data change callbacks
|
|
/// </summary>
|
|
private void FireLocalPlayerDataChangeCallbacks(LocalPlayerData data)
|
|
{
|
|
Debug.Log($"firing LocalPlayerDataChangeCallbacks ({_onLocalPlayerDataChangeCallbacks.Count})");
|
|
foreach (var callback in _onLocalPlayerDataChangeCallbacks)
|
|
{
|
|
try
|
|
{
|
|
callback.Invoke(data);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
Debug.LogError($"error invoking LocalPlayerDataChangeCallback: {e.Message}");
|
|
}
|
|
}
|
|
}
|
|
} |