diff --git a/ColourMeOKGame/Assets/Scripts/AccountUI.cs b/ColourMeOKGame/Assets/Scripts/AccountUI.cs
index bf8cb65..6f7fac0 100644
--- a/ColourMeOKGame/Assets/Scripts/AccountUI.cs
+++ b/ColourMeOKGame/Assets/Scripts/AccountUI.cs
@@ -78,22 +78,11 @@ public class AccountUI : MonoBehaviour
///
private Button _usernameUpdateButton;
- private void Awake()
- {
- GameManager.Instance.Backend.RegisterOnSignInCallback(OnSignInCallback);
- }
-
- public void Start()
- {
- if (state == State.UnassociatedState) throw new Exception("unreachable state");
-
- // GameManager.Instance.Backend.RegisterOnSignInCallback(OnSignInCallback);
- }
-
///
- /// function to subscribe button events to their respective functions
+ /// function called when the object is enabled,
+ /// subscribes button events to their respective functions
///
- public void OnEnable()
+ private void OnEnable()
{
var ui = GetComponent().rootVisualElement;
@@ -121,17 +110,18 @@ public void OnEnable()
_secondaryActionButton.clicked += OnSecondaryActionButtonClick;
TransitionStateTo(State.NotSignedIn);
- }
-
- private void OnSignInCallback(FirebaseUser user)
- {
- Debug.Log("sign in account ui callback");
-
- var username = GameManager.Instance.Backend.GetUsername();
- _usernameField.value = username;
- _emailField.value = GameManager.Instance.Backend.GetUser().Email;
- _passwordField.value = "";
- _header.text = $"Signed in as {username}";
+
+ if (state == State.UnassociatedState) throw new Exception("unreachable state");
+ GameManager.Instance.Backend.RegisterOnSignInCallback(_ =>
+ {
+ Debug.Log("post-authentication callback, updating AccountView fields");
+ var username = GameManager.Instance.Backend.GetUsername();
+ _header.text = $"Signed in as {username}";
+ _passwordField.value = "";
+ _usernameField.value = username;
+ _emailField.value = GameManager.Instance.Backend.GetUser().Email;
+ });
+ GameManager.Instance.RegisterOnLocalPlayerDataChangeCallback(PopulateFields);
}
private void TransitionStateTo(State newState, bool keepAccompanyingText = false)
@@ -618,6 +608,18 @@ private void OnSecondaryActionButtonClick()
throw new ArgumentOutOfRangeException();
}
}
+
+ ///
+ /// populate the fields with the given username and email,
+ /// used as a callback to when local player data is changed
+ ///
+ public void PopulateFields(LocalPlayerData data)
+ {
+ Debug.Log(
+ $"populating AccountView fields with lkUsername={data.LastKnownUsername} and lkEmail={data.LastKnownEmail}");
+ _usernameField.value = data.LastKnownUsername;
+ _emailField.value = data.LastKnownEmail;
+ }
///
/// state of the account view
diff --git a/ColourMeOKGame/Assets/Scripts/AccountUI.cs.meta b/ColourMeOKGame/Assets/Scripts/AccountUI.cs.meta
index ac9fded..db998f3 100644
--- a/ColourMeOKGame/Assets/Scripts/AccountUI.cs.meta
+++ b/ColourMeOKGame/Assets/Scripts/AccountUI.cs.meta
@@ -4,7 +4,7 @@ MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
- executionOrder: 0
+ executionOrder: -10
icon: {instanceID: 0}
userData:
assetBundleName:
diff --git a/ColourMeOKGame/Assets/Scripts/Backend.cs b/ColourMeOKGame/Assets/Scripts/Backend.cs
index da7166e..12fc26c 100644
--- a/ColourMeOKGame/Assets/Scripts/Backend.cs
+++ b/ColourMeOKGame/Assets/Scripts/Backend.cs
@@ -60,12 +60,18 @@ public enum UserAccountDetailTargetEnum
///
/// callback functions to be invoked when the user signs in
///
- private readonly List> _onSignInCallback = new();
+ private readonly List> _onSignInCallbacks = new();
///
/// callback functions to be invoked when the user signs out
///
- private readonly List _onSignOutCallback = new();
+ private readonly List _onSignOutCallbacks = new();
+
+ ///
+ /// callback functions to be invoked when the user signs in
+ ///
+ ///
+ private readonly List> _onConnectionStatusChangedCallbacks = new ();
///
/// the firebase authentication object
@@ -100,9 +106,9 @@ public enum UserAccountDetailTargetEnum
///
/// variable initialisation function
///
- public void Initialise()
+ public void Initialise(Action callback)
{
- FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task =>
+ FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task =>
{
// cher is this robust enough
switch (task.Result)
@@ -112,6 +118,7 @@ public void Initialise()
_auth.StateChanged += AuthStateChanged;
_db = FirebaseDatabase.DefaultInstance.RootReference;
Status = FirebaseConnectionStatus.Connected;
+ callback(Status);
break;
case DependencyStatus.UnavailableDisabled:
@@ -119,21 +126,25 @@ public void Initialise()
case DependencyStatus.UnavilableMissing:
case DependencyStatus.UnavailablePermission:
Status = FirebaseConnectionStatus.ExternalError;
+ callback(Status);
break;
case DependencyStatus.UnavailableUpdating:
Status = FirebaseConnectionStatus.Updating;
- RetryInitialiseAfterDelay();
+ callback(Status);
+ RetryInitialiseAfterDelay(callback);
break;
case DependencyStatus.UnavailableUpdaterequired:
Status = FirebaseConnectionStatus.UpdateRequired;
+ callback(Status);
break;
case DependencyStatus.UnavailableOther:
default:
Status = FirebaseConnectionStatus.InternalError;
Debug.LogError("firebase ??? blew up or something," + task.Result);
+ callback(Status);
break;
}
@@ -146,8 +157,8 @@ public void Initialise()
///
private void FireOnSignInCallbacks()
{
- Debug.Log($"firing on sign in callbacks ({_onSignInCallback.Count})");
- foreach (var callback in _onSignInCallback)
+ Debug.Log($"firing OnSignInCallbacks ({_onSignInCallbacks.Count})");
+ foreach (var callback in _onSignInCallbacks)
{
try
{
@@ -155,18 +166,18 @@ private void FireOnSignInCallbacks()
}
catch (Exception e)
{
- Debug.LogError(e);
+ Debug.LogError($"error invoking OnSignInCallback: {e.Message}");
}
}
}
///
- /// function to fire all on sign out callbacks
+ /// function to fire all on sign-out callbacks
///
private void FireOnSignOutCallbacks()
{
- Debug.Log($"firing on sign out callbacks ({_onSignOutCallback.Count})");
- foreach (var callback in _onSignOutCallback)
+ Debug.Log($"firing OnSignOutCallbacks ({_onSignOutCallbacks.Count})");
+ foreach (var callback in _onSignOutCallbacks)
{
try
{
@@ -174,7 +185,7 @@ private void FireOnSignOutCallbacks()
}
catch (Exception e)
{
- Debug.LogError(e);
+ Debug.LogError($"error invoking OnSignOutCallback: {e.Message}");
}
}
}
@@ -182,10 +193,10 @@ private void FireOnSignOutCallbacks()
///
/// async function to retry initialisation after a delay
///
- private async void RetryInitialiseAfterDelay()
+ private async void RetryInitialiseAfterDelay(Action callback)
{
await Task.Delay(TimeSpan.FromSeconds(10));
- Initialise();
+ Initialise(callback);
}
///
@@ -235,25 +246,24 @@ private void AuthStateChanged(object sender, EventArgs eventArgs)
/// callback function that takes in a FirebaseUser object
public void RegisterOnSignInCallback(Action callback)
{
- Debug.Log("registering on sign in callback");
- _onSignInCallback.Add(callback);
+ _onSignInCallbacks.Add(callback);
}
- // ///
- // /// function to register a callback for when the user signs out
- // ///
- // /// callback function
- // public void RegisterOnSignOutCallback(Action callback)
- // {
- // _onSignOutCallback.Add(callback);
- // }
+ ///
+ /// function to register a callback for when the user signs out
+ ///
+ /// callback function
+ public void RegisterOnSignOutCallback(Action callback)
+ {
+ _onSignOutCallbacks.Add(callback);
+ }
///
/// abstraction function to authenticate the user
///
/// email string
/// user raw password string
- /// callback function that takes in an AuthenticationResult argument
+ /// callback function that takes in an AuthenticationResult enum
/// whether to treat authentication as registration
/// username string if registering
public void AuthenticateUser(
@@ -472,8 +482,7 @@ public void ForgotPassword(string email, Action callback)
/// abstraction function to get the user's recent scores from the database
///
///
- /// callback function that takes in a DatabaseTransactionResult and List of LocalPlayerData.Score
- /// argument
+ /// callback function that takes in a DatabaseTransactionResult enum and a List<LocalPlayerData.Score>
///
public void GetRecentScores(Action> callback)
{
@@ -485,7 +494,7 @@ public void GetRecentScores(Action
/// score
- /// callback function that takes in one DatabaseTransactionResult argument
+ /// callback function that takes in a DatabaseTransactionResult enum
public void SubmitScore(
LocalPlayerData.Score score,
Action callback)
@@ -497,7 +506,7 @@ public void GetRecentScores(Action
- /// callback function that takes in a DatabaseTransactionResult and float (user rating) argument
+ /// callback function that takes in a DatabaseTransactionResult enum and a user rating float
public void CalculateUserRating(
Action callback)
{
@@ -508,7 +517,7 @@ public void GetRecentScores(Action
/// new user rating value as a float
- /// callback function that takes in one DatabaseTransactionResult argument
+ /// callback function that takes in a DatabaseTransactionResult enum
public void UpdateUserRating(
float newRating,
Action callback)
@@ -520,7 +529,7 @@ public void GetRecentScores(Action
///
- /// callback function that takes in a DatabaseTransactionResult and LeaderboardEntry[] argument
+ /// callback function that takes in a DatabaseTransactionResult enum and a List<LeaderboardEntry>
///
public void GetLeaderboard(
Action callback)
@@ -533,7 +542,7 @@ public void GetRecentScores(Action
/// the target account detail to update
/// the new value for the target account detail
- /// callback function that takes in one DatabaseTransactionResult argument
+ /// callback function that takes in a DatabaseTransactionResult enum
/// thrown when the target is not a valid UserAccountDetailTargetEnum
public void UpdateUserAccountDetail(
UserAccountDetailTargetEnum target,
diff --git a/ColourMeOKGame/Assets/Scripts/GameManager.cs b/ColourMeOKGame/Assets/Scripts/GameManager.cs
index ec2b3a3..44e2a6a 100644
--- a/ColourMeOKGame/Assets/Scripts/GameManager.cs
+++ b/ColourMeOKGame/Assets/Scripts/GameManager.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UIElements;
@@ -20,7 +21,17 @@ public class GameManager : MonoBehaviour
///
/// the local player data object for storing player data
///
- private LocalPlayerData _localPlayerData;
+ private LocalPlayerData _data;
+
+ ///
+ /// read-only property for accessing the local player data outside of this class
+ ///
+ public LocalPlayerData Data => _data;
+
+ ///
+ /// list of callbacks to call when the local player data changes
+ ///
+ private readonly List> _onLocalPlayerDataChangeCallbacks = new List>();
///
/// backend object for handling communication with the firebase backend
@@ -47,40 +58,55 @@ private void Awake()
}
}
- private void Start()
- {
- // load the local player data and refresh the ui
- _localPlayerData = new LocalPlayerData();
- _localPlayerData.LoadFromTheWorld();
- PopulateFields();
- try
- {
- RenderFromPlayerData();
- }
- catch (Exception)
- {
- // TODO: remove this once the bug is fixed
- Debug.LogWarning("handling known exception, remove this once the bug is fixed");
- }
-
- // register a callback to refresh the ui when the player signs in
- Backend.RegisterOnSignInCallback(_ =>
- {
- Debug.Log("sign in callback, refreshing GameManager-controlled SideView UI");
- _localPlayerData.LoadFromTheWorld();
- PopulateFields();
- RenderFromPlayerData();
- });
- }
-
///
/// called when the game object is enabled, initialises variables
///
private void OnEnable()
{
- Backend = new Backend();
- Backend.Initialise();
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