diff --git a/Assets/Accounts/ScriptableObjects/UserAvatarList.asset b/Assets/Accounts/ScriptableObjects/UserAvatarList.asset new file mode 100644 index 0000000..dd6dba2 --- /dev/null +++ b/Assets/Accounts/ScriptableObjects/UserAvatarList.asset @@ -0,0 +1,42 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &11400000 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 81765ea55baf15d45b01b02187b02429, type: 3} + m_Name: UserAvatarList + m_EditorClassIdentifier: + avatars: + - {fileID: 21300000, guid: 6feaaea4b64633f49b4538bfd4b3755c, type: 3} + - {fileID: 21300000, guid: 399cc241fc79bd74db314f146e7fb6b9, type: 3} + - {fileID: 21300000, guid: 4654657a2ebea444898fa6eeaefcd18d, type: 3} + - {fileID: 21300000, guid: 0cc198f1cde659246a199b30459720b1, type: 3} + - {fileID: 21300000, guid: 7f105a09a3d164547925ee1bdfa595ca, type: 3} + - {fileID: 21300000, guid: 313c22e5834595645989d609fe9d8853, type: 3} + - {fileID: 21300000, guid: e5f3d99cdf5298d4f86d42dd019a6bad, type: 3} + - {fileID: 21300000, guid: b67b99d98d1ceb1489743bcd78b9ab70, type: 3} + - {fileID: 21300000, guid: e4af402f37099cd4195d7d2654519744, type: 3} + - {fileID: 21300000, guid: 73f4e028d9efb644aa23538a749667c5, type: 3} + - {fileID: 21300000, guid: 61e56570163833e448037bc353ada0ac, type: 3} + - {fileID: 21300000, guid: 8e69dfd19237abb4f98eb11e74153109, type: 3} + - {fileID: 21300000, guid: bc11ff9d6cc35de45ab58f39f13d7142, type: 3} + - {fileID: 21300000, guid: f989719a5c45c7a4183b2bc12c1c4905, type: 3} + - {fileID: 21300000, guid: 1392922567cd59d4fb0beceea3f5917a, type: 3} + - {fileID: 21300000, guid: 3c314ae9e10eafb49b57c98c9e779bd8, type: 3} + - {fileID: 21300000, guid: 33509e453b5093e43a148a668a961c56, type: 3} + - {fileID: 21300000, guid: 39ac3b86729423846be1fbd56b8d92d6, type: 3} + - {fileID: 21300000, guid: 1118d67f50622cc4ab02aa23c6dc1fd4, type: 3} + - {fileID: 21300000, guid: e519f0f7b00e6834187963a0131cae52, type: 3} + - {fileID: 21300000, guid: eefb367ff44256d43a14cde2c3924321, type: 3} + - {fileID: 21300000, guid: 83d6525e4efa4954091e08095349f45a, type: 3} + - {fileID: 21300000, guid: db31bca6363270441ab54421f55c1263, type: 3} + - {fileID: 21300000, guid: 9d5771baa6ea6e041b066135d6798e1c, type: 3} + - {fileID: 21300000, guid: 2b01165a5836ab14593d7a5862bd6793, type: 3} + - {fileID: 21300000, guid: 8c304fe460423214ea0bb6ebc235ed2d, type: 3} + - {fileID: 21300000, guid: b203b4e5f8568ff46b2277ce6d61017a, type: 3} diff --git a/Assets/Accounts/ScriptableObjects/UserAvatarList.asset.meta b/Assets/Accounts/ScriptableObjects/UserAvatarList.asset.meta new file mode 100644 index 0000000..aa1812e --- /dev/null +++ b/Assets/Accounts/ScriptableObjects/UserAvatarList.asset.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 017ec1af3b6cc4d4ab2b506911a4edad +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 11400000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Accounts/Scripts/AccountsScripts.asmdef b/Assets/Accounts/Scripts/AccountsScripts.asmdef index 9238363..8a40a7f 100644 --- a/Assets/Accounts/Scripts/AccountsScripts.asmdef +++ b/Assets/Accounts/Scripts/AccountsScripts.asmdef @@ -3,6 +3,7 @@ "rootNamespace": "", "references": [ "GUID:6055be8ebefd69e48b49212b09b47b2f", + "GUID:e83ddf9a537a96b4a804a16bb7872ec1", "GUID:7f2d0ee6dd21e1d4eb25b71b7a749d25" ], "includePlatforms": [], diff --git a/Assets/Accounts/Scripts/ChangeUserScreen.cs b/Assets/Accounts/Scripts/ChangeUserScreen.cs index e5e0041..fbf7175 100644 --- a/Assets/Accounts/Scripts/ChangeUserScreen.cs +++ b/Assets/Accounts/Scripts/ChangeUserScreen.cs @@ -22,11 +22,6 @@ public class ChangeUserScreen : MonoBehaviour /// public GameObject error; - /// - /// Reference to the user list - /// - public UserList userList; - /// /// Index of the current selected user in the UserList /// @@ -42,7 +37,7 @@ public class ChangeUserScreen : MonoBehaviour /// void Start() { - userList.Load(); + PersistentDataController.GetInstance().Load(); error.SetActive(false); DisplayUsers(); } @@ -57,8 +52,8 @@ public class ChangeUserScreen : MonoBehaviour Destroy(child.gameObject); } - List users = userList.GetUsers(); - currentUserIndex = userList.GetCurrentUserIndex(); + List users = UserList.GetUsers(); + int currentUserIndex = UserList.IndexOf(UserList.GetCurrentUser().GetUsername()); for (int i = 0; i < users.Count; i++) { User user = users[i]; @@ -99,8 +94,7 @@ public class ChangeUserScreen : MonoBehaviour /// public void IChooseYou() { - userList.ChangeCurrentUser(currentUserIndex); - userList.Save(); + UserList.ChangeCurrentUser(currentUserIndex); SystemController.GetInstance().BackToPreviousScene(); } diff --git a/Assets/Accounts/Scripts/CourseProgressCard.cs b/Assets/Accounts/Scripts/CourseProgressCard.cs index 76b7550..2c6522b 100644 --- a/Assets/Accounts/Scripts/CourseProgressCard.cs +++ b/Assets/Accounts/Scripts/CourseProgressCard.cs @@ -21,7 +21,7 @@ public class CourseProgressCard : MonoBehaviour /// /// Reference to the progress so we can display a progress bar /// - public Progress courseProgress; + public PersistentDataController.SavedCourseProgress courseProgress; /// /// Reference to the list of courses so we can query the correct course @@ -48,11 +48,11 @@ public class CourseProgressCard : MonoBehaviour /// void Start() { - Course course = courseList.GetCourseByIndex(courseProgress.Get("courseIndex")); + Course course = courseList.GetCourseByIndex(courseProgress.courseIndex); thumbnail.sprite = course.thumbnail; title.text = course.title; - progressBar.value = courseProgress.Get("courseProgress"); + progressBar.value = courseProgress.progress; button.onClick.AddListener(selectActivity); } } diff --git a/Assets/Accounts/Scripts/MinigameProgressCard.cs b/Assets/Accounts/Scripts/MinigameProgressCard.cs index 6e4b2f5..aca0b4b 100644 --- a/Assets/Accounts/Scripts/MinigameProgressCard.cs +++ b/Assets/Accounts/Scripts/MinigameProgressCard.cs @@ -22,7 +22,7 @@ public class MinigameProgressCard : MonoBehaviour /// /// Reference to the minigame progress /// - public Progress minigameProgress; + public PersistentDataController.SavedMinigameProgress minigameProgress; /// /// Reference to the minigame list @@ -49,11 +49,11 @@ public class MinigameProgressCard : MonoBehaviour /// void Start() { - Minigame minigame = minigameList.GetMinigameByIndex(minigameProgress.Get("minigameIndex")); + Minigame minigame = minigameList.GetMinigameByIndex(minigameProgress.minigameIndex); thumbnail.sprite = minigame.thumbnail; title.text = minigame.title; - List highscores = minigameProgress.Get>("highestScores"); + List highscores = minigameProgress.highestScores; int score = highscores.Count > 0 ? highscores[0].scoreValue : 0; highscore.text = $"Topscore: {score}"; button.onClick.AddListener(selectActivity); diff --git a/Assets/Accounts/Scripts/Progress.cs b/Assets/Accounts/Scripts/Progress.cs deleted file mode 100644 index e6adf98..0000000 --- a/Assets/Accounts/Scripts/Progress.cs +++ /dev/null @@ -1,114 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Runtime.Serialization.Formatters.Binary; -using UnityEngine; - -/// -/// A class for holding all progress belonging to a user -/// -[Serializable] -public class Progress -{ - /// - /// A helper class for handling the stored progress - /// - [Serializable] - protected class DataEntry - { - /// - /// The key, used to reference the data object - /// - public string key; - - /// - /// The object, representated as a list of byte (which can be serialized) - /// - public List bytes = new List(); - - public DataEntry(string key, byte[] data) - { - this.key = key; - this.bytes = new List(data); - } - } - - /// - /// Entries in the Progress object - /// - [SerializeField] - private List entries = new List(); - - - /// - /// Update the value of a certain key, - /// or add a new value if the key was not present - /// - /// The type of the data to be added/updated - /// The key, used for referencing the data - /// The object of type - /// true if successful, false otherwise - public bool AddOrUpdate(string key, T data) - { - if (data == null) - return false; - - DataEntry entry = entries.Find(x => x.key == key); - - // Hacky serialization stuff - BinaryFormatter bf = new BinaryFormatter(); - using (MemoryStream ms = new MemoryStream()) - { - bf.Serialize(ms, data); - if (entry != null) - { - entry.bytes.Clear(); - entry.bytes.AddRange(ms.ToArray()); - } - else - { - entries.Add(new DataEntry(key, ms.ToArray())); - } - return true; - } - } - - /// - /// Get the data object of a certain key - /// - /// The type of the data object - /// The key referencing the data object - /// The data, cast to a type - /// - public T Get(string key) - { - BinaryFormatter bf = new BinaryFormatter(); - using (MemoryStream ms = new MemoryStream()) - { - // Find the correct key - foreach (DataEntry entry in entries) - { - if (entry.key == key) - { - // Hacky serialization stuff - byte[] data = entry.bytes.ToArray(); - ms.Write(data, 0, data.Length); - ms.Seek(0, SeekOrigin.Begin); - return (T)bf.Deserialize(ms); - } - } - } - // Raise an exception when key is not found - throw new KeyNotFoundException(); - } - - /// - /// Check whether a key is present - /// - /// The key to check - /// true if a item can be found with the specified key - public bool Has(string key) - { - return entries.Find(x => x.key == key) != null; - } -} diff --git a/Assets/Accounts/Scripts/User.cs b/Assets/Accounts/Scripts/User.cs index 74aa614..bd6aa93 100644 --- a/Assets/Accounts/Scripts/User.cs +++ b/Assets/Accounts/Scripts/User.cs @@ -2,40 +2,45 @@ using System; using System.Collections.Generic; using System.Linq; using UnityEngine; +using static PersistentDataController; /// /// A class holding all information of a user /// -[Serializable] public class User { /// - /// User nickname + /// Reference to the user stored data record /// - public string username; + private SavedUserData storedUserData; /// - /// The avatar of the user + /// Constructor /// - public Sprite avatar; + /// Reference to the user stored data record + public User(SavedUserData data) + { + this.storedUserData = data; + } /// - /// The total playtime of the user + /// Get the username /// - /// TODO: needs to be implemented - public double playtime; + /// + public string GetUsername() { return storedUserData.username; } /// - /// List of courses a user started/completed + /// Get the total playtime /// - [SerializeField] - public List courses = new List(); + /// + public double GetPlaytime() { return storedUserData.playtime; } /// - /// List of minigames a user played + /// Get the avatar /// - [SerializeField] - public List minigames = new List(); + /// + public Sprite GetAvatar() { return UserList.AVATARS[storedUserData.avatarIndex]; } + /// /// Get a list of all recently started courses @@ -46,10 +51,10 @@ public class User { // TODO: return better results (for now only return all courses) List> recentCourses = new List>(); - foreach (Progress courseProgress in courses) + foreach (var courseProgress in storedUserData.courses) { - CourseIndex idx = courseProgress.Get("courseIndex"); - float progress = courseProgress.Get("courseProgress"); + CourseIndex idx = courseProgress.courseIndex; + float progress = courseProgress.progress; recentCourses.Add(Tuple.Create(idx, progress)); } return recentCourses.Take(3).ToList(); @@ -63,31 +68,58 @@ public class User public List> GetRecommendedCourses() { List> recommenedCourses = new List>(); - if (courses.Count == 0) + if (storedUserData.courses.Count == 0) { recommenedCourses.Add(Tuple.Create(CourseIndex.FINGERSPELLING, 0.0f)); } else { // TODO: return better results (for now only return all courses) - foreach (Progress courseProgress in courses) + foreach (var courseProgress in storedUserData.courses) { - CourseIndex idx = courseProgress.Get("courseIndex"); - float progress = courseProgress.Get("courseProgress"); + CourseIndex idx = courseProgress.courseIndex; + float progress = courseProgress.progress; recommenedCourses.Add(Tuple.Create(idx, progress)); } } return recommenedCourses.Take(3).ToList(); } + /// + /// Get the progress of all courses the user did + /// + /// + public List GetCourses() + { + return storedUserData.courses; + } + /// /// Get the progress of a certain course /// /// Index of course /// Progress belonging to the courseIndex, null if course was not found - public Progress GetCourseProgress(CourseIndex courseIndex) + public SavedCourseProgress GetCourseProgress(CourseIndex courseIndex) { - return courses.Find((p) => p.Get("courseIndex") == courseIndex); + return storedUserData.courses.Find((p) => p.courseIndex == courseIndex); + } + + /// + /// Add new progress of a course + /// + /// SavedCourseProgress data record + public void AddCourseProgress(SavedCourseProgress progress) + { + storedUserData.courses.Add(progress); + } + + /// + /// Get the progress of all minigames the user did + /// + /// + public List GetMinigames() + { + return storedUserData.minigames; } /// @@ -95,8 +127,17 @@ public class User /// /// Index of the minigame /// Progress belonging to the minigameIndex, null if minigame was not found - public Progress GetMinigameProgress(MinigameIndex minigameIndex) + public SavedMinigameProgress GetMinigameProgress(MinigameIndex minigameIndex) { - return minigames.Find((p) => p.Get("minigameIndex") == minigameIndex); + return storedUserData.minigames.Find((p) => p.minigameIndex == minigameIndex); + } + + /// + /// Add new progress of a minigame + /// + /// SavedMinigameProgress data record + public void AddMinigameProgress(SavedMinigameProgress progress) + { + storedUserData.minigames.Add(progress); } } diff --git a/Assets/Accounts/Scripts/UserAvatarList.cs b/Assets/Accounts/Scripts/UserAvatarList.cs new file mode 100644 index 0000000..e753689 --- /dev/null +++ b/Assets/Accounts/Scripts/UserAvatarList.cs @@ -0,0 +1,19 @@ +using System.Collections.Generic; +using UnityEngine; + +/// +/// Container to hold a reference to all possible user avatar sprites +/// +[CreateAssetMenu(menuName = "Create new Scriptable/User Avatar List")] +public class UserAvatarList : ScriptableObject +{ + /// + /// List of avatar sprites + /// + public List avatars = new List(); + + public void Awake() + { + UserList.AVATARS = avatars; + } +} diff --git a/Assets/Accounts/Scripts/Progress.cs.meta b/Assets/Accounts/Scripts/UserAvatarList.cs.meta similarity index 83% rename from Assets/Accounts/Scripts/Progress.cs.meta rename to Assets/Accounts/Scripts/UserAvatarList.cs.meta index f99f844..e6a265c 100644 --- a/Assets/Accounts/Scripts/Progress.cs.meta +++ b/Assets/Accounts/Scripts/UserAvatarList.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: d887bc641cc7a8f4abf9d4eb34d26923 +guid: 81765ea55baf15d45b01b02187b02429 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Accounts/Scripts/UserCard.cs b/Assets/Accounts/Scripts/UserCard.cs index d807568..3bc3ea2 100644 --- a/Assets/Accounts/Scripts/UserCard.cs +++ b/Assets/Accounts/Scripts/UserCard.cs @@ -8,11 +8,6 @@ using UnityEngine.UI; /// public class UserCard : MonoBehaviour { - /// - /// Reference to the userlist - /// - public UserList userList; - /// /// User to upload info into this card /// @@ -53,8 +48,8 @@ public class UserCard : MonoBehaviour /// void Start() { - avatar.sprite = user.avatar; - username.text = user.username; + avatar.sprite = user.GetAvatar(); + username.text = user.GetUsername(); button.onClick.AddListener(selectUser); } @@ -63,10 +58,9 @@ public class UserCard : MonoBehaviour /// public void DeleteUser() { - if (userList.DeleteUser(user)) + if (UserList.DeleteUser(user.GetUsername())) { // User is removed, update and save - userList.Save(); updateUserCardContainer(); } else diff --git a/Assets/Accounts/Scripts/UserCreationScreen.cs b/Assets/Accounts/Scripts/UserCreationScreen.cs index 6b5cb77..cf185c5 100644 --- a/Assets/Accounts/Scripts/UserCreationScreen.cs +++ b/Assets/Accounts/Scripts/UserCreationScreen.cs @@ -34,20 +34,9 @@ public class UserCreationScreen : MonoBehaviour /// public GameObject avatarPrefab; - /// - /// List of all sprites that are supported as avatars - /// - public List sprites = new List(); - - /// - /// Reference to the UserList ScriptableObject - /// - public UserList users; - /// /// Current selected avatar /// - [SerializeField] private int selectedAvatar = 0; /// @@ -63,7 +52,7 @@ public class UserCreationScreen : MonoBehaviour { errorMessage.SetActive(false); - for (int i = 0; i < sprites.Count; i++) + for (int i = 0; i < UserList.AVATARS.Count; i++) { // Create instance of prefab GameObject instance = GameObject.Instantiate(avatarPrefab, avatarsContainer); @@ -79,7 +68,7 @@ public class UserCreationScreen : MonoBehaviour // Set background color background.color = selectedAvatar == i ? Color.blue : Color.gray; // Find correct component for setting the sprite - instance.transform.Find("Image").GetComponent().sprite = sprites[i]; + instance.transform.Find("Image").GetComponent().sprite = UserList.AVATARS[i]; } } @@ -113,10 +102,10 @@ public class UserCreationScreen : MonoBehaviour string username = inputName.text; if (IsValidUsername(username)) { - if (users.GetUserByUsername(username) == null) + if (UserList.GetUserByUsername(username) == null) { // Create a new entry in the UserList ScriptableObject - users.ChangeCurrentUser(users.CreateAndAddNewUser(username, sprites[selectedAvatar])); + UserList.AddUser(username, UserList.AVATARS[selectedAvatar]); SystemController.GetInstance().BackToPreviousScene(); } // Warn user that username already exists diff --git a/Assets/Accounts/Scripts/UserList.cs b/Assets/Accounts/Scripts/UserList.cs index 44916f0..4a17766 100644 --- a/Assets/Accounts/Scripts/UserList.cs +++ b/Assets/Accounts/Scripts/UserList.cs @@ -1,87 +1,33 @@ using System; using System.Collections.Generic; -using System.IO; using UnityEngine; /// /// Keep track of all users /// -[CreateAssetMenu(menuName = "Create new Scriptable/UserList")] -public class UserList : ScriptableObject +public static class UserList { /// - /// Helper class to enable serialization of the UserList class - /// (ScriptableObjects cannot be serialized) + /// List of possible avatar sprites /// - [Serializable] - public class StoredUserList - { - /// - /// The index of the current/last logged in user in the storedUsers list - /// - public int currentUserIndex = -1; - - /// - /// A list containing all users (which can be serialized) - /// - public List storedUsers = new List(); - } - - /// - /// Reference to the serializable version of UserList - /// - [SerializeField] - private StoredUserList storedUserList = new StoredUserList(); - - /// - /// Path of the .json-file to store all serialized data - /// - public static string PATH = null; - - /// - /// OnEnable will make sure the PATH-variable is correctly initialized - /// - void OnEnable() - { - // The PATH variable can be set by the testing framework, - // so we don't overwrite the actual userlist with test data - if (PATH == null) - { - PATH = $"{Application.persistentDataPath}/users.json"; - Load(); - } - } - - /// - /// Create a new user - /// - /// The username of the new user - /// Reference to the user avatar - /// A newly created user - public User CreateNewUser(string name, Sprite avatar) - { - User user = new User(); - user.username = name; - user.avatar = avatar; - return user; - } + public static List AVATARS = new List(); /// /// Create a new user and save (add to list) /// - /// The username of the new user + /// The username of the new user /// Reference to the user avatar /// A newly created user - public User CreateAndAddNewUser(string name, Sprite avatar) + public static User AddUser(string username, Sprite avatar) { - User user = CreateNewUser(name, avatar); - storedUserList.storedUsers.Add(user); - if (storedUserList.storedUsers.Count == 1) - { - storedUserList.currentUserIndex = 0; - } - Save(); - return user; + PersistentDataController pdc = PersistentDataController.GetInstance(); + PersistentDataController.SavedUserData data = new PersistentDataController.SavedUserData(); + data.username = username; + data.playtime = 0.0; + data.avatarIndex = AVATARS.IndexOf(avatar); + + pdc.AddUser(data); + return new User(data); } /// @@ -89,43 +35,61 @@ public class UserList : ScriptableObject /// /// The username of the user /// User-object if a user with such username was found, null otherwise - public User GetUserByUsername(string username) + public static User GetUserByUsername(string username) { - foreach (User user in storedUserList.storedUsers) - if (user.username == username) return user; + foreach (User user in GetUsers()) + if (user.GetUsername() == username) return user; return null; } + /// + /// Get a user by index + /// + /// The index of the user + /// User object + /// + public static User GetUserByIndex(int index) + { + List users = GetUsers(); + if (index < 0 || users.Count <= index) + throw new IndexOutOfRangeException(); + + return users[index]; + } + /// /// Get a list of all users currently stored /// /// A list of all users - public List GetUsers() + public static List GetUsers() { - return storedUserList.storedUsers; + PersistentDataController pdc = PersistentDataController.GetInstance(); + return pdc.GetUsers().ConvertAll((d) => new User(d)); } /// /// Get the current logged in user /// /// The current logged in user - public User GetCurrentUser() + public static User GetCurrentUser() { - if (storedUserList.storedUsers.Count == 0) - { + List users = GetUsers(); + if (users.Count == 0) return null; - } - return storedUserList.storedUsers[storedUserList.currentUserIndex]; + return users[PersistentDataController.GetInstance().GetCurrentUser()]; } /// - /// Get the index in the userlist of the current playing user + /// Get the index in the userlist of a user /// /// - public int GetCurrentUserIndex() + public static int IndexOf(string username) { - return storedUserList.currentUserIndex; + int idx = GetUsers().FindIndex((e) => e.GetUsername() == username); + if (idx < 0) + throw new KeyNotFoundException(); + return idx; } /// @@ -133,89 +97,66 @@ public class UserList : ScriptableObject /// /// Index of the user in the userlist /// - public void ChangeCurrentUser(int index) + public static void ChangeCurrentUser(int index) { - if (0 <= index && index < storedUserList.storedUsers.Count) - { - storedUserList.currentUserIndex = index; - } - else - { + if (index < 0 || GetUsers().Count <= index) throw new IndexOutOfRangeException(); - } + + PersistentDataController.GetInstance().SetCurrentUser(index, true); } + /// /// Change the current user /// - /// Reference to the user in the userlist + /// Username of the user /// - public void ChangeCurrentUser(User user) + public static void ChangeCurrentUser(string username) { - int idx = storedUserList.storedUsers.IndexOf(user); - if (idx < 0) - { - throw new KeyNotFoundException(); - } - storedUserList.currentUserIndex = idx; - } - - /// - /// Remove the user - /// - /// The index of the user in the userlist - /// true if user was successful removed, false otherwise e.GetUsername() == username); + try { ChangeCurrentUser(index); } + catch (IndexOutOfRangeException) { throw new KeyNotFoundException(); } } /// /// I am inevitable, *snap* /// - /// Reference to the user to be removed + /// The index of the user in the userlist /// true if the user was successful removed, false otherwise - public bool DeleteUser(User user) + /// + public static bool DeleteUser(int index) { - if (1 < storedUserList.storedUsers.Count) - { - if (storedUserList.currentUserIndex == storedUserList.storedUsers.Count - 1) - { - storedUserList.currentUserIndex--; - } + List users = GetUsers(); + if (index < 0 || users.Count <= index) + throw new IndexOutOfRangeException(); - return storedUserList.storedUsers.Remove(user); + if (1 < users.Count) + { + PersistentDataController.GetInstance().DeleteUser(index); + return true; } return false; } /// - /// Save the users + /// Delete a user from the userliset /// - public void Save() + /// Username of the user + /// true if the user was successful removed, false otherwise + /// + public static bool DeleteUser(string username) { - string json = JsonUtility.ToJson(storedUserList); - File.CreateText(PATH).Close(); - File.WriteAllText(PATH, json); + int index = GetUsers().FindIndex((e) => e.GetUsername() == username); + + try { return DeleteUser(index); } + catch (IndexOutOfRangeException) { throw new KeyNotFoundException(); } } /// - /// Override the current content of the userlist by what is stored on disk + /// Save the current UserList /// - public void Load() + public static void Save() { - storedUserList.storedUsers.Clear(); - storedUserList.currentUserIndex = -1; - - if (!File.Exists(PATH)) - { - Save(); - } - string text = File.ReadAllText(PATH); - storedUserList = JsonUtility.FromJson(text); + PersistentDataController.GetInstance().Save(); } } diff --git a/Assets/Accounts/Scripts/UserProgressScreen.cs b/Assets/Accounts/Scripts/UserProgressScreen.cs index 7ccafdb..a89fcbb 100644 --- a/Assets/Accounts/Scripts/UserProgressScreen.cs +++ b/Assets/Accounts/Scripts/UserProgressScreen.cs @@ -10,11 +10,6 @@ using UnityEngine.UI; /// public class UserProgressScreen : MonoBehaviour { - /// - /// Reference to the userlist - /// - public UserList userList; - /// /// Reference to the current user /// @@ -112,12 +107,12 @@ public class UserProgressScreen : MonoBehaviour void Start() { // Assign the current user - userList.Load(); - user = userList.GetCurrentUser(); + PersistentDataController.GetInstance().Load(); + user = UserList.GetCurrentUser(); // Set correct displayed items - username.text = user.username; - avatar.sprite = user.avatar; + username.text = user.GetUsername(); + avatar.sprite = user.GetAvatar(); // TODO: implement total playtime //playtime.text = $"Totale speeltijd: {user.playtime.ToString("0.00")}"; @@ -126,9 +121,10 @@ public class UserProgressScreen : MonoBehaviour int i = 0; // Display courses - coursesContainer.SetActive(user.courses.Count > 0); - emptyCourses.SetActive(user.courses.Count <= 0); - foreach (Progress courseProgress in user.courses) + var courses = user.GetCourses(); + coursesContainer.SetActive(courses.Count > 0); + emptyCourses.SetActive(courses.Count <= 0); + foreach (var courseProgress in courses) { // Create instance of prefab GameObject instance = GameObject.Instantiate(courseCardPrefab, coursesContainer.transform.Find("Viewport").Find("Content").transform); @@ -142,13 +138,14 @@ public class UserProgressScreen : MonoBehaviour // Store reference to background so we can apply fancy coloring Image background = instance.GetComponent(); background.color = Color.gray; - activities.Add(Tuple.Create(background, (int)courseProgress.Get("courseIndex"))); + activities.Add(Tuple.Create(background, (int)courseProgress.courseIndex)); } // Display minigames - minigamesContainer.SetActive(user.minigames.Count > 0); - emptyMinigames.SetActive(user.minigames.Count <= 0); - foreach (Progress minigameProgress in user.minigames) + var minigames = user.GetMinigames(); + minigamesContainer.SetActive(minigames.Count > 0); + emptyMinigames.SetActive(minigames.Count <= 0); + foreach (var minigameProgress in minigames) { // Create instance of prefab GameObject instance = GameObject.Instantiate(minigameCardPrefab, minigamesContainer.transform.Find("Viewport").Find("Content").transform); @@ -162,7 +159,7 @@ public class UserProgressScreen : MonoBehaviour // Store reference to background so we can apply fancy coloring Image background = instance.GetComponent(); background.color = Color.gray; - activities.Add(Tuple.Create(background, (int)minigameProgress.Get("minigameIndex"))); + activities.Add(Tuple.Create(background, (int)minigameProgress.minigameIndex)); } } @@ -183,7 +180,7 @@ public class UserProgressScreen : MonoBehaviour selectedActivity = newActivity; activities[selectedActivity].Item1.color = Color.blue; - if (selectedActivity < user.courses.Count) + if (selectedActivity < user.GetCourses().Count) { // TODO: create a better graph //DisplayCourseGraph((CourseIndex)activities[selectedActivity].Item2); @@ -211,9 +208,9 @@ public class UserProgressScreen : MonoBehaviour /// Index of the minigame private void DisplayMinigameGraph(MinigameIndex minigameIndex) { - Progress progress = user.GetMinigameProgress(minigameIndex); - List latestScores = progress.Get>("latestScores"); - List highestScores = progress.Get>("highestScores"); + var progress = user.GetMinigameProgress(minigameIndex); + List latestScores = progress.latestScores; + List highestScores = progress.highestScores; if (0 < highestScores.Count) { PlotGraph(latestScores.ConvertAll((s) => (double)s.scoreValue), highestScores[0].scoreValue); diff --git a/Assets/Accounts/Tests/AccountsTests.asmdef b/Assets/Accounts/Tests/AccountsTests.asmdef index df1d734..5167069 100644 --- a/Assets/Accounts/Tests/AccountsTests.asmdef +++ b/Assets/Accounts/Tests/AccountsTests.asmdef @@ -5,7 +5,8 @@ "UnityEngine.TestRunner", "UnityEditor.TestRunner", "AccountsScripts", - "InterfacesScripts" + "InterfacesScripts", + "SystemArchitecture" ], "includePlatforms": [ "Editor" diff --git a/Assets/Accounts/Tests/ProgressTest.cs b/Assets/Accounts/Tests/ProgressTest.cs deleted file mode 100644 index 6500940..0000000 --- a/Assets/Accounts/Tests/ProgressTest.cs +++ /dev/null @@ -1,213 +0,0 @@ -using NUnit.Framework; -using System; -using System.Collections.Generic; -using System.Runtime.Serialization; -using UnityEngine; - -/// -/// Test the Progress class -/// -[TestFixture] -public class ProgressTest -{ - /// - /// Reference to the progress object to be tested - /// - private Progress progress; - - /// - /// A dummy serializable struct to perform test operations on - /// - [Serializable] - private struct SerializableStruct - { - public int r, g, b; - public float x, y, z; - } - - /// - /// A dummy non-serializable struct to perform test operations on - /// - private struct NonSerializableStruct - { - public int r, g, b; - public float x, y, z; - } - - /// - /// Setup the tests - /// - [SetUp] - public void Setup_Progress() - { - progress = new Progress(); - } - - /// - /// Test for creation of a new progress - /// - [Test] - public void Test_New_Progress() - { - Assert.IsNotNull(progress); - } - - /// - /// Test whether invalid data will not be added - /// - [Test] - public void Test_Progress_Add_InvalidData() - { - Assert.IsFalse(progress.AddOrUpdate("key", null)); - } - - /// - /// Test whether a duplicated key will be added - /// - [Test] - public void Test_Progress_Add_DuplicateKey() - { - progress.AddOrUpdate("key 1", 0); - Assert.IsTrue(progress.AddOrUpdate("key 1", 1)); - } - - /// - /// Test whether a int value can be added - /// - [Test] - public void Test_Progress_Add_Int() - { - Assert.IsTrue(progress.AddOrUpdate("key", 1)); - } - - /// - /// Test whether a double value can be added - /// - [Test] - public void Test_Progress_Add_Double() - { - Assert.IsTrue(progress.AddOrUpdate("key", 1.0)); - } - - /// - /// Test whether a string value can be added - /// - [Test] - public void Test_Progress_Add_String() - { - Assert.IsTrue(progress.AddOrUpdate("key", "Hello World!")); - } - - /// - /// Test whether a serializable struct can be added - /// - [Test] - public void Test_Progress_Add_SerializableStruct() - { - Assert.IsTrue(progress.AddOrUpdate("key", new SerializableStruct())); - } - - /// - /// Test whether a non-serializable struct will throw an error - /// - [Test] - public void Test_Progress_Add_NonSerializableStruct() - { - NonSerializableStruct nss = new NonSerializableStruct(); - Assert.Throws(delegate { progress.AddOrUpdate("key", nss); }); - } - - /// - /// Test whether a key is present - /// - [Test] - public void Test_Progress_Has_ValidKey() - { - progress.AddOrUpdate("key", 1); - Assert.IsTrue(progress.Has("key")); - } - - /// - /// Test whether a key is not present - /// - [Test] - public void Test_Progress_Has_InvalidKey() - { - Assert.IsFalse(progress.Has("non-existing key")); - } - - /// - /// Test whether an invalid key will throw an error - /// - [Test] - public void Test_Progress_Get_InvalidKey() - { - Assert.Throws(delegate { progress.Get("non-existing key"); }); - } - - /// - /// Test whether an invalid type will throw an error - /// - [Test] - public void Test_Progress_Get_InvalidType() - { - progress.AddOrUpdate("key", 123456789); - Assert.Throws(delegate { progress.Get("key"); }); - } - - /// - /// Test whether a value is correctly updated - /// - [Test] - public void Test_Progress_Update() - { - progress.AddOrUpdate("key", 1); - Assert.AreEqual(progress.Get("key"), 1); - progress.AddOrUpdate("key", 2); - Assert.AreEqual(progress.Get("key"), 2); - } - - /// - /// Test whether a int value can be read - /// - [Test] - public void Test_Progress_Get_Int() - { - progress.AddOrUpdate("key", 1); - Assert.AreEqual(progress.Get("key"), 1); - } - - /// - /// Test whether a double value can be read - /// - [Test] - public void Test_Progress_Get_Double() - { - progress.AddOrUpdate("key", 1.0); - Assert.AreEqual(progress.Get("key"), 1.0); - } - - /// - /// Test whether a string value can be read - /// - [Test] - public void Test_Progress_Get_String() - { - progress.AddOrUpdate("key", "Hello World!"); - Assert.AreEqual(progress.Get("key"), "Hello World!"); - } - - /// - /// Test whether a serializable struct can be read - /// - [Test] - public void Test_Progress_Get_Struct() - { - int R = 1, G = 10, B = 100; - float X = 0.1f, Y = 0.01f, Z = 0.001f; - SerializableStruct data = new SerializableStruct { r = R, g = G, b = B, x = X, y = Y, z = Z }; - progress.AddOrUpdate("key", data); - SerializableStruct result = progress.Get("key"); - Assert.AreEqual(result, data); - } -} diff --git a/Assets/Accounts/Tests/UserListTest.cs b/Assets/Accounts/Tests/UserListTest.cs index 4adff57..faef19b 100644 --- a/Assets/Accounts/Tests/UserListTest.cs +++ b/Assets/Accounts/Tests/UserListTest.cs @@ -1,8 +1,8 @@ using NUnit.Framework; using System; -using System.Collections; using System.Collections.Generic; using System.IO; +using UnityEditor; using UnityEngine; /// @@ -12,20 +12,10 @@ using UnityEngine; public class UserListTest { /// - /// Create a new path so the existing users.json file will not be overwritten + /// Create a new path so the existing .json file will not be overwritten /// private static string PATH = $"{Application.persistentDataPath}/unit_test_users.json"; - /// - /// NUnit test magic (for skipping the setup) - /// - public const string SKIP_SETUP = "SKIP_SETUP"; - - /// - /// Reference to the userlist to be tested - /// - private UserList userList; - /// /// Helper variable for quick user creation /// @@ -34,11 +24,7 @@ public class UserListTest /// /// Helper variable for quick user creation /// - private Sprite avatar = Sprite.Create( - Texture2D.blackTexture, - new Rect(0, 0, Texture2D.blackTexture.width, Texture2D.blackTexture.height), - new Vector2(0.5f, 0.5f) - ); + private Sprite avatar = null; /// /// Setup the tests @@ -46,27 +32,14 @@ public class UserListTest [SetUp] public void Setup_UserList() { - // Check whether the current test needs to skip the setup - ArrayList cat = TestContext.CurrentContext.Test.Properties["_CATEGORIES"] as ArrayList; - bool skip = cat != null && cat.Contains(SKIP_SETUP); - if (!skip) - { - // The actual setup code - UserList.PATH = UserListTest.PATH; - userList = ScriptableObject.CreateInstance(); - } - } + PersistentDataController.PATH = UserListTest.PATH; - /// - /// Test whether the UserList.PATH is correctly set - /// - [Test] - [Category(SKIP_SETUP)] - public void Test_UserList_OnEnable() - { - UserList.PATH = null; - userList = ScriptableObject.CreateInstance(); - Assert.AreEqual($"{Application.persistentDataPath}/users.json", UserList.PATH); + if (File.Exists(PATH)) + File.Delete(PATH); + + PersistentDataController.GetInstance().Load(); + AssetDatabase.LoadAssetAtPath("Assets/Accounts/ScriptableObjects/UserAvatarList.asset").Awake(); + avatar = UserList.AVATARS[0]; } /// @@ -75,36 +48,22 @@ public class UserListTest [Test] public void Test_New_UserList() { - Assert.IsNotNull(userList); - Assert.Zero(userList.GetUsers().Count); + Assert.Zero(UserList.GetUsers().Count); } /// /// Test for creation of new user (without adding the user to the list) /// [Test] - public void Test_UserList_CreateNewUser() + public void Test_UserList_AddUser() { - User user = userList.CreateNewUser(username, avatar); + Assert.Zero(UserList.GetUsers().Count); + User user = UserList.AddUser(username, avatar); Assert.IsNotNull(user); - Assert.Zero(userList.GetUsers().Count); - Assert.AreEqual(username, user.username); - Assert.AreEqual(avatar, user.avatar); - } - - /// - /// Test for creating a new user and adding the user to the list - /// - public void Test_UserList_CreateAndAddNewUser() - { - Assert.AreEqual(-1, userList.GetCurrentUserIndex()); - User user = userList.CreateAndAddNewUser(username, avatar); - - Assert.IsNotNull(user); - Assert.AreEqual(1, userList.GetUsers().Count); - Assert.AreEqual(user, userList.GetUsers()[0]); - Assert.Zero(userList.GetCurrentUserIndex()); + Assert.AreEqual(1, UserList.GetUsers().Count); + Assert.AreEqual(username, user.GetUsername()); + Assert.AreEqual(avatar, user.GetAvatar()); } /// @@ -113,9 +72,9 @@ public class UserListTest [Test] public void Test_UserList_GetUserByUsername_Valid() { - User u = userList.CreateAndAddNewUser(username, avatar); - User v = userList.GetUserByUsername(username); - Assert.AreEqual(u, v); + User u = UserList.AddUser(username, avatar); + User v = UserList.GetUserByUsername(username); + Assert.AreEqual(u.GetUsername(), v.GetUsername()); } /// @@ -124,32 +83,70 @@ public class UserListTest [Test] public void Test_UserList_GetUserByUsername_Null() { - User user = userList.GetUserByUsername("not-a-user"); + User user = UserList.GetUserByUsername("not-a-user"); Assert.IsNull(user); } + + + /// + /// Test whether an existing user can be found by its username + /// + [Test] + public void Test_UserList_GetUserByIndex_Valid() + { + User u = UserList.AddUser(username, avatar); + User v = UserList.GetUserByIndex(0); + Assert.AreEqual(u.GetUsername(), v.GetUsername()); + } + + /// + /// Test whether a non-existing user can not be found + /// + [Test] + public void Test_UserList_GetUserByIndex_Exception() + { + Assert.Throws(delegate { UserList.GetUserByIndex(0); }); + } + + /// + /// Test whether a userlist is correctly returned + /// + [Test] + public void Test_UserList_GetUsers() + { + List u = new List(); + for (int i = 0; i < 5; i++) + u.Add(UserList.AddUser($"{username}_{i}", avatar)); + + List v = UserList.GetUsers(); + Assert.AreEqual(v.Count, u.Count); + for (int i = 0; i < 5; i++) + Assert.AreEqual(u[i].GetUsername(), v[i].GetUsername()); + } + /// /// Test whether the correct current user is returned /// [Test] public void Test_UserList_GetCurrentUser() { - User u = userList.CreateAndAddNewUser($"{username}_{'u'}", avatar); - User v = userList.CreateAndAddNewUser($"{username}_{'v'}", avatar); - User w = userList.CreateAndAddNewUser($"{username}_{'w'}", avatar); - userList.ChangeCurrentUser(2); + User u = UserList.AddUser($"{username}_{'u'}", avatar); + User v = UserList.AddUser($"{username}_{'v'}", avatar); + User w = UserList.AddUser($"{username}_{'w'}", avatar); + UserList.ChangeCurrentUser(2); - User W = userList.GetCurrentUser(); - Assert.AreEqual(w, W); + User W = UserList.GetCurrentUser(); + Assert.AreEqual(w.GetUsername(), W.GetUsername()); } /// /// Test whether a null user is returned when the userlist is empty /// [Test] - public void Test_UserList_GetCurrent_Empty() + public void Test_UserList_GetCurrentUser_Empty() { - User user = userList.GetCurrentUser(); + User user = UserList.GetCurrentUser(); Assert.IsNull(user); } @@ -157,24 +154,30 @@ public class UserListTest /// Test whether the correct index is returned for the current user /// [Test] - public void Test_UserList_GetCurrentUserIndex() + public void Test_UserList_IndexOf_Valid() { - User u = userList.CreateAndAddNewUser($"{username}_{'u'}", avatar); - User v = userList.CreateAndAddNewUser($"{username}_{'v'}", avatar); - User w = userList.CreateAndAddNewUser($"{username}_{'w'}", avatar); - userList.ChangeCurrentUser(2); + User u = UserList.AddUser($"{username}_{'u'}", avatar); + User v = UserList.AddUser($"{username}_{'v'}", avatar); + User w = UserList.AddUser($"{username}_{'w'}", avatar); + UserList.ChangeCurrentUser(2); - int idx = userList.GetCurrentUserIndex(); - Assert.AreEqual(2, idx); + Assert.AreEqual(0, UserList.IndexOf(u.GetUsername())); + Assert.AreEqual(1, UserList.IndexOf(v.GetUsername())); + Assert.AreEqual(2, UserList.IndexOf(w.GetUsername())); } /// - /// Test whether a bad index is returned when the userlist is empty + /// Test whether the correct index is returned for the current user /// [Test] - public void Test_UserList_GetCurrentUserIndex_Empty() + public void Test_UserList_IndexOf_Exception() { - Assert.AreEqual(-1, userList.GetCurrentUserIndex()); + User u = new User(new PersistentDataController.SavedUserData() + { + username = username, + avatarIndex = 0 + }); + Assert.Throws(delegate { UserList.IndexOf(u.GetUsername()); }); } /// @@ -183,13 +186,13 @@ public class UserListTest [Test] public void Test_UserList_ChangeCurrentUser_ValidIndex() { - User u = userList.CreateAndAddNewUser($"{username}_{'u'}", avatar); - User v = userList.CreateAndAddNewUser($"{username}_{'v'}", avatar); - User w = userList.CreateAndAddNewUser($"{username}_{'w'}", avatar); - userList.ChangeCurrentUser(2); + User u = UserList.AddUser($"{username}_{'u'}", avatar); + User v = UserList.AddUser($"{username}_{'v'}", avatar); + User w = UserList.AddUser($"{username}_{'w'}", avatar); + UserList.ChangeCurrentUser(2); - User W = userList.GetCurrentUser(); - Assert.AreEqual(w, W); + User W = UserList.GetCurrentUser(); + Assert.AreEqual(w.GetUsername(), W.GetUsername()); } /// @@ -198,11 +201,11 @@ public class UserListTest [Test] public void Test_UserList_ChangeCurrentUser_InvalidIndex() { - User u = userList.CreateAndAddNewUser($"{username}_{'u'}", avatar); - User v = userList.CreateAndAddNewUser($"{username}_{'v'}", avatar); - User w = userList.CreateAndAddNewUser($"{username}_{'w'}", avatar); - Assert.Throws(delegate { userList.ChangeCurrentUser(-1); }); - Assert.Throws(delegate { userList.ChangeCurrentUser(5); }); + User u = UserList.AddUser($"{username}_{'u'}", avatar); + User v = UserList.AddUser($"{username}_{'v'}", avatar); + User w = UserList.AddUser($"{username}_{'w'}", avatar); + Assert.Throws(delegate { UserList.ChangeCurrentUser(-1); }); + Assert.Throws(delegate { UserList.ChangeCurrentUser(5); }); } /// @@ -211,41 +214,45 @@ public class UserListTest [Test] public void Test_UserList_ChangeCurrentUser_IndexEmpty() { - Assert.Throws(delegate { userList.ChangeCurrentUser(0); }); + Assert.Throws(delegate { UserList.ChangeCurrentUser(0); }); } /// /// Test whether the current user is correctly changed /// [Test] - public void Test_UserList_ChangeCurrentUser_ValidUser() + public void Test_UserList_ChangeCurrentUser_ValidUsername() { - User u = userList.CreateAndAddNewUser($"{username}_{'u'}", avatar); - User v = userList.CreateAndAddNewUser($"{username}_{'v'}", avatar); - User w = userList.CreateAndAddNewUser($"{username}_{'w'}", avatar); - userList.ChangeCurrentUser(v); - User V = userList.GetCurrentUser(); - Assert.AreEqual(v, V); + User u = UserList.AddUser($"{username}_{'u'}", avatar); + User v = UserList.AddUser($"{username}_{'v'}", avatar); + User w = UserList.AddUser($"{username}_{'w'}", avatar); + UserList.ChangeCurrentUser(v.GetUsername()); + User V = UserList.GetCurrentUser(); + Assert.AreEqual(v.GetUsername(), V.GetUsername()); } /// /// Test whether the current user is not changed when a non-existing user is given /// [Test] - public void Test_UserList_ChangeCurrentUser_InvalidUser() + public void Test_UserList_ChangeCurrentUser_InvalidUsername() { - User u = userList.CreateAndAddNewUser($"{username}_{'u'}", avatar); - User v = userList.CreateNewUser($"{username}_{'v'}", avatar); - Assert.Throws(delegate { userList.ChangeCurrentUser(v); }); + User u = UserList.AddUser($"{username}_{'u'}", avatar); + User v = new User(new PersistentDataController.SavedUserData() + { + username = $"{username}_{'v'}", + avatarIndex = 0 + }); + Assert.Throws(delegate { UserList.ChangeCurrentUser(v.GetUsername()); }); } /// /// Test whether the current user is not changed when a null user is given /// [Test] - public void Test_UserList_ChangeCurrentUser_NullUser() + public void Test_UserList_ChangeCurrentUser_NullUsername() { - Assert.Throws(delegate { userList.ChangeCurrentUser(null); }); + Assert.Throws(delegate { UserList.ChangeCurrentUser(null); }); } /// @@ -254,10 +261,10 @@ public class UserListTest [Test] public void Test_UserList_DeleteUser_ValidIndex() { - User u = userList.CreateAndAddNewUser($"{username}_{'u'}", avatar); - User v = userList.CreateAndAddNewUser($"{username}_{'v'}", avatar); - User w = userList.CreateAndAddNewUser($"{username}_{'w'}", avatar); - Assert.IsTrue(userList.DeleteUser(1)); + User u = UserList.AddUser($"{username}_{'u'}", avatar); + User v = UserList.AddUser($"{username}_{'v'}", avatar); + User w = UserList.AddUser($"{username}_{'w'}", avatar); + Assert.IsTrue(UserList.DeleteUser(1)); } /// @@ -266,11 +273,11 @@ public class UserListTest [Test] public void Test_UserList_DeleteUser_InValidIndex() { - User u = userList.CreateAndAddNewUser($"{username}_{'u'}", avatar); - User v = userList.CreateAndAddNewUser($"{username}_{'v'}", avatar); - User w = userList.CreateAndAddNewUser($"{username}_{'w'}", avatar); - Assert.IsFalse(userList.DeleteUser(-1)); - Assert.IsFalse(userList.DeleteUser(5)); + User u = UserList.AddUser($"{username}_{'u'}", avatar); + User v = UserList.AddUser($"{username}_{'v'}", avatar); + User w = UserList.AddUser($"{username}_{'w'}", avatar); + Assert.Throws(delegate { UserList.DeleteUser(-1); }); + Assert.Throws(delegate { UserList.DeleteUser(5); }); } /// @@ -279,44 +286,61 @@ public class UserListTest [Test] public void Test_UserList_DeleteUser_IndexEmpty() { - Assert.IsFalse(userList.DeleteUser(0)); + Assert.Throws(delegate { UserList.DeleteUser(0); }); } /// /// Test whether deleting an existing user will correctly remove the user and set the currentUserIndex correctly /// [Test] - public void Test_UserList_DeleteUser_LastValid() + public void Test_UserList_DeleteUser_BeforeCurrentUser() { - User u = userList.CreateAndAddNewUser($"{username}_{'u'}", avatar); - User v = userList.CreateAndAddNewUser($"{username}_{'v'}", avatar); - User w = userList.CreateAndAddNewUser($"{username}_{'w'}", avatar); - userList.ChangeCurrentUser(2); + User u = UserList.AddUser($"{username}_{'u'}", avatar); + User v = UserList.AddUser($"{username}_{'v'}", avatar); + User w = UserList.AddUser($"{username}_{'w'}", avatar); + UserList.ChangeCurrentUser(1); - Assert.AreEqual(3, userList.GetUsers().Count); - Assert.AreEqual(2, userList.GetCurrentUserIndex()); - Assert.IsTrue(userList.DeleteUser(w)); - Assert.AreEqual(2, userList.GetUsers().Count); - Assert.AreEqual(1, userList.GetCurrentUserIndex()); + Assert.AreEqual(3, UserList.GetUsers().Count); + Assert.AreEqual(1, UserList.IndexOf(UserList.GetCurrentUser().GetUsername())); + Assert.IsTrue(UserList.DeleteUser(u.GetUsername())); + Assert.AreEqual(2, UserList.GetUsers().Count); + Assert.AreEqual(0, UserList.IndexOf(UserList.GetCurrentUser().GetUsername())); } /// - /// Test whether deleting an existing user will remove the user correctly + /// Test whether deleting an existing user will correctly remove the user and set the currentUserIndex correctly /// - /// This will change the currentUserIndex to point to another user [Test] - public void Test_UserList_DeleteUser_FirstValid() + public void Test_UserList_DeleteUser_CurrentUser() { - User u = userList.CreateAndAddNewUser($"{username}_{'u'}", avatar); - User v = userList.CreateAndAddNewUser($"{username}_{'v'}", avatar); - User w = userList.CreateAndAddNewUser($"{username}_{'w'}", avatar); - userList.ChangeCurrentUser(0); + User u = UserList.AddUser($"{username}_{'u'}", avatar); + User v = UserList.AddUser($"{username}_{'v'}", avatar); + User w = UserList.AddUser($"{username}_{'w'}", avatar); + UserList.ChangeCurrentUser(1); - Assert.AreEqual(3, userList.GetUsers().Count); - Assert.AreEqual(0, userList.GetCurrentUserIndex()); - Assert.IsTrue(userList.DeleteUser(u)); - Assert.AreEqual(2, userList.GetUsers().Count); - Assert.AreEqual(0, userList.GetCurrentUserIndex()); + Assert.AreEqual(3, UserList.GetUsers().Count); + Assert.AreEqual(1, UserList.IndexOf(UserList.GetCurrentUser().GetUsername())); + Assert.IsTrue(UserList.DeleteUser(v.GetUsername())); + Assert.AreEqual(2, UserList.GetUsers().Count); + Assert.AreEqual(0, UserList.IndexOf(UserList.GetCurrentUser().GetUsername())); + } + + /// + /// Test whether deleting an existing user will correctly remove the user and set the currentUserIndex correctly + /// + [Test] + public void Test_UserList_DeleteUser_AfterCurrentUser() + { + User u = UserList.AddUser($"{username}_{'u'}", avatar); + User v = UserList.AddUser($"{username}_{'v'}", avatar); + User w = UserList.AddUser($"{username}_{'w'}", avatar); + UserList.ChangeCurrentUser(1); + + Assert.AreEqual(3, UserList.GetUsers().Count); + Assert.AreEqual(1, UserList.IndexOf(UserList.GetCurrentUser().GetUsername())); + Assert.IsTrue(UserList.DeleteUser(w.GetUsername())); + Assert.AreEqual(2, UserList.GetUsers().Count); + Assert.AreEqual(1, UserList.IndexOf(UserList.GetCurrentUser().GetUsername())); } /// @@ -325,12 +349,16 @@ public class UserListTest [Test] public void Test_UserList_DeleteUser_Invalid() { - User u = userList.CreateAndAddNewUser($"{username}_{'u'}", avatar); - User v = userList.CreateNewUser($"{username}_{'v'}", avatar); + User u = UserList.AddUser($"{username}_{'u'}", avatar); + User v = new User(new PersistentDataController.SavedUserData() + { + username = $"{username}_{'v'}", + avatarIndex = 0 + }); - Assert.AreEqual(1, userList.GetUsers().Count); - Assert.IsFalse(userList.DeleteUser(v)); - Assert.AreEqual(1, userList.GetUsers().Count); + Assert.AreEqual(1, UserList.GetUsers().Count); + Assert.Throws(delegate { UserList.DeleteUser(v.GetUsername()); }); + Assert.AreEqual(1, UserList.GetUsers().Count); } /// @@ -339,10 +367,14 @@ public class UserListTest [Test] public void Test_UserList_DeleteUser_Empty() { - User user = userList.CreateNewUser(username, avatar); - Assert.Zero(userList.GetUsers().Count); - Assert.IsFalse(userList.DeleteUser(user)); - Assert.Zero(userList.GetUsers().Count); + User user = new User(new PersistentDataController.SavedUserData() + { + username = username, + avatarIndex = 0 + }); + Assert.Zero(UserList.GetUsers().Count); + Assert.Throws(delegate { UserList.DeleteUser(user.GetUsername()); }); + Assert.Zero(UserList.GetUsers().Count); } /// @@ -351,23 +383,16 @@ public class UserListTest [Test] public void Test_UserList_Save_New() { - if (File.Exists(PATH)) - { - File.Delete(PATH); - } - List u = new List(); for (int i = 0; i < 5; i++) - { - u.Add(userList.CreateAndAddNewUser($"{username}_{i}", avatar)); - } - userList.ChangeCurrentUser(3); - userList.Save(); + u.Add(UserList.AddUser($"{username}_{i}", avatar)); + + UserList.ChangeCurrentUser(3); + UserList.Save(); FileAssert.Exists(PATH); string content = File.ReadAllText(PATH); - int id = avatar.GetInstanceID(); - string expected = $"{{\"currentUserIndex\":3,\"storedUsers\":[{{\"username\":\"u5erNam3_0\",\"avatar\":{{\"instanceID\":{id}}},\"playtime\":0.0,\"courses\":[],\"minigames\":[]}},{{\"username\":\"u5erNam3_1\",\"avatar\":{{\"instanceID\":{id}}},\"playtime\":0.0,\"courses\":[],\"minigames\":[]}},{{\"username\":\"u5erNam3_2\",\"avatar\":{{\"instanceID\":{id}}},\"playtime\":0.0,\"courses\":[],\"minigames\":[]}},{{\"username\":\"u5erNam3_3\",\"avatar\":{{\"instanceID\":{id}}},\"playtime\":0.0,\"courses\":[],\"minigames\":[]}},{{\"username\":\"u5erNam3_4\",\"avatar\":{{\"instanceID\":{id}}},\"playtime\":0.0,\"courses\":[],\"minigames\":[]}}]}}"; + string expected = $"{{\"version\":{PersistentDataController.VERSION},\"users\":[{{\"entries\":[],\"username\":\"u5erNam3_0\",\"avatarIndex\":0,\"playtime\":0.0,\"minigames\":[],\"courses\":[]}},{{\"entries\":[],\"username\":\"u5erNam3_1\",\"avatarIndex\":0,\"playtime\":0.0,\"minigames\":[],\"courses\":[]}},{{\"entries\":[],\"username\":\"u5erNam3_2\",\"avatarIndex\":0,\"playtime\":0.0,\"minigames\":[],\"courses\":[]}},{{\"entries\":[],\"username\":\"u5erNam3_3\",\"avatarIndex\":0,\"playtime\":0.0,\"minigames\":[],\"courses\":[]}},{{\"entries\":[],\"username\":\"u5erNam3_4\",\"avatarIndex\":0,\"playtime\":0.0,\"minigames\":[],\"courses\":[]}}],\"currentUser\":3,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; Assert.AreEqual(expected, content); } @@ -385,16 +410,14 @@ public class UserListTest List u = new List(); for (int i = 0; i < 5; i++) - { - u.Add(userList.CreateAndAddNewUser($"{username}_{i}", avatar)); - } - userList.ChangeCurrentUser(3); - userList.Save(); + u.Add(UserList.AddUser($"{username}_{i}", avatar)); + + UserList.ChangeCurrentUser(3); + UserList.Save(); FileAssert.Exists(PATH); string content = File.ReadAllText(PATH); - int id = avatar.GetInstanceID(); - string expected = $"{{\"currentUserIndex\":3,\"storedUsers\":[{{\"username\":\"u5erNam3_0\",\"avatar\":{{\"instanceID\":{id}}},\"playtime\":0.0,\"courses\":[],\"minigames\":[]}},{{\"username\":\"u5erNam3_1\",\"avatar\":{{\"instanceID\":{id}}},\"playtime\":0.0,\"courses\":[],\"minigames\":[]}},{{\"username\":\"u5erNam3_2\",\"avatar\":{{\"instanceID\":{id}}},\"playtime\":0.0,\"courses\":[],\"minigames\":[]}},{{\"username\":\"u5erNam3_3\",\"avatar\":{{\"instanceID\":{id}}},\"playtime\":0.0,\"courses\":[],\"minigames\":[]}},{{\"username\":\"u5erNam3_4\",\"avatar\":{{\"instanceID\":{id}}},\"playtime\":0.0,\"courses\":[],\"minigames\":[]}}]}}"; + string expected = $"{{\"version\":{PersistentDataController.VERSION},\"users\":[{{\"entries\":[],\"username\":\"u5erNam3_0\",\"avatarIndex\":0,\"playtime\":0.0,\"minigames\":[],\"courses\":[]}},{{\"entries\":[],\"username\":\"u5erNam3_1\",\"avatarIndex\":0,\"playtime\":0.0,\"minigames\":[],\"courses\":[]}},{{\"entries\":[],\"username\":\"u5erNam3_2\",\"avatarIndex\":0,\"playtime\":0.0,\"minigames\":[],\"courses\":[]}},{{\"entries\":[],\"username\":\"u5erNam3_3\",\"avatarIndex\":0,\"playtime\":0.0,\"minigames\":[],\"courses\":[]}},{{\"entries\":[],\"username\":\"u5erNam3_4\",\"avatarIndex\":0,\"playtime\":0.0,\"minigames\":[],\"courses\":[]}}],\"currentUser\":3,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; Assert.AreEqual(expected, content); } @@ -404,67 +427,11 @@ public class UserListTest [Test] public void Test_UserList_Save_Empty() { - userList.Save(); + UserList.Save(); FileAssert.Exists(PATH); string content = File.ReadAllText(PATH); - string expected = "{\"currentUserIndex\":-1,\"storedUsers\":[]}"; + string expected = $"{{\"version\":{PersistentDataController.VERSION},\"users\":[],\"currentUser\":-1,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; Assert.AreEqual(expected, content); } - - /// - /// Test whether a userlist (containing some users) is correrctly loaded - /// - [Test] - public void Test_UserList_Load() - { - List u = new List(); - for (int i = 0; i < 5; i++) - { - u.Add(userList.CreateAndAddNewUser($"{username}_{i}", avatar)); - } - userList.ChangeCurrentUser(3); - userList.Save(); - - userList.Load(); - Assert.AreEqual(userList.GetUsers().Count, u.Count); - Assert.AreEqual(userList.GetCurrentUserIndex(), 3); - List v = userList.GetUsers(); - for (int i = 0; i < 5; i++) - { - Assert.AreEqual(u[i].username, v[i].username); - Assert.AreEqual(u[i].avatar, v[i].avatar); - } - } - - /// - /// Test whether an empty userlist is correctly loaded - /// - [Test] - public void Test_UserList_Load_Empty() - { - userList.Save(); - userList.Load(); - Assert.Zero(userList.GetUsers().Count); - Assert.AreEqual(-1, userList.GetCurrentUserIndex()); - } - - /// - /// Test if the user save file is not found, a new one will be created and an empty userlist will be loaded - /// - [Test] - public void Test_UserList_Load_NotFound() - { - List u = new List(); - for (int i = 0; i < 5; i++) - { - u.Add(userList.CreateAndAddNewUser($"{username}_{i}", avatar)); - } - userList.ChangeCurrentUser(3); - userList.Save(); - - File.Delete(PATH); - userList.Load(); - Assert.Zero(userList.GetUsers().Count); - } } diff --git a/Assets/Accounts/Tests/UserTest.cs b/Assets/Accounts/Tests/UserTest.cs index 81d4045..fd605dc 100644 --- a/Assets/Accounts/Tests/UserTest.cs +++ b/Assets/Accounts/Tests/UserTest.cs @@ -19,7 +19,10 @@ public class UserTest [SetUp] public void Setup_User() { - user = new User(); + PersistentDataController.SavedUserData data = new PersistentDataController.SavedUserData(); + data.username = "username"; + data.avatarIndex = 0; + user = new User(data); } @@ -30,8 +33,8 @@ public class UserTest public void Test_New_User() { Assert.NotNull(user); - Assert.Zero(user.courses.Count); - Assert.Zero(user.minigames.Count); + Assert.Zero(user.GetCourses().Count); + Assert.Zero(user.GetMinigames().Count); } /// @@ -40,10 +43,10 @@ public class UserTest [Test] public void Test_User_AddCourse() { - Progress p = new Progress(); - user.courses.Add(p); - Assert.AreEqual(user.courses.Count, 1); - Assert.Zero(user.minigames.Count); + var p = new PersistentDataController.SavedCourseProgress(); + user.AddCourseProgress(p); + Assert.AreEqual(user.GetCourses().Count, 1); + Assert.Zero(user.GetMinigames().Count); } /// @@ -52,10 +55,10 @@ public class UserTest [Test] public void Test_User_AddMinigame() { - Progress p = new Progress(); - user.minigames.Add(p); - Assert.Zero(user.courses.Count); - Assert.AreEqual(user.minigames.Count, 1); + var p = new PersistentDataController.SavedMinigameProgress(); + user.AddMinigameProgress(p); + Assert.Zero(user.GetCourses().Count); + Assert.AreEqual(user.GetMinigames().Count, 1); } /// @@ -73,10 +76,10 @@ public class UserTest [Test] public void Test_User_GetRecentCourses_All() { - Progress p = new Progress(); - p.AddOrUpdate("courseIndex", CourseIndex.FINGERSPELLING); - p.AddOrUpdate("courseProgress", 0.5f); - user.courses.Add(p); + var p = new PersistentDataController.SavedCourseProgress(); + p.courseIndex = CourseIndex.FINGERSPELLING; + p.progress = 0.5f; + user.AddCourseProgress(p); List> list = user.GetRecentCourses(); Assert.AreEqual(list.Count, 1); Assert.AreEqual(list[0].Item1, CourseIndex.FINGERSPELLING); @@ -101,10 +104,10 @@ public class UserTest [Test] public void Test_User_GetRecommendedCourses_All() { - Progress p = new Progress(); - p.AddOrUpdate("courseIndex", CourseIndex.FINGERSPELLING); - p.AddOrUpdate("courseProgress", 0.5f); - user.courses.Add(p); + var p = new PersistentDataController.SavedCourseProgress(); + p.courseIndex = CourseIndex.FINGERSPELLING; + p.progress = 0.5f; + user.AddCourseProgress(p); List> list = user.GetRecommendedCourses(); Assert.AreEqual(list.Count, 1); Assert.AreEqual(list[0].Item1, CourseIndex.FINGERSPELLING); @@ -127,13 +130,13 @@ public class UserTest [Test] public void Test_User_GetCourseProgress_Valid() { - Progress p = new Progress(); - p.AddOrUpdate("courseIndex", CourseIndex.FINGERSPELLING); - p.AddOrUpdate("courseProgress", 3.14159265f); - user.courses.Add(p); - Progress q = user.GetCourseProgress(CourseIndex.FINGERSPELLING); - Assert.AreEqual(q.Get("courseIndex"), CourseIndex.FINGERSPELLING); - Assert.AreEqual(q.Get("courseProgress"), 3.14159265f); + var p = new PersistentDataController.SavedCourseProgress(); + p.courseIndex = CourseIndex.FINGERSPELLING; + p.progress = 3.14159265f; + user.AddCourseProgress(p); + var q = user.GetCourseProgress(CourseIndex.FINGERSPELLING); + Assert.AreEqual(q.courseIndex, CourseIndex.FINGERSPELLING); + Assert.AreEqual(q.progress, 3.14159265f); } /// @@ -145,9 +148,9 @@ public class UserTest Assert.Null(user.GetMinigameProgress(MinigameIndex.SPELLING_BEE)); Assert.Null(user.GetMinigameProgress((MinigameIndex)100)); - Progress p = new Progress(); - p.AddOrUpdate("minigameIndex", MinigameIndex.SPELLING_BEE); - user.minigames.Add(p); + var p = new PersistentDataController.SavedMinigameProgress(); + p.minigameIndex = MinigameIndex.SPELLING_BEE; + user.AddMinigameProgress(p); Assert.Null(user.GetMinigameProgress(MinigameIndex.HANGMAN)); } @@ -157,10 +160,12 @@ public class UserTest [Test] public void Test_User_GetMinigameProgress_Valid() { - Progress p = new Progress(); - p.AddOrUpdate("minigameIndex", MinigameIndex.SPELLING_BEE); - user.minigames.Add(p); - Progress q = user.GetMinigameProgress(MinigameIndex.SPELLING_BEE); - Assert.AreEqual(q.Get("minigameIndex"), CourseIndex.FINGERSPELLING); + var p = new PersistentDataController.SavedMinigameProgress(); + p.minigameIndex = MinigameIndex.SPELLING_BEE; + user.AddMinigameProgress(p); + var q = user.GetMinigameProgress(MinigameIndex.SPELLING_BEE); + Assert.AreEqual(q.minigameIndex, MinigameIndex.SPELLING_BEE); + Assert.Zero(q.latestScores.Count); + Assert.Zero(q.highestScores.Count); } } diff --git a/Assets/Common/Images/Animals/dolfijn.png.meta b/Assets/Common/Images/Animals/dolfijn.png.meta index 2c61f14..4b57023 100644 --- a/Assets/Common/Images/Animals/dolfijn.png.meta +++ b/Assets/Common/Images/Animals/dolfijn.png.meta @@ -113,6 +113,18 @@ TextureImporter: overridden: 0 androidETC2FallbackOverride: 0 forceMaximumCompressionQuality_BC6H_BC7: 0 + - serializedVersion: 3 + buildTarget: Windows Store Apps + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 spriteSheet: serializedVersion: 2 sprites: [] diff --git a/Assets/Common/Interfaces.meta b/Assets/Common/Interfaces.meta index 5b0f200..75557e1 100644 --- a/Assets/Common/Interfaces.meta +++ b/Assets/Common/Interfaces.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: f3e4df0d6e02ad2f0905d1614f2e6545 +guid: 06c24ca85a8bc6b4d947cdb9b2492e99 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/Common/Interfaces/CourseList.cs b/Assets/Common/Interfaces/CourseList.cs index ce2908a..a5f7e2b 100644 --- a/Assets/Common/Interfaces/CourseList.cs +++ b/Assets/Common/Interfaces/CourseList.cs @@ -4,7 +4,7 @@ using UnityEngine; /// /// Keep track of all courses /// -[CreateAssetMenu(menuName = "Create new Scriptable/CourseList")] +[CreateAssetMenu(menuName = "Create new Scriptable/Course List")] public class CourseList : ScriptableObject { /// diff --git a/Assets/Common/Interfaces/InterfacesScripts.asmdef b/Assets/Common/Interfaces/InterfacesScripts.asmdef index b05c2ef..71360c2 100644 --- a/Assets/Common/Interfaces/InterfacesScripts.asmdef +++ b/Assets/Common/Interfaces/InterfacesScripts.asmdef @@ -2,8 +2,8 @@ "name": "InterfacesScripts", "rootNamespace": "", "references": [ - "GUID:5c2b5ba89f9e74e418232e154bc5cc7a", - "GUID:d23f64cfd3b314bb4a18a8284c99bf5e" + "GUID:d23f64cfd3b314bb4a18a8284c99bf5e", + "GUID:e83ddf9a537a96b4a804a16bb7872ec1" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Assets/Common/Interfaces/MinigameList.cs b/Assets/Common/Interfaces/MinigameList.cs index 67f3b90..86fae55 100644 --- a/Assets/Common/Interfaces/MinigameList.cs +++ b/Assets/Common/Interfaces/MinigameList.cs @@ -5,7 +5,7 @@ using UnityEngine; /// /// Keep track off installed minigames /// -[CreateAssetMenu(menuName = "Create new Scriptable/MinigameList")] +[CreateAssetMenu(menuName = "Create new Scriptable/Minigame List")] public class MinigameList : ScriptableObject { /// @@ -33,7 +33,7 @@ public class MinigameList : ScriptableObject /// /// public void SetCurrentMinigame(MinigameIndex index) - { + { currentMinigameIndex = minigames.FindIndex((mi) => mi.index == index); } } diff --git a/Assets/Common/Interfaces/ThemeList.cs b/Assets/Common/Interfaces/ThemeList.cs index 8681445..c3385af 100644 --- a/Assets/Common/Interfaces/ThemeList.cs +++ b/Assets/Common/Interfaces/ThemeList.cs @@ -5,7 +5,7 @@ using UnityEngine; /// /// Keep track off defined themes /// -[CreateAssetMenu(menuName = "Create new Scriptable/ThemeList")] +[CreateAssetMenu(menuName = "Create new Scriptable/Theme List")] public class ThemeList : ScriptableObject { /// diff --git a/Assets/Common/PlayModeTests/BackButtonTests.cs b/Assets/Common/PlayModeTests/BackButtonTests.cs index 52fac01..07bcefe 100644 --- a/Assets/Common/PlayModeTests/BackButtonTests.cs +++ b/Assets/Common/PlayModeTests/BackButtonTests.cs @@ -1,13 +1,9 @@ -using System.Collections; -using System.Linq; -using System.IO; - using NUnit.Framework; -using TMPro; +using System.Collections; +using System.IO; +using UnityEditor; using UnityEngine; using UnityEngine.TestTools; -using UnityEngine.SceneManagement; - public class BackButtonTests { @@ -15,14 +11,13 @@ public class BackButtonTests [UnitySetUp] public IEnumerator SetupFunction() { - string path = $"{Application.persistentDataPath}/users.json"; - var oneUser = "{\"currentUserIndex\": 0,\"storedUsers\": [{\"username\": \"TEST\",\"avatar\": {\"instanceID\": 40848},\"playtime\": 0.0,\"courses\": [],\"minigames\": []}]}"; + string path = $"{Application.persistentDataPath}/unit_test_users.json"; + string oneUser = $"{{\"version\":{PersistentDataController.VERSION},\"users\":[{{\"entries\":[],\"username\":\"TEST\",\"avatarIndex\":0,\"playtime\":0.0,\"minigames\":[],\"courses\":[]}}],\"currentUser\":0,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; - using (StreamWriter writer = new StreamWriter(path)) - { - writer.Write(oneUser); - } - + File.WriteAllText(path, oneUser); + PersistentDataController.PATH = path; + PersistentDataController.GetInstance().Load(); + AssetDatabase.LoadAssetAtPath("Assets/Accounts/ScriptableObjects/UserAvatarList.asset").Awake(); SystemController.GetInstance().LoadNextScene("Common/Scenes/MainMenuScreen"); yield return new WaitForSeconds(0.2f); SystemController.GetInstance().LoadNextScene("Common/Scenes/ListMinigamesScreen"); @@ -33,11 +28,11 @@ public class BackButtonTests public IEnumerator BackTest() { - var backButton = (BackButton) GameObject.FindObjectOfType(typeof(BackButton)); + var backButton = (BackButton)GameObject.FindObjectOfType(typeof(BackButton)); backButton.Back(); yield return new WaitForSeconds(0.2f); - var mainMenuScreen = (MainMenuScreen) GameObject.FindObjectOfType(typeof(MainMenuScreen)); + var mainMenuScreen = (MainMenuScreen)GameObject.FindObjectOfType(typeof(MainMenuScreen)); Assert.IsNotNull(mainMenuScreen); } } diff --git a/Assets/Common/PlayModeTests/CommonPlayModeTests.asmdef b/Assets/Common/PlayModeTests/CommonPlayModeTests.asmdef index 1682fab..0ea4cd7 100644 --- a/Assets/Common/PlayModeTests/CommonPlayModeTests.asmdef +++ b/Assets/Common/PlayModeTests/CommonPlayModeTests.asmdef @@ -9,7 +9,8 @@ "InterfacesScripts", "Unity.TextMeshPro", "AccountsScripts", - "SignPredictor" + "SignPredictor", + "SystemArchitecture" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Assets/Common/PlayModeTests/CourseActivityTests.cs b/Assets/Common/PlayModeTests/CourseActivityTests.cs index 2125822..4eb81ac 100644 --- a/Assets/Common/PlayModeTests/CourseActivityTests.cs +++ b/Assets/Common/PlayModeTests/CourseActivityTests.cs @@ -1,13 +1,9 @@ -using System.Collections; -using System.Linq; -using System.IO; - using NUnit.Framework; -using TMPro; +using System.Collections; +using System.IO; +using UnityEditor; using UnityEngine; using UnityEngine.TestTools; -using UnityEngine.SceneManagement; - public class CourseActivityTests { @@ -15,14 +11,13 @@ public class CourseActivityTests [UnitySetUp] public IEnumerator SetupFunction() { - string path = $"{Application.persistentDataPath}/users.json"; - var oneUser = "{\"currentUserIndex\": 0,\"storedUsers\": [{\"username\": \"TEST\",\"avatar\": {\"instanceID\": 40848},\"playtime\": 0.0,\"courses\": [],\"minigames\": []}]}"; - - using (StreamWriter writer = new StreamWriter(path)) - { - writer.Write(oneUser); - } + string path = $"{Application.persistentDataPath}/unit_test_users.json"; + string oneUser = $"{{\"version\":{PersistentDataController.VERSION},\"users\":[{{\"entries\":[],\"username\":\"TEST\",\"avatarIndex\":0,\"playtime\":0.0,\"minigames\":[],\"courses\":[]}}],\"currentUser\":0,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; + File.WriteAllText(path, oneUser); + PersistentDataController.PATH = path; + PersistentDataController.GetInstance().Load(); + AssetDatabase.LoadAssetAtPath("Assets/Accounts/ScriptableObjects/UserAvatarList.asset").Awake(); SystemController.GetInstance().LoadNextScene("Common/Scenes/CourseActivityScreen"); yield return new WaitForSeconds(0.2f); } @@ -30,11 +25,11 @@ public class CourseActivityTests [UnityTest] public IEnumerator StartCoursesTests() { - var courseActivityScreen = (CourseActivityScreen) GameObject.FindObjectOfType(typeof(CourseActivityScreen)); + var courseActivityScreen = (CourseActivityScreen)GameObject.FindObjectOfType(typeof(CourseActivityScreen)); courseActivityScreen.StartCourse(); yield return new WaitForSeconds(0.2f); - var templateCourse = (CoursesController) GameObject.FindObjectOfType(typeof(CoursesController)); + var templateCourse = (CoursesController)GameObject.FindObjectOfType(typeof(CoursesController)); Assert.IsNotNull(templateCourse); } } diff --git a/Assets/Common/PlayModeTests/CourseMenuScreenTests.cs b/Assets/Common/PlayModeTests/CourseMenuScreenTests.cs index 8f5a89d..ce2a517 100644 --- a/Assets/Common/PlayModeTests/CourseMenuScreenTests.cs +++ b/Assets/Common/PlayModeTests/CourseMenuScreenTests.cs @@ -1,13 +1,9 @@ -using System.Collections; -using System.Linq; -using System.IO; - using NUnit.Framework; -using TMPro; +using System.Collections; +using System.IO; +using UnityEditor; using UnityEngine; using UnityEngine.TestTools; -using UnityEngine.SceneManagement; - public class CourseMenuScreenTest { @@ -15,14 +11,13 @@ public class CourseMenuScreenTest [UnitySetUp] public IEnumerator SetupFunction() { - string path = $"{Application.persistentDataPath}/users.json"; - var oneUser = "{\"currentUserIndex\": 0,\"storedUsers\": [{\"username\": \"TEST\",\"avatar\": {\"instanceID\": 40848},\"playtime\": 0.0,\"courses\": [],\"minigames\": []}]}"; - - using (StreamWriter writer = new StreamWriter(path)) - { - writer.Write(oneUser); - } + string path = $"{Application.persistentDataPath}/unit_test_users.json"; + string oneUser = $"{{\"version\":{PersistentDataController.VERSION},\"users\":[{{\"entries\":[],\"username\":\"TEST\",\"avatarIndex\":0,\"playtime\":0.0,\"minigames\":[],\"courses\":[]}}],\"currentUser\":0,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; + File.WriteAllText(path, oneUser); + PersistentDataController.PATH = path; + PersistentDataController.GetInstance().Load(); + AssetDatabase.LoadAssetAtPath("Assets/Accounts/ScriptableObjects/UserAvatarList.asset").Awake(); SystemController.GetInstance().LoadNextScene("Common/Scenes/CoursesMenuScreen"); yield return new WaitForSeconds(0.2f); } @@ -30,7 +25,7 @@ public class CourseMenuScreenTest [UnityTest] public IEnumerator GotoListOfCoursesTest() { - var courseMenuScreen = (CourseMenuScreen) GameObject.FindObjectOfType(typeof(CourseMenuScreen)); + var courseMenuScreen = (CourseMenuScreen)GameObject.FindObjectOfType(typeof(CourseMenuScreen)); courseMenuScreen.GotoListOfCourses(); yield return new WaitForSeconds(0.2f); diff --git a/Assets/Common/PlayModeTests/ListCoursesScreenTests.cs b/Assets/Common/PlayModeTests/ListCoursesScreenTests.cs index 552906a..0efcd63 100644 --- a/Assets/Common/PlayModeTests/ListCoursesScreenTests.cs +++ b/Assets/Common/PlayModeTests/ListCoursesScreenTests.cs @@ -1,13 +1,9 @@ -using System.Collections; -using System.Linq; -using System.IO; - using NUnit.Framework; -using TMPro; +using System.Collections; +using System.IO; +using UnityEditor; using UnityEngine; using UnityEngine.TestTools; -using UnityEngine.SceneManagement; - public class ListCoursesScreenTest { @@ -15,14 +11,13 @@ public class ListCoursesScreenTest [UnitySetUp] public IEnumerator SetupFunction() { - string path = $"{Application.persistentDataPath}/users.json"; - var oneUser = "{\"currentUserIndex\": 0,\"storedUsers\": [{\"username\": \"TEST\",\"avatar\": {\"instanceID\": 40848},\"playtime\": 0.0,\"courses\": [],\"minigames\": []}]}"; - - using (StreamWriter writer = new StreamWriter(path)) - { - writer.Write(oneUser); - } + string path = $"{Application.persistentDataPath}/unit_test_users.json"; + string oneUser = $"{{\"version\":{PersistentDataController.VERSION},\"users\":[{{\"entries\":[],\"username\":\"TEST\",\"avatarIndex\":0,\"playtime\":0.0,\"minigames\":[],\"courses\":[]}}],\"currentUser\":0,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; + File.WriteAllText(path, oneUser); + PersistentDataController.PATH = path; + PersistentDataController.GetInstance().Load(); + AssetDatabase.LoadAssetAtPath("Assets/Accounts/ScriptableObjects/UserAvatarList.asset").Awake(); SystemController.GetInstance().LoadNextScene("Common/Scenes/ListCoursesScreen"); yield return new WaitForSeconds(0.2f); } diff --git a/Assets/Common/PlayModeTests/MainMenuScreenTests.cs b/Assets/Common/PlayModeTests/MainMenuScreenTests.cs index 5e48d47..1517265 100644 --- a/Assets/Common/PlayModeTests/MainMenuScreenTests.cs +++ b/Assets/Common/PlayModeTests/MainMenuScreenTests.cs @@ -1,12 +1,10 @@ -using System.Collections; -using System.Linq; -using System.IO; - using NUnit.Framework; -using TMPro; +using System.Collections; +using System.IO; +using UnityEditor; using UnityEngine; -using UnityEngine.TestTools; using UnityEngine.SceneManagement; +using UnityEngine.TestTools; public class MainMenuScreenTests @@ -15,14 +13,13 @@ public class MainMenuScreenTests [UnitySetUp] public IEnumerator SetupFunction() { - string path = $"{Application.persistentDataPath}/users.json"; - var oneUser = "{\"currentUserIndex\": 0,\"storedUsers\": [{\"username\": \"TEST\",\"avatar\": {\"instanceID\": 40848},\"playtime\": 0.0,\"courses\": [],\"minigames\": []}]}"; - - using (StreamWriter writer = new StreamWriter(path)) - { - writer.Write(oneUser); - } + string path = $"{Application.persistentDataPath}/unit_test_users.json"; + string oneUser = $"{{\"version\":{PersistentDataController.VERSION},\"users\":[{{\"entries\":[],\"username\":\"TEST\",\"avatarIndex\":0,\"playtime\":0.0,\"minigames\":[],\"courses\":[]}}],\"currentUser\":0,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; + File.WriteAllText(path, oneUser); + PersistentDataController.PATH = path; + PersistentDataController.GetInstance().Load(); + AssetDatabase.LoadAssetAtPath("Assets/Accounts/ScriptableObjects/UserAvatarList.asset").Awake(); SceneManager.LoadScene("Common/Scenes/MainMenuScreen"); yield return new WaitForSeconds(0.2f); } @@ -42,28 +39,28 @@ public class MainMenuScreenTests [UnityTest] public IEnumerator GotoMiniGamesTest() { - var mainMenuScreen = (MainMenuScreen) GameObject.FindObjectOfType(typeof(MainMenuScreen)); + var mainMenuScreen = (MainMenuScreen)GameObject.FindObjectOfType(typeof(MainMenuScreen)); mainMenuScreen.GotoMinigames(); yield return new WaitForSeconds(0.2f); - var listMinigamesScreen = (ListMinigamesScreen) GameObject.FindObjectOfType(typeof(ListMinigamesScreen)); + var listMinigamesScreen = (ListMinigamesScreen)GameObject.FindObjectOfType(typeof(ListMinigamesScreen)); Assert.IsNotNull(listMinigamesScreen); } -/* [UnityTest] - public IEnumerator GotoSettingsTest() - { - Arrange - SceneManager.LoadScene("Common/Scenes/MainMenuScreen"); + /* [UnityTest] + public IEnumerator GotoSettingsTest() + { + Arrange + SceneManager.LoadScene("Common/Scenes/MainMenuScreen"); - yield return new WaitForSeconds(1f); - var mainMenuScreen = (MainMenuScreen)GameObject.FindObjectOfType(typeof(MainMenuScreen)); - mainMenuScreen.GotoSettings(); - yield return new WaitForSeconds(1f); + yield return new WaitForSeconds(1f); + var mainMenuScreen = (MainMenuScreen)GameObject.FindObjectOfType(typeof(MainMenuScreen)); + mainMenuScreen.GotoSettings(); + yield return new WaitForSeconds(1f); - var minigameActivityScreen = (MinigameActivityScreen)GameObject.FindObjectOfType(typeof(MinigameActivityScreen)); - Assert.IsNotNull(minigameActivityScreen); - }*/ + var minigameActivityScreen = (MinigameActivityScreen)GameObject.FindObjectOfType(typeof(MinigameActivityScreen)); + Assert.IsNotNull(minigameActivityScreen); + }*/ } diff --git a/Assets/Common/PlayModeTests/MinigameActivityScreenTests.cs b/Assets/Common/PlayModeTests/MinigameActivityScreenTests.cs index 8896662..59e5ac5 100644 --- a/Assets/Common/PlayModeTests/MinigameActivityScreenTests.cs +++ b/Assets/Common/PlayModeTests/MinigameActivityScreenTests.cs @@ -1,12 +1,9 @@ -using System.Collections; -using System.Linq; -using System.IO; - using NUnit.Framework; -using TMPro; +using System.Collections; +using System.IO; +using UnityEditor; using UnityEngine; using UnityEngine.TestTools; -using UnityEngine.SceneManagement; public class MiniGameActivityScreenTests @@ -15,14 +12,13 @@ public class MiniGameActivityScreenTests [UnitySetUp] public IEnumerator SetupFunction() { - string path = $"{Application.persistentDataPath}/users.json"; - var oneUser = "{\"currentUserIndex\": 0,\"storedUsers\": [{\"username\": \"TEST\",\"avatar\": {\"instanceID\": 40848},\"playtime\": 0.0,\"courses\": [],\"minigames\": []}]}"; - - using (StreamWriter writer = new StreamWriter(path)) - { - writer.Write(oneUser); - } + string path = $"{Application.persistentDataPath}/unit_test_users.json"; + string oneUser = $"{{\"version\":{PersistentDataController.VERSION},\"users\":[{{\"entries\":[],\"username\":\"TEST\",\"avatarIndex\":0,\"playtime\":0.0,\"minigames\":[],\"courses\":[]}}],\"currentUser\":0,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; + File.WriteAllText(path, oneUser); + PersistentDataController.PATH = path; + PersistentDataController.GetInstance().Load(); + AssetDatabase.LoadAssetAtPath("Assets/Accounts/ScriptableObjects/UserAvatarList.asset").Awake(); SystemController.GetInstance().LoadNextScene("Common/Scenes/CoursesMenuScreen"); yield return new WaitForSeconds(0.2f); } diff --git a/Assets/Common/PlayModeTests/StartGameTests.cs b/Assets/Common/PlayModeTests/StartGameTests.cs index ccc5eda..e8c9ecc 100644 --- a/Assets/Common/PlayModeTests/StartGameTests.cs +++ b/Assets/Common/PlayModeTests/StartGameTests.cs @@ -1,36 +1,31 @@ -using System.Collections; -using System.Linq; -using System.IO; - using NUnit.Framework; -using TMPro; +using System.Collections; +using System.IO; +using UnityEditor; using UnityEngine; -using UnityEngine.TestTools; using UnityEngine.SceneManagement; +using UnityEngine.TestTools; public class StartGamesTests { - - [UnityTest] public IEnumerator BootWithUsersTest() { - string path = $"{Application.persistentDataPath}/users.json"; - var oneUser = "{\"currentUserIndex\": 0,\"storedUsers\": [{\"username\": \"TEST\",\"avatar\": {\"instanceID\": 40848},\"playtime\": 0.0,\"courses\": [],\"minigames\": []}]}"; - - using (StreamWriter writer = new StreamWriter(path)) - { - writer.Write(oneUser); - } + string path = $"{Application.persistentDataPath}/unit_test_users.json"; + string oneUser = $"{{\"version\":{PersistentDataController.VERSION},\"users\":[{{\"entries\":[],\"username\":\"TEST\",\"avatarIndex\":0,\"playtime\":0.0,\"minigames\":[],\"courses\":[]}}],\"currentUser\":0,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; + File.WriteAllText(path, oneUser); + PersistentDataController.PATH = path; + PersistentDataController.GetInstance().Load(); + AssetDatabase.LoadAssetAtPath("Assets/Accounts/ScriptableObjects/UserAvatarList.asset").Awake(); SceneManager.LoadScene("Common/Scenes/Boot"); yield return new WaitForSeconds(1); - var userCreationScreen = (UserCreationScreen) GameObject.FindObjectOfType(typeof(UserCreationScreen)); - var bootScreen = (BootScreen) GameObject.FindObjectOfType(typeof(BootScreen)); - var mainMenuScreen = (MainMenuScreen) GameObject.FindObjectOfType(typeof(MainMenuScreen)); + var userCreationScreen = (UserCreationScreen)GameObject.FindObjectOfType(typeof(UserCreationScreen)); + var bootScreen = (BootScreen)GameObject.FindObjectOfType(typeof(BootScreen)); + var mainMenuScreen = (MainMenuScreen)GameObject.FindObjectOfType(typeof(MainMenuScreen)); // yield return Application.RequestUserAuthorization(UserAuthorization.WebCam); // if (Application.HasUserAuthorization(UserAuthorization.WebCam)) @@ -42,41 +37,37 @@ public class StartGamesTests // Assert.AreEqual(bootScreen.errorText.text, "Zorg ervoor dat deze applicatie toegang heeft tot je webcam!"); // } // else - if(0 >= WebCamTexture.devices.Length){ - Debug.Log("no webcam"); - Assert.IsNull(userCreationScreen); + if (0 >= WebCamTexture.devices.Length) + { Assert.IsNull(mainMenuScreen); Assert.IsNotNull(bootScreen); Assert.AreEqual(bootScreen.errorText.text, "Zorg ervoor dat je webcam correct is aangesloten!"); } - else + else { - Debug.Log("everything is there"); Assert.IsNull(bootScreen); - Assert.IsNull(userCreationScreen); Assert.IsNotNull(mainMenuScreen); } + Assert.IsNull(userCreationScreen); } [UnityTest] public IEnumerator BootWithoutUsersTest() { - // Arrange - string path = $"{Application.persistentDataPath}/users.json"; - var oneUser = "{}"; - - using (StreamWriter writer = new StreamWriter(path)) - { - writer.Write(oneUser); - } + string path = $"{Application.persistentDataPath}/unit_test_users.json"; + string noUsers = "https://www.youtube.com/watch?v=dQw4w9WgXcQ"; + File.WriteAllText(path, noUsers); + PersistentDataController.PATH = path; + PersistentDataController.GetInstance().Load(); + AssetDatabase.LoadAssetAtPath("Assets/Accounts/ScriptableObjects/UserAvatarList.asset").Awake(); SceneManager.LoadScene("Common/Scenes/Boot"); yield return new WaitForSeconds(1); - var userCreationScreen = (UserCreationScreen) GameObject.FindObjectOfType(typeof(UserCreationScreen)); - var bootScreen = (BootScreen) GameObject.FindObjectOfType(typeof(BootScreen)); - var mainMenuScreen = (MainMenuScreen) GameObject.FindObjectOfType(typeof(MainMenuScreen)); + var userCreationScreen = (UserCreationScreen)GameObject.FindObjectOfType(typeof(UserCreationScreen)); + var bootScreen = (BootScreen)GameObject.FindObjectOfType(typeof(BootScreen)); + var mainMenuScreen = (MainMenuScreen)GameObject.FindObjectOfType(typeof(MainMenuScreen)); // yield return Application.RequestUserAuthorization(UserAuthorization.WebCam); // if (Application.HasUserAuthorization(UserAuthorization.WebCam)) @@ -88,19 +79,18 @@ public class StartGamesTests // Assert.AreEqual(bootScreen.errorText.text, "Zorg ervoor dat deze applicatie toegang heeft tot je webcam!"); // } // else - if(0 >= WebCamTexture.devices.Length){ - Debug.Log("no webcam"); + if (0 >= WebCamTexture.devices.Length) + { Assert.IsNull(userCreationScreen); - Assert.IsNull(mainMenuScreen); Assert.IsNotNull(bootScreen); Assert.AreEqual(bootScreen.errorText.text, "Zorg ervoor dat je webcam correct is aangesloten!"); - } else + } + else { - Debug.Log("no users"); Assert.IsNull(bootScreen); - Assert.IsNull(mainMenuScreen); Assert.IsNotNull(userCreationScreen); } + Assert.IsNull(mainMenuScreen); } } diff --git a/Assets/Common/PlayModeTests/UserButtonTests.cs b/Assets/Common/PlayModeTests/UserButtonTests.cs index 40a324c..271b7cb 100644 --- a/Assets/Common/PlayModeTests/UserButtonTests.cs +++ b/Assets/Common/PlayModeTests/UserButtonTests.cs @@ -1,12 +1,9 @@ -using System.Collections; -using System.Linq; -using System.IO; - using NUnit.Framework; -using TMPro; +using System.Collections; +using System.IO; +using UnityEditor; using UnityEngine; using UnityEngine.TestTools; -using UnityEngine.SceneManagement; public class UserButtonTests @@ -15,28 +12,27 @@ public class UserButtonTests [UnitySetUp] public IEnumerator SetupFunction() { - string path = $"{Application.persistentDataPath}/users.json"; - var oneUser = "{\"currentUserIndex\": 0,\"storedUsers\": [{\"username\": \"TEST\",\"avatar\": {\"instanceID\": 40848},\"playtime\": 0.0,\"courses\": [],\"minigames\": []}]}"; - - using (StreamWriter writer = new StreamWriter(path)) - { - writer.Write(oneUser); - } + string path = $"{Application.persistentDataPath}/unit_test_users.json"; + string oneUser = $"{{\"version\":{PersistentDataController.VERSION},\"users\":[{{\"entries\":[],\"username\":\"TEST\",\"avatarIndex\":0,\"playtime\":0.0,\"minigames\":[],\"courses\":[]}}],\"currentUser\":0,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; + File.WriteAllText(path, oneUser); + PersistentDataController.PATH = path; + PersistentDataController.GetInstance().Load(); + AssetDatabase.LoadAssetAtPath("Assets/Accounts/ScriptableObjects/UserAvatarList.asset").Awake(); SystemController.GetInstance().LoadNextScene("Common/Scenes/CoursesMenuScreen"); yield return new WaitForSeconds(0.2f); } -/* [UnityTest] - public IEnumerator OpenProgressCallbackTest() - { - var userButton = (UserButton)GameObject.FindObjectOfType(typeof(UserButton)); - userButton.OpenProgressCallback(); - yield return new WaitForSeconds(0.2f); + /* [UnityTest] + public IEnumerator OpenProgressCallbackTest() + { + var userButton = (UserButton)GameObject.FindObjectOfType(typeof(UserButton)); + userButton.OpenProgressCallback(); + yield return new WaitForSeconds(0.2f); - var listCoursesScreen = (ListCoursesScreen)GameObject.FindObjectOfType(typeof(ListCoursesScreen)); - Assert.IsNotNull(listCoursesScreen); - }*/ + var listCoursesScreen = (ListCoursesScreen)GameObject.FindObjectOfType(typeof(ListCoursesScreen)); + Assert.IsNotNull(listCoursesScreen); + }*/ [UnityTest] public IEnumerator ChangeUserCallbackTest() diff --git a/Assets/Common/Scenes/Boot.unity b/Assets/Common/Scenes/Boot.unity index 4f95155..9117d31 100644 --- a/Assets/Common/Scenes/Boot.unity +++ b/Assets/Common/Scenes/Boot.unity @@ -314,6 +314,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: errorText: {fileID: 1663223260} + sprites: {fileID: 11400000, guid: 017ec1af3b6cc4d4ab2b506911a4edad, type: 2} --- !u!4 &1427583095 Transform: m_ObjectHideFlags: 0 diff --git a/Assets/Common/Scripts/BootScreen.cs b/Assets/Common/Scripts/BootScreen.cs index ef66015..b1a7c71 100644 --- a/Assets/Common/Scripts/BootScreen.cs +++ b/Assets/Common/Scripts/BootScreen.cs @@ -12,12 +12,20 @@ public class BootScreen : MonoBehaviour /// public TMP_Text errorText; + /// + /// Reference to the list that holds all user avatars + /// + public UserAvatarList sprites; + /// /// Request authorization and check whether at least 1 webcam is available /// /// IEnumerator object IEnumerator Start() { + UserList.AVATARS = sprites.avatars; + PersistentDataController.GetInstance().Load(); + yield return Application.RequestUserAuthorization(UserAuthorization.WebCam); if (Application.HasUserAuthorization(UserAuthorization.WebCam)) { diff --git a/Assets/Common/Scripts/CommonScripts.asmdef b/Assets/Common/Scripts/CommonScripts.asmdef index ed617d5..d6a3630 100644 --- a/Assets/Common/Scripts/CommonScripts.asmdef +++ b/Assets/Common/Scripts/CommonScripts.asmdef @@ -5,6 +5,7 @@ "GUID:6055be8ebefd69e48b49212b09b47b2f", "GUID:63c63e721f65ebb7d871cb9ef49f4752", "GUID:1631ed2680c61245b8211d943c1639a8", + "GUID:e83ddf9a537a96b4a804a16bb7872ec1", "GUID:7f2d0ee6dd21e1d4eb25b71b7a749d25" ], "includePlatforms": [], diff --git a/Assets/Common/Scripts/CourseActivityScreen.cs b/Assets/Common/Scripts/CourseActivityScreen.cs index aec384a..34aa7f0 100644 --- a/Assets/Common/Scripts/CourseActivityScreen.cs +++ b/Assets/Common/Scripts/CourseActivityScreen.cs @@ -17,15 +17,10 @@ public class CourseActivityScreen : MonoBehaviour /// public CourseList courseList; - /// - /// Reference to the users - /// - public UserList userList; - /// /// Reference to the course progress /// - private Progress progress; + private PersistentDataController.SavedCourseProgress progress; /// /// Title Display @@ -66,10 +61,10 @@ public class CourseActivityScreen : MonoBehaviour //slider.value = progressValue; // Set progress - userList.Load(); - progress = userList.GetCurrentUser().GetCourseProgress(course.index); + PersistentDataController.GetInstance().Load(); + progress = UserList.GetCurrentUser().GetCourseProgress(course.index); if (progress != null) - progressBar.value = progress.Get("courseProgress"); + progressBar.value = progress.progress; else progressBar.value = 0.0f; } diff --git a/Assets/Common/Scripts/CourseMenuScreen.cs b/Assets/Common/Scripts/CourseMenuScreen.cs index ef56303..0ea4ecd 100644 --- a/Assets/Common/Scripts/CourseMenuScreen.cs +++ b/Assets/Common/Scripts/CourseMenuScreen.cs @@ -27,11 +27,6 @@ public class CourseMenuScreen : MonoBehaviour /// public GameObject courseItem; - /// - /// Reference to the users so we can get the current user; - /// - public UserList userList; - /// /// Reference to the courses /// @@ -42,8 +37,8 @@ public class CourseMenuScreen : MonoBehaviour /// void Start() { - userList.Load(); - User user = userList.GetCurrentUser(); + PersistentDataController.GetInstance().Load(); + User user = UserList.GetCurrentUser(); // Recent courses List> recentCourses = user.GetRecentCourses(); diff --git a/Assets/Common/Scripts/ListCoursesScreen.cs b/Assets/Common/Scripts/ListCoursesScreen.cs index 7628ecf..0f58972 100644 --- a/Assets/Common/Scripts/ListCoursesScreen.cs +++ b/Assets/Common/Scripts/ListCoursesScreen.cs @@ -5,11 +5,6 @@ using UnityEngine; /// public class ListCoursesScreen : MonoBehaviour { - /// - /// Reference to the userlist - /// - public UserList userList; - /// /// Reference to the course-list container object /// @@ -30,8 +25,8 @@ public class ListCoursesScreen : MonoBehaviour /// void Start() { - userList.Load(); - User user = userList.GetCurrentUser(); + PersistentDataController.GetInstance().Load(); + User user = UserList.GetCurrentUser(); foreach (Course course in courseList.courses) { @@ -42,8 +37,8 @@ public class ListCoursesScreen : MonoBehaviour CourseItem item = instance.GetComponent(); item.course = course; - Progress progress = user.GetCourseProgress(course.index); - item.progress = progress != null ? progress.Get("courseProgress") : 0.0f; + var progress = user.GetCourseProgress(course.index); + item.progress = progress != null ? progress.progress : 0.0f; } } diff --git a/Assets/Common/Scripts/MainMenuScreen.cs b/Assets/Common/Scripts/MainMenuScreen.cs index d4f7382..0a5481f 100644 --- a/Assets/Common/Scripts/MainMenuScreen.cs +++ b/Assets/Common/Scripts/MainMenuScreen.cs @@ -6,19 +6,13 @@ using UnityEngine; /// public class MainMenuScreen : MonoBehaviour { - /// - /// Referece to the userlist to check whether an user account is present - /// - public UserList userList; - /// /// Check on load whether a user is already present, /// if not load the UserCreationScreen scene so the user can create a new account /// void Awake() { - userList.Load(); - if (!File.Exists(UserList.PATH) || userList.GetUsers().Count <= 0) + if (!File.Exists(PersistentDataController.PATH) || UserList.GetUsers().Count <= 0) { SystemController.GetInstance().LoadNextScene("Accounts/Scenes/UserCreationScreen"); } diff --git a/Assets/Common/Scripts/MinigameActivityScreen.cs b/Assets/Common/Scripts/MinigameActivityScreen.cs index 46dc2ba..39dff9f 100644 --- a/Assets/Common/Scripts/MinigameActivityScreen.cs +++ b/Assets/Common/Scripts/MinigameActivityScreen.cs @@ -40,15 +40,10 @@ public class MinigameActivityScreen : MonoBehaviour /// public TMP_Text controls; - /// - /// Reference to the users - /// - public UserList userList; - /// /// Reference to the Minigame progress /// - private Progress progress; + private PersistentDataController.SavedMinigameProgress progress; /// /// Reference to the users-high-scores container object @@ -65,7 +60,7 @@ public class MinigameActivityScreen : MonoBehaviour /// void Start() { - userList.Load(); + PersistentDataController.GetInstance().Load(); GenerateContent(); GenerateHighScores(); } @@ -109,17 +104,17 @@ public class MinigameActivityScreen : MonoBehaviour Minigame minigame = minigameList.minigames[index]; List> allScores = new List>(); - foreach (User user in userList.GetUsers()) + foreach (User user in UserList.GetUsers()) { // Get user's progress for this minigame progress = user.GetMinigameProgress(minigame.index); if (progress != null) { // Add scores to dictionary - List scores = progress.Get>("highestScores"); + List scores = progress.highestScores; foreach (Score score in scores) { - allScores.Add(new Tuple(user.username, user.avatar, score)); + allScores.Add(new Tuple(user.GetUsername(), user.GetAvatar(), score)); } } } diff --git a/Assets/Common/Scripts/UserButton.cs b/Assets/Common/Scripts/UserButton.cs index 5fa77e5..ee25a5e 100644 --- a/Assets/Common/Scripts/UserButton.cs +++ b/Assets/Common/Scripts/UserButton.cs @@ -7,11 +7,6 @@ using UnityEngine.UI; /// public class UserButton : MonoBehaviour { - /// - /// Reference to the user list, so we can extract the current user - /// - public UserList userList; - /// /// UI reference to the avatar object /// @@ -32,10 +27,10 @@ public class UserButton : MonoBehaviour /// void Start() { - userList.Load(); - User user = userList.GetCurrentUser(); - avatar.sprite = user.avatar; - username.text = user.username; + PersistentDataController.GetInstance().Load(); + User user = UserList.GetCurrentUser(); + avatar.sprite = user.GetAvatar(); + username.text = user.GetUsername(); dropdownBox.SetActive(false); } diff --git a/Assets/Common/Tests/CommonTests.asmdef b/Assets/Common/Tests/CommonTests.asmdef index 7d1328b..3a38e25 100644 --- a/Assets/Common/Tests/CommonTests.asmdef +++ b/Assets/Common/Tests/CommonTests.asmdef @@ -7,6 +7,7 @@ "CommonScripts", "InterfacesScripts", "SignPredictor", + "SystemArchitecture", "NatML.ML" ], "includePlatforms": [ diff --git a/Assets/Common/Tests/ThemeListTest.cs b/Assets/Common/Tests/ThemeListTest.cs index f316212..dc3afa1 100644 --- a/Assets/Common/Tests/ThemeListTest.cs +++ b/Assets/Common/Tests/ThemeListTest.cs @@ -1,5 +1,6 @@ using NUnit.Framework; using UnityEngine; + /// /// Test the ThemeList class /// diff --git a/Assets/Common/Tests/ThemeTest.cs b/Assets/Common/Tests/ThemeTest.cs index e6db61f..a93d7e4 100644 --- a/Assets/Common/Tests/ThemeTest.cs +++ b/Assets/Common/Tests/ThemeTest.cs @@ -1,6 +1,7 @@ using NUnit.Framework; using System.Collections.Generic; using UnityEngine; + /// /// Test the Theme class /// diff --git a/Assets/Courses/PlayModeTests/PlayModeTests.asmdef b/Assets/Courses/PlayModeTests/PlayModeTests.asmdef index c978340..176f405 100644 --- a/Assets/Courses/PlayModeTests/PlayModeTests.asmdef +++ b/Assets/Courses/PlayModeTests/PlayModeTests.asmdef @@ -1,6 +1,22 @@ { "name": "PlayModeTests", - "optionalUnityReferences": [ - "TestAssemblies" - ] -} + "rootNamespace": "", + "references": [ + "UnityEngine.TestRunner", + "UnityEditor.TestRunner", + "SystemArchitecture" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": true, + "precompiledReferences": [ + "nunit.framework.dll" + ], + "autoReferenced": false, + "defineConstraints": [ + "UNITY_INCLUDE_TESTS" + ], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/Courses/Scripts/CourseScripts.asmdef b/Assets/Courses/Scripts/CourseScripts.asmdef index 942691a..a8b163e 100644 --- a/Assets/Courses/Scripts/CourseScripts.asmdef +++ b/Assets/Courses/Scripts/CourseScripts.asmdef @@ -7,6 +7,7 @@ "InterfacesScripts", "SignPredictor", "NatML.ML", + "SystemArchitecture", "Tween" ], "includePlatforms": [], diff --git a/Assets/Courses/Scripts/CoursesController.cs b/Assets/Courses/Scripts/CoursesController.cs index 298f968..05749b5 100644 --- a/Assets/Courses/Scripts/CoursesController.cs +++ b/Assets/Courses/Scripts/CoursesController.cs @@ -39,11 +39,6 @@ public class CoursesController : AbstractFeedback /// public TMP_Text title; - /// - /// Reference to user list to get current user - /// - public UserList userList; - /// /// The current user /// @@ -52,7 +47,7 @@ public class CoursesController : AbstractFeedback /// /// Current user progress for this course /// - private Progress progress = null; + private PersistentDataController.SavedCourseProgress progress = null; /// /// ScriptableObject with list of all courses @@ -169,17 +164,17 @@ public class CoursesController : AbstractFeedback previewMessage.SetActive(course.theme.modelIndex == ModelIndex.NONE); // Create entry in current user for keeping track of progress - userList.Load(); - user = userList.GetCurrentUser(); + //PersistentDataController pdc = PersistentDataController.GetInstance(); + //pdc.Load(); + user = UserList.GetCurrentUser(); progress = user.GetCourseProgress(course.index); if (progress == null) { - progress = new Progress(); - progress.AddOrUpdate("courseIndex", course.index); - progress.AddOrUpdate("courseProgress", -1.0f); - user.courses.Add(progress); + progress = new PersistentDataController.SavedCourseProgress(); + progress.courseIndex = course.index; + user.AddCourseProgress(progress); } - userList.Save(); + UserList.Save(); // Force the videoplayer to add bars to preserve aspect ratio player.aspectRatio = VideoAspectRatio.FitInside; @@ -260,8 +255,8 @@ public class CoursesController : AbstractFeedback // TODO: fix correct word count correctWords++; - progress.AddOrUpdate("courseProgress", (float)correctWords / (float)maxWords); - userList.Save(); + progress.progress = (float)correctWords / (float)maxWords; + UserList.Save(); // Update UI if course is not finished yet if (currentWordIndex < maxWords) @@ -297,8 +292,8 @@ public class CoursesController : AbstractFeedback // Link button CoursesButton.onClick.AddListener(() => { SystemController.GetInstance().BackToPreviousScene(); }); - progress.AddOrUpdate("courseProgress", 1f); - userList.Save(); + progress.progress = 1.0f; + UserList.Save(); } /// /// The updateFunction that is called when new probabilities become available diff --git a/Assets/Hangman/Scripts/HangmanController.cs b/Assets/Hangman/Scripts/HangmanController.cs index 1edfed0..3ebdd40 100644 --- a/Assets/Hangman/Scripts/HangmanController.cs +++ b/Assets/Hangman/Scripts/HangmanController.cs @@ -1,3 +1,4 @@ +using DigitalRuby.Tween; using System; using System.Collections; using System.Collections.Generic; @@ -5,7 +6,6 @@ using System.Linq; using TMPro; using UnityEngine; using UnityEngine.UI; -using DigitalRuby.Tween; public class HangmanController : AbstractFeedback { @@ -162,11 +162,6 @@ public class HangmanController : AbstractFeedback /// public MinigameList minigamelist; - /// - /// Reference to the user list to access the current user - /// - public UserList userList; - /// /// Reference to the current user /// @@ -175,7 +170,7 @@ public class HangmanController : AbstractFeedback /// /// Reference to the minigame progress of the current user /// - private Progress progress = null; + private PersistentDataController.SavedMinigameProgress progress = null; /// /// Reference to the scoreboard @@ -262,18 +257,15 @@ public class HangmanController : AbstractFeedback playerPanel.SetActive(true); // Create entry in current user for keeping track of progress - userList.Load(); - user = userList.GetCurrentUser(); - Progress progress = user.GetMinigameProgress(minigame.index); + user = UserList.GetCurrentUser(); + progress = user.GetMinigameProgress(minigame.index); if (progress == null) { - progress = new Progress(); - progress.AddOrUpdate("minigameIndex", minigame.index); - progress.AddOrUpdate>("highestScores", new List()); - progress.AddOrUpdate>("latestScores", new List()); - user.minigames.Add(progress); + progress = new PersistentDataController.SavedMinigameProgress(); + progress.minigameIndex = minigame.index; + user.AddMinigameProgress(progress); } - userList.Save(); + UserList.Save(); } /// @@ -577,12 +569,11 @@ public class HangmanController : AbstractFeedback score.time = DateTime.Now.ToString(); // Save the new score - user = userList.GetCurrentUser(); - Progress progress = user.GetMinigameProgress(minigame.index); + progress = user.GetMinigameProgress(minigame.index); // Get the current list of scores - List latestScores = progress.Get>("latestScores"); - List highestScores = progress.Get>("highestScores"); + List latestScores = progress.latestScores; + List highestScores = progress.highestScores; // Add the new score latestScores.Add(score); @@ -592,10 +583,10 @@ public class HangmanController : AbstractFeedback highestScores.Sort((a, b) => b.scoreValue.CompareTo(a.scoreValue)); // Only save the top 10 scores, so this list doesn't keep growing endlessly - progress.AddOrUpdate>("latestScores", latestScores.Take(10).ToList()); - progress.AddOrUpdate>("highestScores", highestScores.Take(10).ToList()); + progress.latestScores = latestScores.Take(10).ToList(); + progress.highestScores = highestScores.Take(10).ToList(); - userList.Save(); + UserList.Save(); } /// @@ -654,17 +645,17 @@ public class HangmanController : AbstractFeedback // Instantiate new entries // Get all scores from all users List> allScores = new List>(); - foreach (User user in userList.GetUsers()) + foreach (User user in UserList.GetUsers()) { // Get user's progress for this minigame - progress = user.minigames.Find((p) => p != null && p.Get("minigameIndex") == minigame.index); + progress = user.GetMinigameProgress(minigame.index); if (progress != null) { // Add scores to dictionary - List scores = progress.Get>("highestScores"); + List scores = progress.highestScores; foreach (Score score in scores) { - allScores.Add(new Tuple(user.username, score)); + allScores.Add(new Tuple(user.GetUsername(), score)); } } } @@ -682,7 +673,7 @@ public class HangmanController : AbstractFeedback GameObject entry = Instantiate(scoreboardEntry, EntriesGrid); entries.Add(entry); // Set the player icon - entry.transform.Find("Image").GetComponent().sprite = userList.GetUserByUsername(username).avatar; + entry.transform.Find("Image").GetComponent().sprite = UserList.GetUserByUsername(username).GetAvatar(); // Set the player name entry.transform.Find("PlayerName").GetComponent().text = username; diff --git a/Assets/Hangman/Scripts/HangmanScripts.asmdef b/Assets/Hangman/Scripts/HangmanScripts.asmdef new file mode 100644 index 0000000..ec792c4 --- /dev/null +++ b/Assets/Hangman/Scripts/HangmanScripts.asmdef @@ -0,0 +1,21 @@ +{ + "name": "HangmanScripts", + "rootNamespace": "", + "references": [ + "GUID:e83ddf9a537a96b4a804a16bb7872ec1", + "GUID:6055be8ebefd69e48b49212b09b47b2f", + "GUID:1631ed2680c61245b8211d943c1639a8", + "GUID:d0b6b39a21908f94fbbd9f2c196a9725", + "GUID:58e104b97fb3752438ada2902a36dcbf", + "GUID:7f2d0ee6dd21e1d4eb25b71b7a749d25" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/Hangman/Scripts/HangmanScripts.asmdef.meta b/Assets/Hangman/Scripts/HangmanScripts.asmdef.meta new file mode 100644 index 0000000..675a808 --- /dev/null +++ b/Assets/Hangman/Scripts/HangmanScripts.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 99b7a088eba870d4486dbdc5ad359f27 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/JustSign/Scripts/JustSignController.cs b/Assets/JustSign/Scripts/JustSignController.cs index d5caf6d..01b256e 100644 --- a/Assets/JustSign/Scripts/JustSignController.cs +++ b/Assets/JustSign/Scripts/JustSignController.cs @@ -10,7 +10,7 @@ using UnityEngine.UI; /// Contains all game logic for the JustSign game /// public class JustSignController : MonoBehaviour -{ +{ /// /// All of the words that can be used in this session /// @@ -107,7 +107,7 @@ public class JustSignController : MonoBehaviour /// Controls movement speed of symbols (higher -> faster) /// private int moveSpeed = 200; - + /// /// Starting X-coordinate of a symbol = (-1920 - symbolsize) / 2 /// @@ -213,11 +213,6 @@ public class JustSignController : MonoBehaviour /// public GameObject scoreboardEntry; - /// - /// Reference to the user list to access the current user - /// - public UserList userList; - /// /// Reference to the current user /// @@ -276,18 +271,15 @@ public class JustSignController : MonoBehaviour score = 0; gameEndedPanel.SetActive(false); // Create entry in current user for keeping track of progress - userList.Load(); - user = userList.GetCurrentUser(); - Progress progress = user.GetMinigameProgress(minigame.index); + user = UserList.GetCurrentUser(); + var progress = user.GetMinigameProgress(minigame.index); if (progress == null) { - progress = new Progress(); - progress.AddOrUpdate("minigameIndex", minigame.index); - progress.AddOrUpdate>("highestScores", new List()); - progress.AddOrUpdate>("latestScores", new List()); - user.minigames.Add(progress); + progress = new PersistentDataController.SavedMinigameProgress(); + progress.minigameIndex = minigame.index; + user.AddMinigameProgress(progress); } - userList.Save(); + PersistentDataController.GetInstance().Save(); scoreDisplay.text = "Score: " + score.ToString(); currentTheme = minigame.themeList.themes[minigame.themeList.currentThemeIndex]; @@ -314,31 +306,42 @@ public class JustSignController : MonoBehaviour /// Update is called once per frame /// void Update() - { - if (gameIsActive) { + { + if (gameIsActive) + { int matchedSymbolIndex = -1; - for (int i = 0; i < activeWords.Count; i++) { - if (activeWords[i].ToLower() == answerField.text.ToLower()) { + for (int i = 0; i < activeWords.Count; i++) + { + if (activeWords[i].ToLower() == answerField.text.ToLower()) + { matchedSymbolIndex = i; } } // Destroy the oldest symbol if the current input matches it - if (matchedSymbolIndex >= 0) { - int difference = Math.Abs((int) (activeSymbols[matchedSymbolIndex].transform.position.x - hitZone.transform.position.x)); - if (difference < perfectBoundary) { + if (matchedSymbolIndex >= 0) + { + int difference = Math.Abs((int)(activeSymbols[matchedSymbolIndex].transform.position.x - hitZone.transform.position.x)); + if (difference < perfectBoundary) + { feedBack.text = "Perfect!"; perfectSigns++; score += perfectScore; - } else if (difference < goodBoundary) { + } + else if (difference < goodBoundary) + { feedBack.text = "Good!"; goodSigns++; score += goodScore; - } else if (difference < mehBoundary) { + } + else if (difference < mehBoundary) + { feedBack.text = "Meh..."; mehSigns++; score += mehScore; - } else { + } + else + { feedBack.text = "Terrible!"; terribleSigns++; score += terribleScore; @@ -349,8 +352,10 @@ public class JustSignController : MonoBehaviour } // Destroy the oldest symbol if it leaves the screen - if (activeSymbols.Count > 0) { - if (activeSymbols[0].GetComponent().localPosition.x > -trackX) { + if (activeSymbols.Count > 0) + { + if (activeSymbols[0].GetComponent().localPosition.x > -trackX) + { DestroySymbolAt(0); incorrectSigns++; feedBack.text = "Te laat!"; @@ -360,18 +365,21 @@ public class JustSignController : MonoBehaviour // Spawn new symbol every spawn period float currentTime = Time.time; - if (currentTime - lastSpawn > currentSong.spawnPeriod && lastSymbolTime > currentTime) { + if (currentTime - lastSpawn > currentSong.spawnPeriod && lastSymbolTime > currentTime) + { lastSpawn = currentTime; SpawnNewSymbol(); } // Check if the song has ended and activate scorescreen if it has - if (currentTime - beginTime > currentSong.duration) { + if (currentTime - beginTime > currentSong.duration) + { ActivateEnd(); } // Move all active symbols to the right - foreach (GameObject symbol in activeSymbols) { + foreach (GameObject symbol in activeSymbols) + { RectTransform rectTransform = symbol.GetComponent(); rectTransform.localPosition = new Vector3(rectTransform.localPosition.x + Time.deltaTime * moveSpeed, trackY, 0); } @@ -401,7 +409,8 @@ public class JustSignController : MonoBehaviour /// Destroy the symbol at the given index /// /// The index of the symbol to destroy - void DestroySymbolAt(int index) { + void DestroySymbolAt(int index) + { activeWords.RemoveAt(index); GameObject symbol = activeSymbols[index]; activeSymbols.RemoveAt(index); @@ -411,12 +420,15 @@ public class JustSignController : MonoBehaviour /// /// Create a new symbol at the start of the track /// - void SpawnNewSymbol() { + void SpawnNewSymbol() + { // Pick a word that isn't in use yet List unusedWordIndices = new List(); - for (int i = 0; i < words.Count; i++) { - if (!activeWords.Contains(words[i].name)) { + for (int i = 0; i < words.Count; i++) + { + if (!activeWords.Contains(words[i].name)) + { unusedWordIndices.Add(i); } } @@ -455,12 +467,11 @@ public class JustSignController : MonoBehaviour score.time = DateTime.Now.ToString(); // Save the new score - user = userList.GetCurrentUser(); - Progress progress = user.GetMinigameProgress(minigame.index); + var progress = user.GetMinigameProgress(minigame.index); // Get the current list of scores - List latestScores = progress.Get>("latestScores"); - List highestScores = progress.Get>("highestScores"); + List latestScores = progress.latestScores; + List highestScores = progress.highestScores; // Add the new score latestScores.Add(score); @@ -470,10 +481,10 @@ public class JustSignController : MonoBehaviour highestScores.Sort((a, b) => b.scoreValue.CompareTo(a.scoreValue)); // Only save the top 10 scores, so this list doesn't keep growing endlessly - progress.AddOrUpdate>("latestScores", latestScores.Take(10).ToList()); - progress.AddOrUpdate>("highestScores", highestScores.Take(10).ToList()); + progress.latestScores = latestScores.Take(10).ToList(); + progress.highestScores = highestScores.Take(10).ToList(); - userList.Save(); + PersistentDataController.GetInstance().Save(); } /// @@ -520,17 +531,17 @@ public class JustSignController : MonoBehaviour // Instantiate new entries // Get all scores from all users List> allScores = new List>(); - foreach (User user in userList.GetUsers()) + foreach (User user in UserList.GetUsers()) { // Get user's progress for this minigame - Progress progress = user.GetMinigameProgress(minigame.index); + var progress = user.GetMinigameProgress(minigame.index); if (progress != null) { // Add scores to dictionary - List scores = progress.Get>("highestScores"); + List scores = progress.highestScores; foreach (Score score in scores) { - allScores.Add(new Tuple(user.username, score)); + allScores.Add(new Tuple(user.GetUsername(), score)); } } } @@ -549,7 +560,7 @@ public class JustSignController : MonoBehaviour scoreboardEntries.Add(entry); // Set the player icon - entry.transform.Find("Image").GetComponent().sprite = userList.GetUserByUsername(username).avatar; + entry.transform.Find("Image").GetComponent().sprite = UserList.GetUserByUsername(username).GetAvatar(); // Set the player name entry.transform.Find("PlayerName").GetComponent().text = username; diff --git a/Assets/JustSign/Scripts/JustSignScripts.asmdef b/Assets/JustSign/Scripts/JustSignScripts.asmdef new file mode 100644 index 0000000..3cf239e --- /dev/null +++ b/Assets/JustSign/Scripts/JustSignScripts.asmdef @@ -0,0 +1,19 @@ +{ + "name": "JustSignScripts", + "rootNamespace": "", + "references": [ + "GUID:e83ddf9a537a96b4a804a16bb7872ec1", + "GUID:6055be8ebefd69e48b49212b09b47b2f", + "GUID:1631ed2680c61245b8211d943c1639a8", + "GUID:7f2d0ee6dd21e1d4eb25b71b7a749d25" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/JustSign/Scripts/JustSignScripts.asmdef.meta b/Assets/JustSign/Scripts/JustSignScripts.asmdef.meta new file mode 100644 index 0000000..1a4de81 --- /dev/null +++ b/Assets/JustSign/Scripts/JustSignScripts.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 643048e31db889c4c8ab5a04e9a70473 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SpellingBee/PlayModeTests/GameEndedPanelTests.cs b/Assets/SpellingBee/PlayModeTests/GameEndedPanelTests.cs index 5ab2d69..daba817 100644 --- a/Assets/SpellingBee/PlayModeTests/GameEndedPanelTests.cs +++ b/Assets/SpellingBee/PlayModeTests/GameEndedPanelTests.cs @@ -1,28 +1,21 @@ -using System.Collections; -using System.Linq; -using System.IO; - using NUnit.Framework; -using TMPro; +using System.Collections; +using System.IO; +using UnityEditor; using UnityEngine; using UnityEngine.TestTools; -using UnityEngine.SceneManagement; - public class GameEndedPanelTests { - [UnitySetUp] public IEnumerator SetupFunction() { string path = $"{Application.persistentDataPath}/unit_test_users.json"; - var oneUser = "{\"currentUserIndex\": 0,\"storedUsers\": [{\"username\": \"TEST\",\"avatar\": {\"instanceID\": 40848},\"playtime\": 0.0,\"courses\": [],\"minigames\": []}]}"; - - using (StreamWriter writer = new StreamWriter(path)) - { - writer.Write(oneUser); - } + string oneUser = $"{{\"version\":{PersistentDataController.VERSION},\"users\":[{{\"entries\":[],\"username\":\"TEST\",\"avatarIndex\":0,\"playtime\":0.0,\"minigames\":[],\"courses\":[]}}],\"currentUser\":0,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; + File.WriteAllText(path, oneUser); + PersistentDataController.GetInstance().Load(); + AssetDatabase.LoadAssetAtPath("Assets/Accounts/ScriptableObjects/UserAvatarList.asset").Awake(); SystemController.GetInstance().LoadNextScene("SpellingBee/Scenes/SpellingBeeGame"); yield return new WaitForSeconds(0.2f); } diff --git a/Assets/SpellingBee/PlayModeTests/SpellingBeeControllerTests.cs b/Assets/SpellingBee/PlayModeTests/SpellingBeeControllerTests.cs index 5049f44..19f62dd 100644 --- a/Assets/SpellingBee/PlayModeTests/SpellingBeeControllerTests.cs +++ b/Assets/SpellingBee/PlayModeTests/SpellingBeeControllerTests.cs @@ -1,28 +1,21 @@ -using System.Collections; -using System.Linq; -using System.IO; - using NUnit.Framework; -using TMPro; +using System.Collections; +using System.IO; +using UnityEditor; using UnityEngine; using UnityEngine.TestTools; -using UnityEngine.SceneManagement; - public class SpellingBeeControllerTests { - [UnitySetUp] public IEnumerator SetupFunction() { string path = $"{Application.persistentDataPath}/unit_test_users.json"; - var oneUser = "{\"currentUserIndex\": 0,\"storedUsers\": [{\"username\": \"TEST\",\"avatar\": {\"instanceID\": 40848},\"playtime\": 0.0,\"courses\": [],\"minigames\": []}]}"; - - using (StreamWriter writer = new StreamWriter(path)) - { - writer.Write(oneUser); - } + string oneUser = $"{{\"version\":{PersistentDataController.VERSION},\"users\":[{{\"entries\":[],\"username\":\"TEST\",\"avatarIndex\":0,\"playtime\":0.0,\"minigames\":[],\"courses\":[]}}],\"currentUser\":0,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; + File.WriteAllText(path, oneUser); + PersistentDataController.GetInstance().Load(); + AssetDatabase.LoadAssetAtPath("Assets/Accounts/ScriptableObjects/UserAvatarList.asset").Awake(); SystemController.GetInstance().LoadNextScene("SpellingBee/Scenes/SpellingBeeGame"); yield return new WaitForSeconds(0.2f); } diff --git a/Assets/SpellingBee/PlayModeTests/SpellingBeePlayModeTests.asmdef b/Assets/SpellingBee/PlayModeTests/SpellingBeePlayModeTests.asmdef index 3cb15ac..4c3d59e 100644 --- a/Assets/SpellingBee/PlayModeTests/SpellingBeePlayModeTests.asmdef +++ b/Assets/SpellingBee/PlayModeTests/SpellingBeePlayModeTests.asmdef @@ -8,6 +8,7 @@ "Unity.TextMeshPro", "SpellingBeeScripts", "AccountsScripts", + "SystemArchitecture", "SignPredictor" ], "includePlatforms": [], diff --git a/Assets/SpellingBee/Scripts/GameEndedPanel.cs b/Assets/SpellingBee/Scripts/GameEndedPanel.cs index e6dfff4..096da0c 100644 --- a/Assets/SpellingBee/Scripts/GameEndedPanel.cs +++ b/Assets/SpellingBee/Scripts/GameEndedPanel.cs @@ -7,8 +7,6 @@ using UnityEngine.UI; public class GameEndedPanel : MonoBehaviour { - public UserList userList; - /// /// "VERLOREN" or "GEWONNEN" /// @@ -125,17 +123,17 @@ public class GameEndedPanel : MonoBehaviour // Instantiate new entries // Get all scores from all users List> allScores = new List>(); - foreach (User user in userList.GetUsers()) + foreach (User user in UserList.GetUsers()) { // Get user's progress for this minigame - Progress progress = user.GetMinigameProgress(MinigameIndex.SPELLING_BEE); + var progress = user.GetMinigameProgress(MinigameIndex.SPELLING_BEE); if (progress != null) { // Add scores to dictionary - List scores = progress.Get>("highestScores"); + List scores = progress.highestScores; foreach (Score score in scores) { - allScores.Add(new Tuple(user.username, score)); + allScores.Add(new Tuple(user.GetUsername(), score)); } } } @@ -154,7 +152,7 @@ public class GameEndedPanel : MonoBehaviour scoreboardEntries.Add(entry); // Set the player icon - entry.transform.Find("Image").GetComponent().sprite = userList.GetUserByUsername(username).avatar; + entry.transform.Find("Image").GetComponent().sprite = UserList.GetUserByUsername(username).GetAvatar(); // Set the player name entry.transform.Find("PlayerName").GetComponent().text = username; diff --git a/Assets/SpellingBee/Scripts/SpellingBeeController.cs b/Assets/SpellingBee/Scripts/SpellingBeeController.cs index a179a81..16954f0 100644 --- a/Assets/SpellingBee/Scripts/SpellingBeeController.cs +++ b/Assets/SpellingBee/Scripts/SpellingBeeController.cs @@ -76,11 +76,6 @@ public partial class SpellingBeeController : AbstractFeedback /// private DateTime startTime; - /// - /// Reference to the user list to access the current user - /// - public UserList userList; - /// /// Reference to the current user /// @@ -204,18 +199,15 @@ public partial class SpellingBeeController : AbstractFeedback bonusTimeText.SetActive(false); // Create entry in current user for keeping track of progress - userList.Load(); - user = userList.GetCurrentUser(); - Progress progress = user.GetMinigameProgress(minigame.index); + user = UserList.GetCurrentUser(); + var progress = user.GetMinigameProgress(minigame.index); if (progress == null) { - progress = new Progress(); - progress.AddOrUpdate("minigameIndex", MinigameIndex.SPELLING_BEE); - progress.AddOrUpdate>("highestScores", new List()); - progress.AddOrUpdate>("latestScores", new List()); - user.minigames.Add(progress); + progress = new PersistentDataController.SavedMinigameProgress(); + progress.minigameIndex = MinigameIndex.SPELLING_BEE; + user.AddMinigameProgress(progress); } - userList.Save(); + UserList.Save(); currentTheme = minigame.themeList.themes[minigame.themeList.currentThemeIndex]; //feedback.signPredictor.ChangeModel(currentTheme.modelIndex); @@ -337,12 +329,11 @@ public partial class SpellingBeeController : AbstractFeedback score.time = DateTime.Now.ToString(); // Save the new score - user = userList.GetCurrentUser(); - Progress progress = user.GetMinigameProgress(minigame.index); + var progress = user.GetMinigameProgress(minigame.index); // Get the current list of scores - List latestScores = progress.Get>("latestScores"); - List highestScores = progress.Get>("highestScores"); + List latestScores = progress.latestScores; + List highestScores = progress.highestScores; // Add the new score latestScores.Add(score); @@ -352,10 +343,10 @@ public partial class SpellingBeeController : AbstractFeedback highestScores.Sort((a, b) => b.scoreValue.CompareTo(a.scoreValue)); // Only save the top 10 scores, so this list doesn't keep growing endlessly - progress.AddOrUpdate>("latestScores", latestScores.Take(10).ToList()); - progress.AddOrUpdate>("highestScores", highestScores.Take(10).ToList()); + progress.latestScores = latestScores.Take(10).ToList(); + progress.highestScores = highestScores.Take(10).ToList(); - userList.Save(); + UserList.Save(); } /// diff --git a/Assets/SpellingBee/Scripts/SpellingBeeScripts.asmdef b/Assets/SpellingBee/Scripts/SpellingBeeScripts.asmdef index dd37fc8..7c87746 100644 --- a/Assets/SpellingBee/Scripts/SpellingBeeScripts.asmdef +++ b/Assets/SpellingBee/Scripts/SpellingBeeScripts.asmdef @@ -6,8 +6,9 @@ "GUID:1631ed2680c61245b8211d943c1639a8", "GUID:3444c67d5a3a93e5a95a48906078c372", "GUID:d0b6b39a21908f94fbbd9f2c196a9725", - "GUID:7f2d0ee6dd21e1d4eb25b71b7a749d25", - "GUID:58e104b97fb3752438ada2902a36dcbf" + "GUID:58e104b97fb3752438ada2902a36dcbf", + "GUID:e83ddf9a537a96b4a804a16bb7872ec1", + "GUID:7f2d0ee6dd21e1d4eb25b71b7a749d25" ], "includePlatforms": [], "excludePlatforms": [], diff --git a/Assets/SpellingBee/Tests/BasicTests.cs b/Assets/SpellingBee/Tests/BasicTests.cs index 7da4cc0..7cffd7c 100644 --- a/Assets/SpellingBee/Tests/BasicTests.cs +++ b/Assets/SpellingBee/Tests/BasicTests.cs @@ -1,7 +1,5 @@ -using System.Collections; -using System.Collections.Generic; using NUnit.Framework; -using UnityEngine; +using System.Collections; using UnityEngine.TestTools; public class BasicTests diff --git a/Assets/Resources.meta b/Assets/SystemArchitecture.meta similarity index 77% rename from Assets/Resources.meta rename to Assets/SystemArchitecture.meta index a546ddd..35c4f20 100644 --- a/Assets/Resources.meta +++ b/Assets/SystemArchitecture.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: c3f7371598add9549b5351c44a9e17b3 +guid: 00903f60e81ce95419bc0c62a11ddfd1 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/Resources/Models.meta b/Assets/SystemArchitecture/Scripts.meta similarity index 77% rename from Assets/Resources/Models.meta rename to Assets/SystemArchitecture/Scripts.meta index 7f94823..5cf4d68 100644 --- a/Assets/Resources/Models.meta +++ b/Assets/SystemArchitecture/Scripts.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 7992d1284c7de4b089f4155b3e4ada83 +guid: 17374f544297b194aa5517c196ca2f07 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/Common/Interfaces/CourseIndex.cs b/Assets/SystemArchitecture/Scripts/CourseIndex.cs similarity index 100% rename from Assets/Common/Interfaces/CourseIndex.cs rename to Assets/SystemArchitecture/Scripts/CourseIndex.cs diff --git a/Assets/Common/Interfaces/CourseIndex.cs.meta b/Assets/SystemArchitecture/Scripts/CourseIndex.cs.meta similarity index 100% rename from Assets/Common/Interfaces/CourseIndex.cs.meta rename to Assets/SystemArchitecture/Scripts/CourseIndex.cs.meta diff --git a/Assets/Common/Interfaces/MinigameIndex.cs b/Assets/SystemArchitecture/Scripts/MinigameIndex.cs similarity index 100% rename from Assets/Common/Interfaces/MinigameIndex.cs rename to Assets/SystemArchitecture/Scripts/MinigameIndex.cs diff --git a/Assets/Common/Interfaces/MinigameIndex.cs.meta b/Assets/SystemArchitecture/Scripts/MinigameIndex.cs.meta similarity index 100% rename from Assets/Common/Interfaces/MinigameIndex.cs.meta rename to Assets/SystemArchitecture/Scripts/MinigameIndex.cs.meta diff --git a/Assets/SystemArchitecture/Scripts/PersistentDataController.cs b/Assets/SystemArchitecture/Scripts/PersistentDataController.cs new file mode 100644 index 0000000..6cdf579 --- /dev/null +++ b/Assets/SystemArchitecture/Scripts/PersistentDataController.cs @@ -0,0 +1,427 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.Serialization.Formatters.Binary; +using UnityEngine; + +/// +/// PersistentDataController singleton +/// +public class PersistentDataController +{ + /// + /// The instance controlling the singleton + /// + private static PersistentDataController instance = null; + + /// + /// Current implementation version of the PersistentDataController + /// + /// MSB represent sprint version, LSB represent subversion + public static readonly int VERSION = 0x04_01; + + /// + /// Path of the .json-file to store all serialized data + /// + public static string PATH = null; + + /// + /// Class to hold a list of data records + /// + [Serializable] + public class PersistentDataContainer + { + /// + /// A helper class for handling the stored progress + /// + [Serializable] + public class PersistentDataEntry + { + /// + /// The key, used to reference the data object + /// + public string key; + + /// + /// The object, representated as a list of byte (which can be serialized) + /// + public List data = new List(); + + public PersistentDataEntry(string key, byte[] data) : this(key, data.ToList()) + { } + + public PersistentDataEntry(string key, List data) + { + this.key = key; + this.data = data; + } + } + + /// + /// List of data records + /// + public List entries = new List(); + + /// + /// Update the value of a certain key, + /// or add a new value if the key was not present. + /// + /// The type of the data to be added/updated + /// The key, used for referencing the data + /// The object of type + /// true if successful, false otherwise + public bool Set(string key, T data) + { + if (data == null) + return false; + + PersistentDataEntry entry = entries.Find(x => x.key == key); + + // Hacky serialization stuff + BinaryFormatter bf = new BinaryFormatter(); + using (MemoryStream ms = new MemoryStream()) + { + bf.Serialize(ms, data); + if (entry != null) + { + entry.data.Clear(); + entry.data.AddRange(ms.ToArray()); + } + else + { + entries.Add(new PersistentDataEntry(key, ms.ToArray())); + } + return true; + } + } + + /// + /// Get the data object of a certain key + /// + /// The type of the data object + /// The key referencing the data object + /// The data, cast to a type + /// + /// + public T Get(string key) + { + BinaryFormatter bf = new BinaryFormatter(); + using (MemoryStream ms = new MemoryStream()) + { + // Find the correct key + foreach (PersistentDataEntry entry in entries) + { + if (entry.key == key) + { + // Hacky serialization stuff + byte[] data = entry.data.ToArray(); + ms.Write(data, 0, data.Length); + ms.Seek(0, SeekOrigin.Begin); + return (T)bf.Deserialize(ms); + } + } + } + + // Raise an exception when key is not found + throw new KeyNotFoundException(); + } + + /// + /// Remove a key-value from the data. + /// + /// The key referencing the data object + /// + public void Remove(string key) + { + if (!Has(key)) + throw new KeyNotFoundException(); + + entries.Remove(entries.Find(x => x.key == key)); + } + + /// + /// Remove and return value from the data. + /// + /// The type of the data object + /// The key referencing the data object + /// Whether the removal of the data should also be saved to disk + /// + public T Pop(string key) + { + T data = Get(key); + Remove(key); + return data; + } + + /// + /// Check whether a key is present + /// + /// The key to check + /// true if a item can be found with the specified key + public bool Has(string key) + { + return entries.Find(x => x.key == key) != null; + } + } + + /// + /// Stored user data record + /// + [Serializable] + public class SavedUserData : PersistentDataContainer + { + public string username = null; + public int avatarIndex = -1; + public double playtime = 0.0; + public List minigames = new List(); + public List courses = new List(); + } + + /// + /// Stored course progress data record + /// + [Serializable] + public class SavedCourseProgress : PersistentDataContainer + { + public CourseIndex courseIndex; + public float progress = -1.0f; + } + + /// + /// Stored minigame progress data record + /// + [Serializable] + public class SavedMinigameProgress : PersistentDataContainer + { + public MinigameIndex minigameIndex; + public List latestScores = new List(); + public List highestScores = new List(); + } + + /// + /// Stored WeSign data record + /// + [Serializable] + private class SavedDataStructure + { + public int version = VERSION; + public List users = new List(); + public int currentUser = -1; + public MinigameIndex currentMinigame; + public CourseIndex currentCourse; + public ThemeIndex currentTheme; + } + + /// + /// The object holding the data references + /// + private SavedDataStructure json = new SavedDataStructure(); + + /// + /// Get the instance loaded by the singleton + /// + /// PersistentDataController instance + public static PersistentDataController GetInstance() + { + // Create a new instance if non exists + if (instance == null) + { + if (PATH == null) + PersistentDataController.PATH = $"{Application.persistentDataPath}/wesign_saved_data.json"; + instance = new PersistentDataController(); + } + return instance; + } + + /// + /// PersistentDataController contructor + /// + private PersistentDataController() + { + Load(); + } + + /// + /// Clear everything stored in the PersistentDataController, won't save to disk + /// + public void Clear() + { + json.users.Clear(); + json.currentUser = -1; + } + + /// + /// Save all data to disk + /// + public void Save() + { + string text = JsonUtility.ToJson(json); + File.CreateText(PATH).Close(); + File.WriteAllText(PATH, text); + } + + /// + /// Override current data with the data from disk, will just clear if no data was found. + /// + /// true if you want to override the existing file if it exists and the loading failed. + /// If the data on disk is outdated (version number is lower than the current version), the loading will also fail + /// true if successful, false otherwise + public bool Load(bool overrideOnFail = true) + { + Clear(); + if (!File.Exists(PATH)) + goto failed; + + try + { + string text = File.ReadAllText(PATH); + SavedDataStructure newJson = JsonUtility.FromJson(text); + if (newJson == null || newJson.version < VERSION) + goto failed; + + json = newJson; + return true; + } + catch (Exception) { goto failed; } + + failed: + if (overrideOnFail) + Save(); + return false; + } + + /// + /// Add a user to the WeSign data record + /// + /// User data record + /// Whether to save the addition immediately to disk + public void AddUser(SavedUserData user, bool save = true) + { + if (json.users.Count == 0) + json.currentUser = 0; + json.users.Add(user); + + if (save) + Save(); + } + + /// + /// Get a list of all user data records + /// + /// + public List GetUsers() + { + return json.users; + } + + /// + /// Get the index of the current user + /// + /// + public int GetCurrentUser() + { + return json.currentUser; + } + + /// + /// Set the index of the current record + /// + /// New index + /// Whether to save the change immediately to disk + /// + public void SetCurrentUser(int index, bool save = true) + { + if (index < 0 || json.users.Count <= index) + throw new IndexOutOfRangeException(); + json.currentUser = index; + + if (save) + Save(); + } + + /// + /// Remove a user data record + /// + /// Index of the user + /// Whether to save the deletion immediately to disk + /// + public void DeleteUser(int index, bool save = true) + { + if (index < 0 || json.users.Count <= index) + throw new IndexOutOfRangeException(); + + if (0 < json.currentUser && index <= json.currentUser) + json.currentUser--; + json.users.RemoveAt(index); + + if (save) + Save(); + } + + /// + /// Get the current course + /// + /// + public CourseIndex GetCurrentCourse() + { + return json.currentCourse; + } + + /// + /// Set the current course + /// + /// New course index + /// Whether to save the change immediately to disk + public void SetCurrentCourse(CourseIndex course, bool save = true) + { + json.currentCourse = course; + + if (save) + Save(); + } + + /// + /// Get the current minigame + /// + /// + public MinigameIndex GetCurrentMinigame() + { + return json.currentMinigame; + } + + /// + /// Set the current minigame + /// + /// New minigame index + /// Whether to save the change immediately to disk + public void SetCurrentMinigame(MinigameIndex minigame, bool save = true) + { + json.currentMinigame = minigame; + + if (save) + Save(); + } + + /// + /// Get the current theme + /// + /// + public ThemeIndex GetCurrentTheme() + { + return json.currentTheme; + } + + /// + /// Set the current theme + /// + /// New theme index + /// Whether to save the change immediately to disk + public void SetCurrentTheme(ThemeIndex theme, bool save = true) + { + json.currentTheme = theme; + + if (save) + Save(); + } +} diff --git a/Assets/Accounts/Tests/ProgressTest.cs.meta b/Assets/SystemArchitecture/Scripts/PersistentDataController.cs.meta similarity index 83% rename from Assets/Accounts/Tests/ProgressTest.cs.meta rename to Assets/SystemArchitecture/Scripts/PersistentDataController.cs.meta index b3be9da..9eeea85 100644 --- a/Assets/Accounts/Tests/ProgressTest.cs.meta +++ b/Assets/SystemArchitecture/Scripts/PersistentDataController.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 30234b937b9c84460ad4846ae1941484 +guid: 164b1accbeff688429a4311f1e40bd59 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Common/Interfaces/Score.cs b/Assets/SystemArchitecture/Scripts/Score.cs similarity index 100% rename from Assets/Common/Interfaces/Score.cs rename to Assets/SystemArchitecture/Scripts/Score.cs diff --git a/Assets/Common/Interfaces/Score.cs.meta b/Assets/SystemArchitecture/Scripts/Score.cs.meta similarity index 100% rename from Assets/Common/Interfaces/Score.cs.meta rename to Assets/SystemArchitecture/Scripts/Score.cs.meta diff --git a/Assets/SystemArchitecture/Scripts/SystemArchitectureScripts.asmdef b/Assets/SystemArchitecture/Scripts/SystemArchitectureScripts.asmdef new file mode 100644 index 0000000..ffce47e --- /dev/null +++ b/Assets/SystemArchitecture/Scripts/SystemArchitectureScripts.asmdef @@ -0,0 +1,14 @@ +{ + "name": "SystemArchitecture", + "rootNamespace": "", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/SystemArchitecture/Scripts/SystemArchitectureScripts.asmdef.meta b/Assets/SystemArchitecture/Scripts/SystemArchitectureScripts.asmdef.meta new file mode 100644 index 0000000..b28cb92 --- /dev/null +++ b/Assets/SystemArchitecture/Scripts/SystemArchitectureScripts.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: e83ddf9a537a96b4a804a16bb7872ec1 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Accounts/Scripts/SystemController.cs b/Assets/SystemArchitecture/Scripts/SystemController.cs similarity index 100% rename from Assets/Accounts/Scripts/SystemController.cs rename to Assets/SystemArchitecture/Scripts/SystemController.cs diff --git a/Assets/Accounts/Scripts/SystemController.cs.meta b/Assets/SystemArchitecture/Scripts/SystemController.cs.meta similarity index 100% rename from Assets/Accounts/Scripts/SystemController.cs.meta rename to Assets/SystemArchitecture/Scripts/SystemController.cs.meta diff --git a/Assets/Common/Interfaces/ThemeIndex.cs b/Assets/SystemArchitecture/Scripts/ThemeIndex.cs similarity index 100% rename from Assets/Common/Interfaces/ThemeIndex.cs rename to Assets/SystemArchitecture/Scripts/ThemeIndex.cs diff --git a/Assets/Common/Interfaces/ThemeIndex.cs.meta b/Assets/SystemArchitecture/Scripts/ThemeIndex.cs.meta similarity index 100% rename from Assets/Common/Interfaces/ThemeIndex.cs.meta rename to Assets/SystemArchitecture/Scripts/ThemeIndex.cs.meta diff --git a/Assets/SystemArchitecture/Tests.meta b/Assets/SystemArchitecture/Tests.meta new file mode 100644 index 0000000..0a1cfbf --- /dev/null +++ b/Assets/SystemArchitecture/Tests.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 8559f509b8f924f44bc10e2d20ac3eed +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SystemArchitecture/Tests/PersistentDataControllerTest.cs b/Assets/SystemArchitecture/Tests/PersistentDataControllerTest.cs new file mode 100644 index 0000000..68e7fa6 --- /dev/null +++ b/Assets/SystemArchitecture/Tests/PersistentDataControllerTest.cs @@ -0,0 +1,606 @@ +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.IO; +using UnityEngine; + +[TestFixture] +public class PersistentDataTests +{ + /// + /// Create a new path so the existing .json file will not be overwritten + /// + private static string PATH = $"{Application.persistentDataPath}/wesign_unit_test.json"; + + /// + /// Reference to the pdc to perform tests on + /// + private PersistentDataController pdc = null; + + /// + /// A dummy serializable struct to perform test operations on + /// + [Serializable] + private struct Struct + { + public int r, g, b; + public float x, y, z; + } + + /// + /// A dummy serializable enum to perform test operations on + /// + private enum Enum + { + SQUARE, + TRIANBLE, + CIRCLE + } + + [SetUp] + public void Setup_PersistentDataController() + { + PersistentDataController.PATH = PersistentDataTests.PATH; + //PersistentDataController.PATH = null; + pdc = PersistentDataController.GetInstance(); + } + + [Test] + public void Test_PersistentDataController_GetInstance() + { + Assert.IsNotNull(pdc); + //Assert.AreEqual($"{Application.persistentDataPath}/wesign_saved_data.json", PersistentDataController.PATH); + } + + [Test] + public void Test_PersistentDataController_Clear() + { + pdc.Load(); + pdc.Clear(); + Assert.Zero(pdc.GetUsers().Count); + Assert.AreEqual(-1, pdc.GetCurrentUser()); + } + + [Test] + public void Test_PersistentDataController_Save_Empty() + { + pdc.Load(); + pdc.Clear(); + + pdc.Save(); + FileAssert.Exists(PATH); + + string content = File.ReadAllText(PATH); + string expected = $"{{\"version\":{PersistentDataController.VERSION},\"users\":[],\"currentUser\":-1,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; + Assert.AreEqual(expected, content); + } + + [Test] + public void Test_PersistentDataController_Save_New() + { + pdc.Load(); + pdc.Clear(); + + if (File.Exists(PATH)) + File.Delete(PATH); + pdc.Save(); + FileAssert.Exists(PATH); + + string content = File.ReadAllText(PATH); + string expected = $"{{\"version\":{PersistentDataController.VERSION},\"users\":[],\"currentUser\":-1,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; + Assert.AreEqual(expected, content); + } + + [Test] + public void Test_PersistentDataController_Load_Existing() + { + string content = $"{{\"version\":{PersistentDataController.VERSION},\"users\":[],\"currentUser\":-1,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; + File.WriteAllText(PATH, content); + Assert.IsTrue(pdc.Load(false)); + } + + [Test] + public void Test_PersistentDataController_Load_OlderVersion() + { + string content = $"{{\"version\":{PersistentDataController.VERSION - 1},\"users\":[],\"currentUser\":-1,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; + File.WriteAllText(PATH, content); + Assert.IsFalse(pdc.Load(false)); + } + + [Test] + public void Test_PersistentDataController_Load_New() + { + if (File.Exists(PATH)) + File.Delete(PATH); + Assert.IsFalse(pdc.Load(false)); + FileAssert.DoesNotExist(PATH); + } + + [Test] + public void Test_PersistentDataController_Load_Exception() + { + File.WriteAllText(PATH, "https://www.youtube.com/watch?v=dQw4w9WgXcQ"); + Assert.IsFalse(pdc.Load(false)); + Assert.AreEqual("https://www.youtube.com/watch?v=dQw4w9WgXcQ", File.ReadAllText(PATH)); + } + + [Test] + public void Test_PersistentDataController_Load_Override() + { + File.WriteAllText(PATH, "https://www.youtube.com/watch?v=dQw4w9WgXcQ"); + Assert.IsFalse(pdc.Load(true)); + string content = File.ReadAllText(PATH); + string expected = $"{{\"version\":{PersistentDataController.VERSION},\"users\":[],\"currentUser\":-1,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; + Assert.AreEqual(expected, content); + } + + [Test] + public void Test_PersistentDataController_Version() + { + const int VERSION = 0x04_01; + Assert.AreEqual(VERSION, PersistentDataController.VERSION); + } + + [Test] + public void Test_PersistentDataController_AddUser() + { + pdc.Load(); + pdc.Clear(); + var d = new PersistentDataController.SavedUserData() + { + username = "username", + avatarIndex = 0 + }; + + pdc.AddUser(d); + string content = File.ReadAllText(PATH); + string expected = $"{{\"version\":{PersistentDataController.VERSION},\"users\":[{{\"entries\":[],\"username\":\"username\",\"avatarIndex\":0,\"playtime\":0.0,\"minigames\":[],\"courses\":[]}}],\"currentUser\":0,\"currentMinigame\":0,\"currentCourse\":0,\"currentTheme\":0}}"; + Assert.AreEqual(expected, content); + } + + [Test] + public void Test_PersistentDataController_GetUsers() + { + pdc.Load(); + pdc.Clear(); + var d = new PersistentDataController.SavedUserData() + { + username = "username", + avatarIndex = 0 + }; + + pdc.AddUser(d); + var users = pdc.GetUsers(); + Assert.AreEqual(1, users.Count); + Assert.AreEqual("username", users[0].username); + Assert.AreEqual(0, users[0].avatarIndex); + } + + [Test] + public void Test_PersistentDataController_GetCurrentUser() + { + pdc.Load(); + pdc.Clear(); + + Assert.AreEqual(-1, pdc.GetCurrentUser()); + pdc.AddUser(new PersistentDataController.SavedUserData() + { + username = "username", + avatarIndex = 0 + }); + Assert.AreEqual(0, pdc.GetCurrentUser()); + } + + [Test] + public void Test_PersistentDataController_SetCurrentUser() + { + pdc.Load(); + pdc.Clear(); + + for (int i = 0; i < 5; i++) + pdc.AddUser(new PersistentDataController.SavedUserData() + { + username = $"username_{i}", + avatarIndex = i + }); + pdc.SetCurrentUser(3); + Assert.AreEqual(3, pdc.GetCurrentUser()); + } + + [Test] + public void Test_PersistentDataController_SetCurrentUser_Invalid() + { + pdc.Load(); + pdc.Clear(); + + pdc.AddUser(new PersistentDataController.SavedUserData() + { + username = $"username", + avatarIndex = 0 + }); + Assert.Throws(delegate { pdc.SetCurrentUser(3); }); + } + + [Test] + public void Test_PersistentDataController_SetCurrentUser_Empty() + { + pdc.Load(); + pdc.Clear(); + Assert.Throws(delegate { pdc.SetCurrentUser(0); }); + } + + [Test] + public void Test_PersistentDataController_DeleteUser_BeforeCurrent() + { + pdc.Load(); + pdc.Clear(); + + var users = new List(); + for (int i = 0; i < 5; i++) + { + var d = new PersistentDataController.SavedUserData() + { + username = $"username_{i}", + avatarIndex = i + }; + pdc.AddUser(d); + users.Add(d); + } + pdc.SetCurrentUser(0); + users.RemoveAt(2); + pdc.DeleteUser(2); + + var vsers = pdc.GetUsers(); + Assert.AreEqual(0, pdc.GetCurrentUser()); + Assert.AreEqual(users.Count, vsers.Count); + for (int i = 0; i < 4; i++) + { + Assert.AreEqual(users[i].username, vsers[i].username); + Assert.AreEqual(users[i].avatarIndex, vsers[i].avatarIndex); + } + } + + [Test] + public void Test_PersistentDataController_DeleteUser_Current() + { + pdc.Load(); + pdc.Clear(); + + var users = new List(); + for (int i = 0; i < 5; i++) + { + var d = new PersistentDataController.SavedUserData() + { + username = $"username_{i}", + avatarIndex = i + }; + pdc.AddUser(d); + users.Add(d); + } + pdc.SetCurrentUser(2); + users.RemoveAt(2); + pdc.DeleteUser(2); + + var vsers = pdc.GetUsers(); + Assert.AreEqual(1, pdc.GetCurrentUser()); + Assert.AreEqual(users.Count, vsers.Count); + for (int i = 0; i < 4; i++) + { + Assert.AreEqual(users[i].username, vsers[i].username); + Assert.AreEqual(users[i].avatarIndex, vsers[i].avatarIndex); + } + } + + [Test] + public void Test_PersistentDataController_DeleteUser_AfterCurrent() + { + pdc.Load(); + pdc.Clear(); + + var users = new List(); + for (int i = 0; i < 5; i++) + { + var d = new PersistentDataController.SavedUserData() + { + username = $"username_{i}", + avatarIndex = i + }; + pdc.AddUser(d); + users.Add(d); + + } + pdc.SetCurrentUser(4); + users.RemoveAt(2); + pdc.DeleteUser(2); + + var vsers = pdc.GetUsers(); + Assert.AreEqual(3, pdc.GetCurrentUser()); + Assert.AreEqual(users.Count, vsers.Count); + for (int i = 0; i < 4; i++) + { + Assert.AreEqual(users[i].username, vsers[i].username); + Assert.AreEqual(users[i].avatarIndex, vsers[i].avatarIndex); + } + } + + [Test] + public void Test_PersistentDataController_DeleteUser_Invalid() + { + pdc.Load(); + pdc.Clear(); + + pdc.AddUser(new PersistentDataController.SavedUserData() + { + username = $"username", + avatarIndex = 0 + }); + Assert.Throws(delegate { pdc.SetCurrentUser(3); }); + } + + [Test] + public void Test_PersistentDataController_DeleteUser_Empty() + { + pdc.Load(); + pdc.Clear(); + Assert.Throws(delegate { pdc.DeleteUser(0); }); + } + + [Test] + public void Test_PersistentDataController_CurrentCourse() + { + pdc.Load(); + pdc.Clear(); + pdc.SetCurrentCourse(CourseIndex.FINGERSPELLING); + Assert.AreEqual(CourseIndex.FINGERSPELLING, pdc.GetCurrentCourse()); + } + + [Test] + public void Test_PersistentDataController_CurrentMinigame() + { + pdc.Load(); + pdc.Clear(); + pdc.SetCurrentMinigame(MinigameIndex.SPELLING_BEE); + Assert.AreEqual(MinigameIndex.SPELLING_BEE, pdc.GetCurrentMinigame()); + } + + [Test] + public void Test_PersistentDataController_CurrentTheme() + { + pdc.Load(); + pdc.Clear(); + pdc.SetCurrentTheme(ThemeIndex.SIGN_ALPHABET); + Assert.AreEqual(ThemeIndex.SIGN_ALPHABET, pdc.GetCurrentTheme()); + } + + [Test] + public void Test_New_PersistentDataContainer() + { + var c = new PersistentDataController.PersistentDataContainer(); + Assert.IsNotNull(c); + Assert.Zero(c.entries.Count); + } + + [Test] + public void Test_PersistentDataContainer_Set_Invalid() + { + var c = new PersistentDataController.PersistentDataContainer(); + Assert.IsFalse(c.Set("key", null)); + } + + [Test] + public void Test_PersistentDataContainer_Set_DuplicateKey() + { + var c = new PersistentDataController.PersistentDataContainer(); + Assert.IsTrue(c.Set("key", 123)); + Assert.IsTrue(c.Set("key", 321)); + } + + [Test] + public void Test_PersistentDataContainer_Set_Int() + { + var c = new PersistentDataController.PersistentDataContainer(); + Assert.IsTrue(c.Set("key", 123)); + } + + [Test] + public void Test_PersistentDataContainer_Set_String() + { + var c = new PersistentDataController.PersistentDataContainer(); + Assert.IsTrue(c.Set("key", "abc")); + } + + [Test] + public void Test_PersistentDataContainer_Set_Struct() + { + var c = new PersistentDataController.PersistentDataContainer(); + Assert.IsTrue(c.Set("key", new Struct())); + } + + [Test] + public void Test_PersistentDataContainer_Set_Enum() + { + var c = new PersistentDataController.PersistentDataContainer(); + Assert.IsTrue(c.Set("key", new Enum())); + } + + [Test] + public void Test_PersistentDataContainer_Get_InvalidType() + { + var c = new PersistentDataController.PersistentDataContainer(); + c.Set("key", new Struct() { r = 255, g = 127, b = 63, x = 31, y = 15, z = 7 }); + Assert.Throws(delegate { c.Get("key"); }); + c.Set("key", 123); + Assert.Throws(delegate { c.Get("key"); }); + } + + [Test] + public void Test_PersistentDataContainer_Get_KeyNotFound() + { + var c = new PersistentDataController.PersistentDataContainer(); + c.Set("key", 123); + Assert.Throws(delegate { c.Get("KEY"); }); + } + + [Test] + public void Test_PersistentDataContainer_Get_Empty() + { + var c = new PersistentDataController.PersistentDataContainer(); + Assert.Throws(delegate { c.Get("key"); }); + } + + [Test] + public void Test_PersistentDataContainer_Get_Int() + { + var c = new PersistentDataController.PersistentDataContainer(); + c.Set("key", 123); + Assert.AreEqual(123, c.Get("key")); + } + + [Test] + public void Test_PersistentDataContainer_Get_String() + { + var c = new PersistentDataController.PersistentDataContainer(); + c.Set("key", "value"); + Assert.AreEqual("value", c.Get("key")); + } + + [Test] + public void Test_PersistentDataContainer_Get_Struct() + { + var c = new PersistentDataController.PersistentDataContainer(); + var s = new Struct() { r = 255, g = 127, b = 63, x = 31, y = 15, z = 7 }; + c.Set("key", s); + Assert.AreEqual(s, c.Get("key")); + } + + [Test] + public void Test_PersistentDataContainer_Get_Enum() + { + var c = new PersistentDataController.PersistentDataContainer(); + var e = Enum.CIRCLE; + c.Set("key", e); + Assert.AreEqual(e, c.Get("key")); + } + + [Test] + public void Test_PersistentDataContainer_Remove_Invalid() + { + var c = new PersistentDataController.PersistentDataContainer(); + c.Set("key", 123); + Assert.Throws(delegate { c.Remove("KEY"); }); + } + + [Test] + public void Test_PersistentDataContainer_Remove_Empty() + { + var c = new PersistentDataController.PersistentDataContainer(); + Assert.Throws(delegate { c.Remove("key"); }); + } + + [Test] + public void Test_PersistentDataContainer_Remove_Int() + { + var c = new PersistentDataController.PersistentDataContainer(); + c.Set("key", 123); + c.Remove("key"); + Assert.Throws(delegate { c.Get("key"); }); + } + + [Test] + public void Test_PersistentDataContainer_Remove_String() + { + var c = new PersistentDataController.PersistentDataContainer(); + c.Set("key", "value"); + c.Remove("key"); + Assert.Throws(delegate { c.Get("key"); }); + } + + [Test] + public void Test_PersistentDataContainer_Remove_Struct() + { + var c = new PersistentDataController.PersistentDataContainer(); + var s = new Struct() { r = 255, g = 127, b = 63, x = 31, y = 15, z = 7 }; + c.Set("key", s); + c.Remove("key"); + Assert.Throws(delegate { c.Get("key"); }); + } + + [Test] + public void Test_PersistentDataContainer_Remove_Enum() + { + var c = new PersistentDataController.PersistentDataContainer(); + c.Set("key", Enum.CIRCLE); + c.Remove("key"); + Assert.Throws(delegate { c.Get("key"); }); + } + + [Test] + public void Test_PersistentDataContainer_Pop_Invalid() + { + var c = new PersistentDataController.PersistentDataContainer(); + c.Set("key", 123); + Assert.Throws(delegate { c.Remove("KEY"); }); + } + + [Test] + public void Test_PersistentDataContainer_Pop_Empty() + { + var c = new PersistentDataController.PersistentDataContainer(); + Assert.Throws(delegate { c.Remove("KEY"); }); + } + + [Test] + public void Test_PersistentDataContainer_Pop_Int() + { + var c = new PersistentDataController.PersistentDataContainer(); + c.Set("key", 123); + Assert.AreEqual(123, c.Pop("key")); + Assert.Throws(delegate { c.Get("key"); }); + } + + [Test] + public void Test_PersistentDataContainer_Pop_String() + { + var c = new PersistentDataController.PersistentDataContainer(); + c.Set("key", "value"); + Assert.AreEqual("value", c.Pop("key")); + Assert.Throws(delegate { c.Get("key"); }); + } + + [Test] + public void Test_PersistentDataContainer_Pop_Struct() + { + var c = new PersistentDataController.PersistentDataContainer(); + var s = new Struct() { r = 255, g = 127, b = 63, x = 31, y = 15, z = 7 }; + c.Set("key", s); + Assert.AreEqual(s, c.Pop("key")); + Assert.Throws(delegate { c.Get("key"); }); + } + + [Test] + public void Test_PersistentDataContainer_Pop_Enum() + { + var c = new PersistentDataController.PersistentDataContainer(); + c.Set("key", Enum.CIRCLE); + Assert.AreEqual(Enum.CIRCLE, c.Pop("key")); + Assert.Throws(delegate { c.Get("key"); }); + } + + [Test] + public void Test_PersistentDataContainer_Has_ValidKey() + { + var c = new PersistentDataController.PersistentDataContainer(); + Assert.IsFalse(c.Has("key")); + c.Set("key", 123); + Assert.IsTrue(c.Has("key")); + } + + [Test] + public void Test_PersistentDataContainer_Has_InvalidKey() + { + var c = new PersistentDataController.PersistentDataContainer(); + Assert.IsFalse(c.Has("KEY")); + c.Set("key", 123); + Assert.IsFalse(c.Has("KEY")); + } +} diff --git a/Assets/SystemArchitecture/Tests/PersistentDataControllerTest.cs.meta b/Assets/SystemArchitecture/Tests/PersistentDataControllerTest.cs.meta new file mode 100644 index 0000000..a406576 --- /dev/null +++ b/Assets/SystemArchitecture/Tests/PersistentDataControllerTest.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 56873c5649b881846a54e2a2aa5ce499 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/SystemArchitecture/Tests/SystemArchitectureTests.asmdef b/Assets/SystemArchitecture/Tests/SystemArchitectureTests.asmdef new file mode 100644 index 0000000..254bdab --- /dev/null +++ b/Assets/SystemArchitecture/Tests/SystemArchitectureTests.asmdef @@ -0,0 +1,24 @@ +{ + "name": "SystemArchitectureTests", + "rootNamespace": "", + "references": [ + "UnityEditor.TestRunner", + "UnityEngine.TestRunner", + "SystemArchitecture" + ], + "includePlatforms": [ + "Editor" + ], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": true, + "precompiledReferences": [ + "nunit.framework.dll" + ], + "autoReferenced": false, + "defineConstraints": [ + "UNITY_INCLUDE_TESTS" + ], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/SystemArchitecture/Tests/SystemArchitectureTests.asmdef.meta b/Assets/SystemArchitecture/Tests/SystemArchitectureTests.asmdef.meta new file mode 100644 index 0000000..e228634 --- /dev/null +++ b/Assets/SystemArchitecture/Tests/SystemArchitectureTests.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: b1a4ef95cbacdca459433eb2ddc05755 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: