diff --git a/ColourMeOKGame/Assets/Scenes/GameScene.unity b/ColourMeOKGame/Assets/Scenes/GameScene.unity
index 486551b..1caf66b 100644
--- a/ColourMeOKGame/Assets/Scenes/GameScene.unity
+++ b/ColourMeOKGame/Assets/Scenes/GameScene.unity
@@ -166,7 +166,7 @@ Transform:
m_PrefabAsset: {fileID: 0}
m_GameObject: {fileID: 133964670}
serializedVersion: 2
- m_LocalRotation: {x: 0, y: 0, z: 0, w: 1}
+ m_LocalRotation: {x: -0, y: -0, z: -0, w: 1}
m_LocalPosition: {x: 0, y: 0, z: 0}
m_LocalScale: {x: 1, y: 1, z: 1}
m_ConstrainProportionsScale: 0
@@ -459,6 +459,8 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 0cfc0b50e9003a0468ebdc186439c53b, type: 3}
m_Name:
m_EditorClassIdentifier:
+ state: 0
+ uiGameObject: {fileID: 133964670}
--- !u!4 &1204483826
Transform:
m_ObjectHideFlags: 0
@@ -480,6 +482,6 @@ SceneRoots:
m_Roots:
- {fileID: 963194228}
- {fileID: 705507995}
- - {fileID: 133964672}
- {fileID: 447905427}
+ - {fileID: 133964672}
- {fileID: 1204483826}
diff --git a/ColourMeOKGame/Assets/Scripts/AccountUI.cs b/ColourMeOKGame/Assets/Scripts/AccountUI.cs
index 977f0ff..5b94677 100644
--- a/ColourMeOKGame/Assets/Scripts/AccountUI.cs
+++ b/ColourMeOKGame/Assets/Scripts/AccountUI.cs
@@ -78,11 +78,20 @@ public class AccountUI : MonoBehaviour
///
private Button _usernameUpdateButton;
- public void Start()
+ ///
+ /// start function to initialise the account view
+ ///
+ ///
+ private void Start()
{
+ TransitionStateTo(State.NotSignedIn);
if (state == State.UnassociatedState) throw new Exception("unreachable state");
-
- // GameManager.Instance.Backend.RegisterOnSignInCallback(OnSignInCallback);
+ GameManager.Instance.Backend.RegisterOnSignInCallback(OnSignInCallback);
+ GameManager.Instance.RegisterOnLocalPlayerDataUpdate(data =>
+ {
+ Debug.Log("local player data update callback, populating AccountView fields");
+ PopulateFields(data.LastKnownUsername, data.LastKnownEmail);
+ });
}
///
@@ -114,15 +123,11 @@ public void OnEnable()
_secondaryActionButton = ui.Q
private DatabaseReference _db;
+ ///
+ /// callback functions to be invoked when the user signs in
+ ///
+ private readonly List> _onSignInCallbacks = new();
+
+ ///
+ /// callback functions to be invoked when the user signs out
+ ///
+ private readonly List> _onSignOutCallbacks = new();
+
///
/// the current user object, if authenticated
///
@@ -95,9 +95,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)
@@ -107,6 +107,7 @@ public void Initialise()
_auth.StateChanged += AuthStateChanged;
_db = FirebaseDatabase.DefaultInstance.RootReference;
Status = FirebaseConnectionStatus.Connected;
+ callback(Status);
break;
case DependencyStatus.UnavailableDisabled:
@@ -114,21 +115,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;
}
@@ -139,10 +144,10 @@ public void Initialise()
///
/// 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);
}
///
@@ -172,7 +177,7 @@ private void AuthStateChanged(object sender, EventArgs eventArgs)
if (!signedIn && _user != null)
{
Debug.Log($"signed out successfully as {_user.UserId}");
- foreach (var callback in _onSignOutCallback)
+ foreach (var callback in _onSignOutCallbacks)
callback(_user);
}
@@ -183,26 +188,29 @@ private void AuthStateChanged(object sender, EventArgs eventArgs)
Debug.Log($"signed in successfully as {_user.UserId}");
RetrieveUsernameWithCallback((_, _) =>
{
- foreach (var callback in _onSignInCallback) callback(_user);
+ Debug.Log($"retrieved username post-authentication, calling {_onSignInCallbacks.Count} callbacks");
+ foreach (var callback in _onSignInCallbacks) callback(_user);
});
}
///
/// function to register a callback for when the user signs in
///
- /// callback function that takes in a FirebaseUser argument
+ /// callback function that takes in a FirebaseUser object
public void RegisterOnSignInCallback(Action callback)
{
- _onSignInCallback.Add(callback);
+ _onSignInCallbacks.Add(callback);
+ Debug.Log($"registering on sign in callback, there are now {_onSignInCallbacks.Count} callbacks");
}
///
/// function to register a callback for when the user signs out
///
- /// callback function that takes in a FirebaseUser argument
+ /// callback function that takes in a FirebaseUser object
public void RegisterOnSignOutCallback(Action callback)
{
- _onSignOutCallback.Add(callback);
+ Debug.Log($"registering on sign out callback, there are now {_onSignOutCallbacks.Count} callbacks");
+ _onSignOutCallbacks.Add(callback);
}
///
@@ -364,21 +372,18 @@ private void RetrieveUsernameWithCallback(Action
{
- DatabaseTransactionResult result;
if (task.IsCompletedSuccessfully)
{
- result = DatabaseTransactionResult.Ok;
_username = task.Result.Value.ToString();
Debug.Log($"our username is {_username}");
+ callback(DatabaseTransactionResult.Ok, _username);
}
else
{
- result = DatabaseTransactionResult.Error;
_username = "Unknown";
Debug.LogError("failed to get username");
+ callback(DatabaseTransactionResult.Error, _username);
}
-
- callback(result, _username);
});
}
@@ -429,8 +434,8 @@ 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>argument
///
public void GetRecentScores(Action> callback)
{
diff --git a/ColourMeOKGame/Assets/Scripts/Colorimetry.cs b/ColourMeOKGame/Assets/Scripts/Colorimetry.cs
index 72c98b6..bf5ce52 100644
--- a/ColourMeOKGame/Assets/Scripts/Colorimetry.cs
+++ b/ColourMeOKGame/Assets/Scripts/Colorimetry.cs
@@ -62,6 +62,7 @@ public static RGB gamut_clip_preserve_chroma(RGB rgb)
/// a and b must be normalized so a^2 + b^2 == 1
///
// https://bottosson.github.io/posts/gamutclipping/ (MIT)
+ // ReSharper disable once MemberCanBePrivate.Global
public static float find_gamut_intersection(
float a,
float b,
@@ -164,6 +165,7 @@ public static RGB gamut_clip_preserve_chroma(RGB rgb)
/// a and b must be normalized so a^2 + b^2 == 1
///
// https://bottosson.github.io/posts/gamutclipping/ (MIT)
+ // ReSharper disable once MemberCanBePrivate.Global
public static LC find_cusp(float a, float b)
{
// First, find the maximum saturation (saturation S = C/L)
@@ -178,7 +180,7 @@ public static LC find_cusp(float a, float b)
}
// https://bottosson.github.io/posts/oklab/#converting-from-linear-srgb-to-oklab (public domain)
-
+ // ReSharper disable once MemberCanBePrivate.Global
public static Lab linear_srgb_to_oklab(RGB c)
{
var l = 0.4122214708f * c.r + 0.5363325363f * c.g + 0.0514459929f * c.b;
@@ -220,6 +222,7 @@ public static RGB oklab_to_linear_srgb(Lab c)
/// a and b must be normalized so a^2 + b^2 == 1
///
// https://bottosson.github.io/posts/gamutclipping/ (MIT)
+ // ReSharper disable once MemberCanBePrivate.Global
public static float compute_max_saturation(float a, float b)
{
// Max saturation will be when one of r, g or b goes below zero.
diff --git a/ColourMeOKGame/Assets/Scripts/GameManager.cs b/ColourMeOKGame/Assets/Scripts/GameManager.cs
index 56709b1..a504299 100644
--- a/ColourMeOKGame/Assets/Scripts/GameManager.cs
+++ b/ColourMeOKGame/Assets/Scripts/GameManager.cs
@@ -1,5 +1,6 @@
+using System;
+using System.Collections.Generic;
using UnityEngine;
-using UnityEngine.Serialization;
using UnityEngine.UIElements;
///
@@ -12,24 +13,45 @@ public class GameManager : MonoBehaviour
///
public enum DisplayState
{
+ UnassociatedState, // initial state, then we transition to Nothing to initialise the ui
Nothing,
- PlayView,
+ GameView,
LeaderboardView,
- AccountView,
+ AccountView
}
///
/// singleton pattern: define instance field for accessing the singleton elsewhere
///
public static GameManager Instance;
-
+
///
/// the current display state of the game
///
- [SerializeField] private DisplayState state = DisplayState.Nothing;
+ [SerializeField] private DisplayState state = DisplayState.UnassociatedState;
///
- /// the visual element object for game ui (hud/prompts/tooltips)
+ /// the game object for the ui
+ ///
+ [SerializeField] private GameObject uiGameObject;
+
+ // ///
+ // /// callback functions to be invoked when the display state changes
+ // ///
+ // private readonly List> _onDisplayStateChange = new();
+
+ ///
+ /// callback functions to be invoked when the local player data is updated
+ ///
+ private readonly List> _onLocalPlayerDataUpdateCallbacks = new();
+
+ ///
+ /// the local player data object for storing player data
+ ///
+ private LocalPlayerData _data;
+
+ ///
+ /// the visual element for the ui
///
private VisualElement _ui;
@@ -37,11 +59,6 @@ public enum DisplayState
/// backend object for handling communication with the firebase backend
///
public Backend Backend;
-
- ///
- /// the local player data object for storing player data
- ///
- private LocalPlayerData _localPlayerData;
///
/// enforces singleton behaviour; sets doesn't destroy on load and checks for multiple instances
@@ -61,30 +78,65 @@ private void Awake()
Debug.Log("awake as non-singleton instance, destroying self");
Destroy(gameObject);
}
- }
- private void Start()
- {
- SetDisplayState(DisplayState.PlayView);
-
- // load the local player data and refresh the ui
- _localPlayerData = new LocalPlayerData();
- _localPlayerData.LoadFromTheWorld();
-
- // register a callback to refresh the ui when the player signs in
- Backend.RegisterOnSignInCallback(_ =>
- {
- _localPlayerData.LoadFromTheWorld();
- });
+ if (uiGameObject == null)
+ throw new NullReferenceException("a reference UI GameObject is not set in the inspector");
+
+ _ui = uiGameObject.GetComponent()?.rootVisualElement;
+ if (_ui == null)
+ throw new NullReferenceException("could not grab the UIDocument in the reference UI GameObject");
}
///
- /// called when the game object is enabled
+ /// called before the first frame update
///
- private void OnEnable()
+ private void Start()
{
+ // transition to the initial state
+ SetDisplayState(DisplayState.Nothing);
+
+ // initialise the backend
Backend = new Backend();
- Backend.Initialise();
+ Backend.Initialise(status =>
+ {
+ Debug.Log("initialised backend, setting connection status text");
+
+ _ui.Q