Resolve WES-117 "Persistent data handling"
This commit is contained in:
8
Assets/SystemArchitecture/Scripts.meta
Normal file
8
Assets/SystemArchitecture/Scripts.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 17374f544297b194aa5517c196ca2f07
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
14
Assets/SystemArchitecture/Scripts/CourseIndex.cs
Normal file
14
Assets/SystemArchitecture/Scripts/CourseIndex.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
|
||||
/// <summary>
|
||||
/// Enum for easy indexing and checking if a course is of a certain kind
|
||||
/// </summary>
|
||||
public enum CourseIndex
|
||||
{
|
||||
FINGERSPELLING,
|
||||
CLOTHING,
|
||||
ANIMALS,
|
||||
FOOD,
|
||||
HOBBIES,
|
||||
HOUSE,
|
||||
FAMILY
|
||||
}
|
||||
11
Assets/SystemArchitecture/Scripts/CourseIndex.cs.meta
Normal file
11
Assets/SystemArchitecture/Scripts/CourseIndex.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a5bf21dee022ed0489face1c734359de
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
10
Assets/SystemArchitecture/Scripts/MinigameIndex.cs
Normal file
10
Assets/SystemArchitecture/Scripts/MinigameIndex.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
/// <summary>
|
||||
/// Enum for easy indexing and checking if a minigame is of a certain kind
|
||||
/// </summary>
|
||||
public enum MinigameIndex
|
||||
{
|
||||
SPELLING_BEE,
|
||||
HANGMAN,
|
||||
JUST_SIGN
|
||||
}
|
||||
11
Assets/SystemArchitecture/Scripts/MinigameIndex.cs.meta
Normal file
11
Assets/SystemArchitecture/Scripts/MinigameIndex.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 97282ff3b465e3c4682d218b3819b2e8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
427
Assets/SystemArchitecture/Scripts/PersistentDataController.cs
Normal file
427
Assets/SystemArchitecture/Scripts/PersistentDataController.cs
Normal file
@@ -0,0 +1,427 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// PersistentDataController singleton
|
||||
/// </summary>
|
||||
public class PersistentDataController
|
||||
{
|
||||
/// <summary>
|
||||
/// The instance controlling the singleton
|
||||
/// </summary>
|
||||
private static PersistentDataController instance = null;
|
||||
|
||||
/// <summary>
|
||||
/// Current implementation version of the PersistentDataController
|
||||
/// </summary>
|
||||
/// <remarks>MSB represent sprint version, LSB represent subversion</remarks>
|
||||
public static readonly int VERSION = 0x04_01;
|
||||
|
||||
/// <summary>
|
||||
/// Path of the <c>.json</c>-file to store all serialized data
|
||||
/// </summary>
|
||||
public static string PATH = null;
|
||||
|
||||
/// <summary>
|
||||
/// Class to hold a list of data records
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class PersistentDataContainer
|
||||
{
|
||||
/// <summary>
|
||||
/// A helper class for handling the stored progress
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class PersistentDataEntry
|
||||
{
|
||||
/// <summary>
|
||||
/// The key, used to reference the data object
|
||||
/// </summary>
|
||||
public string key;
|
||||
|
||||
/// <summary>
|
||||
/// The object, representated as a list of byte (which can be serialized)
|
||||
/// </summary>
|
||||
public List<byte> data = new List<byte>();
|
||||
|
||||
public PersistentDataEntry(string key, byte[] data) : this(key, data.ToList())
|
||||
{ }
|
||||
|
||||
public PersistentDataEntry(string key, List<byte> data)
|
||||
{
|
||||
this.key = key;
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List of data records
|
||||
/// </summary>
|
||||
public List<PersistentDataEntry> entries = new List<PersistentDataEntry>();
|
||||
|
||||
/// <summary>
|
||||
/// Update the value of a certain key,
|
||||
/// or add a new value if the key was not present.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the data to be added/updated</typeparam>
|
||||
/// <param name="key">The key, used for referencing the data</param>
|
||||
/// <param name="data">The object of type <typeparamref name="T"/></param>
|
||||
/// <returns><c>true</c> if successful, <c>false</c> otherwise</returns>
|
||||
public bool Set<T>(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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the data object of a certain key
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the data object</typeparam>
|
||||
/// <param name="key">The key referencing the data object</param>
|
||||
/// <returns>The data, cast to a type <typeparamref name="T"/></returns>
|
||||
/// <exception cref="KeyNotFoundException"></exception>
|
||||
/// <exception cref="InvalidCastException"></exception>
|
||||
public T Get<T>(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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove a key-value from the data.
|
||||
/// </summary>
|
||||
/// <param name="key">The key referencing the data object</param>
|
||||
/// <exception cref="KeyNotFoundException"></exception>
|
||||
public void Remove(string key)
|
||||
{
|
||||
if (!Has(key))
|
||||
throw new KeyNotFoundException();
|
||||
|
||||
entries.Remove(entries.Find(x => x.key == key));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove and return value from the data.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the data object</typeparam>
|
||||
/// <param name="key">The key referencing the data object</param>
|
||||
/// <param name="save">Whether the removal of the data should also be saved to disk</param>
|
||||
/// <returns></returns>
|
||||
public T Pop<T>(string key)
|
||||
{
|
||||
T data = Get<T>(key);
|
||||
Remove(key);
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check whether a key is present
|
||||
/// </summary>
|
||||
/// <param name="key">The key to check</param>
|
||||
/// <returns>true if a item can be found with the specified key</returns>
|
||||
public bool Has(string key)
|
||||
{
|
||||
return entries.Find(x => x.key == key) != null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stored user data record
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class SavedUserData : PersistentDataContainer
|
||||
{
|
||||
public string username = null;
|
||||
public int avatarIndex = -1;
|
||||
public double playtime = 0.0;
|
||||
public List<SavedMinigameProgress> minigames = new List<SavedMinigameProgress>();
|
||||
public List<SavedCourseProgress> courses = new List<SavedCourseProgress>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stored course progress data record
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class SavedCourseProgress : PersistentDataContainer
|
||||
{
|
||||
public CourseIndex courseIndex;
|
||||
public float progress = -1.0f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stored minigame progress data record
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class SavedMinigameProgress : PersistentDataContainer
|
||||
{
|
||||
public MinigameIndex minigameIndex;
|
||||
public List<Score> latestScores = new List<Score>();
|
||||
public List<Score> highestScores = new List<Score>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stored WeSign data record
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
private class SavedDataStructure
|
||||
{
|
||||
public int version = VERSION;
|
||||
public List<SavedUserData> users = new List<SavedUserData>();
|
||||
public int currentUser = -1;
|
||||
public MinigameIndex currentMinigame;
|
||||
public CourseIndex currentCourse;
|
||||
public ThemeIndex currentTheme;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The object holding the data references
|
||||
/// </summary>
|
||||
private SavedDataStructure json = new SavedDataStructure();
|
||||
|
||||
/// <summary>
|
||||
/// Get the instance loaded by the singleton
|
||||
/// </summary>
|
||||
/// <returns><c>PersistentDataController</c> instance</returns>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// PersistentDataController contructor
|
||||
/// </summary>
|
||||
private PersistentDataController()
|
||||
{
|
||||
Load();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear everything stored in the PersistentDataController, won't save to disk
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
json.users.Clear();
|
||||
json.currentUser = -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Save all data to disk
|
||||
/// </summary>
|
||||
public void Save()
|
||||
{
|
||||
string text = JsonUtility.ToJson(json);
|
||||
File.CreateText(PATH).Close();
|
||||
File.WriteAllText(PATH, text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Override current data with the data from disk, will just clear if no data was found.
|
||||
/// </summary>
|
||||
/// <param name="overrideOnFail"><c>true</c> if you want to override the existing file if it exists and the loading failed.</param>
|
||||
/// <remarks>If the data on disk is outdated (version number is lower than the current version), the loading will also fail</remarks>
|
||||
/// <returns><c>true</c> if successful, <c>false</c> otherwise</returns>
|
||||
public bool Load(bool overrideOnFail = true)
|
||||
{
|
||||
Clear();
|
||||
if (!File.Exists(PATH))
|
||||
goto failed;
|
||||
|
||||
try
|
||||
{
|
||||
string text = File.ReadAllText(PATH);
|
||||
SavedDataStructure newJson = JsonUtility.FromJson<SavedDataStructure>(text);
|
||||
if (newJson == null || newJson.version < VERSION)
|
||||
goto failed;
|
||||
|
||||
json = newJson;
|
||||
return true;
|
||||
}
|
||||
catch (Exception) { goto failed; }
|
||||
|
||||
failed:
|
||||
if (overrideOnFail)
|
||||
Save();
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a user to the WeSign data record
|
||||
/// </summary>
|
||||
/// <param name="user">User data record</param>
|
||||
/// <param name="save">Whether to save the addition immediately to disk</param>
|
||||
public void AddUser(SavedUserData user, bool save = true)
|
||||
{
|
||||
if (json.users.Count == 0)
|
||||
json.currentUser = 0;
|
||||
json.users.Add(user);
|
||||
|
||||
if (save)
|
||||
Save();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a list of all user data records
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<SavedUserData> GetUsers()
|
||||
{
|
||||
return json.users;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the index of the current user
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public int GetCurrentUser()
|
||||
{
|
||||
return json.currentUser;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the index of the current record
|
||||
/// </summary>
|
||||
/// <param name="index">New index</param>
|
||||
/// <param name="save">Whether to save the change immediately to disk</param>
|
||||
/// <exception cref="IndexOutOfRangeException"></exception>
|
||||
public void SetCurrentUser(int index, bool save = true)
|
||||
{
|
||||
if (index < 0 || json.users.Count <= index)
|
||||
throw new IndexOutOfRangeException();
|
||||
json.currentUser = index;
|
||||
|
||||
if (save)
|
||||
Save();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove a user data record
|
||||
/// </summary>
|
||||
/// <param name="index">Index of the user</param>
|
||||
/// <param name="save">Whether to save the deletion immediately to disk</param>
|
||||
/// <exception cref="IndexOutOfRangeException"></exception>
|
||||
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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the current course
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public CourseIndex GetCurrentCourse()
|
||||
{
|
||||
return json.currentCourse;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the current course
|
||||
/// </summary>
|
||||
/// <param name="course">New course index</param>
|
||||
/// <param name="save">Whether to save the change immediately to disk</param>
|
||||
public void SetCurrentCourse(CourseIndex course, bool save = true)
|
||||
{
|
||||
json.currentCourse = course;
|
||||
|
||||
if (save)
|
||||
Save();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the current minigame
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public MinigameIndex GetCurrentMinigame()
|
||||
{
|
||||
return json.currentMinigame;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the current minigame
|
||||
/// </summary>
|
||||
/// <param name="minigame">New minigame index</param>
|
||||
/// <param name="save">Whether to save the change immediately to disk</param>
|
||||
public void SetCurrentMinigame(MinigameIndex minigame, bool save = true)
|
||||
{
|
||||
json.currentMinigame = minigame;
|
||||
|
||||
if (save)
|
||||
Save();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the current theme
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ThemeIndex GetCurrentTheme()
|
||||
{
|
||||
return json.currentTheme;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the current theme
|
||||
/// </summary>
|
||||
/// <param name="theme">New theme index</param>
|
||||
/// <param name="save">Whether to save the change immediately to disk</param>
|
||||
public void SetCurrentTheme(ThemeIndex theme, bool save = true)
|
||||
{
|
||||
json.currentTheme = theme;
|
||||
|
||||
if (save)
|
||||
Save();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 164b1accbeff688429a4311f1e40bd59
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
12
Assets/SystemArchitecture/Scripts/Score.cs
Normal file
12
Assets/SystemArchitecture/Scripts/Score.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
|
||||
/// <summary>
|
||||
/// Score class
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class Score
|
||||
{
|
||||
public int scoreValue;
|
||||
public string time;
|
||||
}
|
||||
|
||||
11
Assets/SystemArchitecture/Scripts/Score.cs.meta
Normal file
11
Assets/SystemArchitecture/Scripts/Score.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 16056ca3e1523f78cbd727cea2bfe047
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "SystemArchitecture",
|
||||
"rootNamespace": "",
|
||||
"references": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e83ddf9a537a96b4a804a16bb7872ec1
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
104
Assets/SystemArchitecture/Scripts/SystemController.cs
Normal file
104
Assets/SystemArchitecture/Scripts/SystemController.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
/// <summary>
|
||||
/// SystemController singleton
|
||||
/// </summary>
|
||||
public class SystemController
|
||||
{
|
||||
/// <summary>
|
||||
/// The instance controlling the singleton
|
||||
/// </summary>
|
||||
private static SystemController instance = null;
|
||||
|
||||
/// <summary>
|
||||
/// Stack of the loaded scenes, used to easily go back to previous scenes
|
||||
/// </summary>
|
||||
private Stack<int> sceneStack = new Stack<int>();
|
||||
|
||||
/// <summary>
|
||||
/// Get the instance loaded by the singleton
|
||||
/// </summary>
|
||||
/// <returns>SystemController instance</returns>
|
||||
public static SystemController GetInstance()
|
||||
{
|
||||
// Create a new instance if non exists
|
||||
if (instance == null)
|
||||
{
|
||||
instance = new SystemController();
|
||||
instance.sceneStack.Push(SceneManager.GetActiveScene().buildIndex);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load the scene and push on the stack
|
||||
/// </summary>
|
||||
/// <param name="scenePath">Path of the scene</param>
|
||||
public void LoadNextScene(string scenePath)
|
||||
{
|
||||
LoadNextScene(SceneUtility.GetBuildIndexByScenePath(scenePath));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load the scene and push on the stack
|
||||
/// </summary>
|
||||
/// <param name="sceneIndex">Buildindex of the scene</param>
|
||||
public void LoadNextScene(int sceneIndex)
|
||||
{
|
||||
sceneStack.Push(sceneIndex);
|
||||
SceneManager.LoadScene(sceneIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Swap the current scene with the new scene on the stack
|
||||
/// </summary>
|
||||
/// <param name="scenePath">Path of the scene</param>
|
||||
public void SwapScene(string scenePath)
|
||||
{
|
||||
SwapScene(SceneUtility.GetBuildIndexByScenePath(scenePath));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Swap the current scene with the new scene on the stack
|
||||
/// </summary>
|
||||
/// <param name="sceneIndex">Buildindex of the scene</param>
|
||||
public void SwapScene(int sceneIndex)
|
||||
{
|
||||
sceneStack.Pop();
|
||||
LoadNextScene(sceneIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Go back to the previous scene and unload the current scene
|
||||
/// </summary>
|
||||
public void BackToPreviousScene()
|
||||
{
|
||||
sceneStack.Pop();
|
||||
|
||||
if (sceneStack.Count > 0) SceneManager.LoadScene(sceneStack.Peek());
|
||||
else Application.Quit();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Go back to a specific scene, unloading all the scenes on the way
|
||||
/// </summary>
|
||||
/// <param name="scenePath">Path of the scene</param>
|
||||
public void BackToScene(string scenePath)
|
||||
{
|
||||
BackToScene(SceneUtility.GetBuildIndexByScenePath(scenePath));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Go back to a specific scene, unloading all the scene on the way
|
||||
/// </summary>
|
||||
/// <param name="sceneIndex">Buildindex of the scene</param>
|
||||
public void BackToScene(int sceneIndex)
|
||||
{
|
||||
while (0 < sceneStack.Count && sceneStack.Peek() != sceneIndex) sceneStack.Pop();
|
||||
|
||||
if (sceneStack.Count > 0) SceneManager.LoadScene(sceneStack.Peek());
|
||||
else Application.Quit();
|
||||
}
|
||||
}
|
||||
11
Assets/SystemArchitecture/Scripts/SystemController.cs.meta
Normal file
11
Assets/SystemArchitecture/Scripts/SystemController.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bf5ea73aa43049e45a0ad926db15f315
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
24
Assets/SystemArchitecture/Scripts/ThemeIndex.cs
Normal file
24
Assets/SystemArchitecture/Scripts/ThemeIndex.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
/// <summary>
|
||||
/// Enum for easy indexing and checking if a course is of a certain kind
|
||||
/// </summary>
|
||||
public enum ThemeIndex
|
||||
{
|
||||
SIGN_ALPHABET,
|
||||
SIGN_CLOTHING,
|
||||
SIGN_ANIMALS,
|
||||
SIGN_FOOD,
|
||||
SIGN_HOBBIES,
|
||||
SIGN_HOUSE,
|
||||
SIGN_FAMILY,
|
||||
SPELLING_GEOGRAPY,
|
||||
SPELLING_BUILDINGS,
|
||||
SPELLING_SPORTS,
|
||||
SPELLING_BASICS,
|
||||
SPELLING_HOBBIES,
|
||||
SPELLING_PEOPLE,
|
||||
SPELLING_FRUIT,
|
||||
SPELLING_VEGGIES,
|
||||
SPELLING_WILD,
|
||||
SPELLING_FARM
|
||||
}
|
||||
11
Assets/SystemArchitecture/Scripts/ThemeIndex.cs.meta
Normal file
11
Assets/SystemArchitecture/Scripts/ThemeIndex.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 58e9afcf842bdfa48939e754bb39182a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
8
Assets/SystemArchitecture/Tests.meta
Normal file
8
Assets/SystemArchitecture/Tests.meta
Normal file
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8559f509b8f924f44bc10e2d20ac3eed
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
606
Assets/SystemArchitecture/Tests/PersistentDataControllerTest.cs
Normal file
606
Assets/SystemArchitecture/Tests/PersistentDataControllerTest.cs
Normal file
@@ -0,0 +1,606 @@
|
||||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
[TestFixture]
|
||||
public class PersistentDataTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Create a new path so the existing .json file will not be overwritten
|
||||
/// </summary>
|
||||
private static string PATH = $"{Application.persistentDataPath}/wesign_unit_test.json";
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the pdc to perform tests on
|
||||
/// </summary>
|
||||
private PersistentDataController pdc = null;
|
||||
|
||||
/// <summary>
|
||||
/// A dummy serializable struct to perform test operations on
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
private struct Struct
|
||||
{
|
||||
public int r, g, b;
|
||||
public float x, y, z;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A dummy serializable enum to perform test operations on
|
||||
/// </summary>
|
||||
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<IndexOutOfRangeException>(delegate { pdc.SetCurrentUser(3); });
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataController_SetCurrentUser_Empty()
|
||||
{
|
||||
pdc.Load();
|
||||
pdc.Clear();
|
||||
Assert.Throws<IndexOutOfRangeException>(delegate { pdc.SetCurrentUser(0); });
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataController_DeleteUser_BeforeCurrent()
|
||||
{
|
||||
pdc.Load();
|
||||
pdc.Clear();
|
||||
|
||||
var users = new List<PersistentDataController.SavedUserData>();
|
||||
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<PersistentDataController.SavedUserData>();
|
||||
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<PersistentDataController.SavedUserData>();
|
||||
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<IndexOutOfRangeException>(delegate { pdc.SetCurrentUser(3); });
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataController_DeleteUser_Empty()
|
||||
{
|
||||
pdc.Load();
|
||||
pdc.Clear();
|
||||
Assert.Throws<IndexOutOfRangeException>(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<object>("key", null));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataContainer_Set_DuplicateKey()
|
||||
{
|
||||
var c = new PersistentDataController.PersistentDataContainer();
|
||||
Assert.IsTrue(c.Set<int>("key", 123));
|
||||
Assert.IsTrue(c.Set<int>("key", 321));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataContainer_Set_Int()
|
||||
{
|
||||
var c = new PersistentDataController.PersistentDataContainer();
|
||||
Assert.IsTrue(c.Set<int>("key", 123));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataContainer_Set_String()
|
||||
{
|
||||
var c = new PersistentDataController.PersistentDataContainer();
|
||||
Assert.IsTrue(c.Set<string>("key", "abc"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataContainer_Set_Struct()
|
||||
{
|
||||
var c = new PersistentDataController.PersistentDataContainer();
|
||||
Assert.IsTrue(c.Set<Struct>("key", new Struct()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataContainer_Set_Enum()
|
||||
{
|
||||
var c = new PersistentDataController.PersistentDataContainer();
|
||||
Assert.IsTrue(c.Set<Enum>("key", new Enum()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataContainer_Get_InvalidType()
|
||||
{
|
||||
var c = new PersistentDataController.PersistentDataContainer();
|
||||
c.Set<Struct>("key", new Struct() { r = 255, g = 127, b = 63, x = 31, y = 15, z = 7 });
|
||||
Assert.Throws<InvalidCastException>(delegate { c.Get<int>("key"); });
|
||||
c.Set<int>("key", 123);
|
||||
Assert.Throws<InvalidCastException>(delegate { c.Get<Struct>("key"); });
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataContainer_Get_KeyNotFound()
|
||||
{
|
||||
var c = new PersistentDataController.PersistentDataContainer();
|
||||
c.Set<int>("key", 123);
|
||||
Assert.Throws<KeyNotFoundException>(delegate { c.Get<int>("KEY"); });
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataContainer_Get_Empty()
|
||||
{
|
||||
var c = new PersistentDataController.PersistentDataContainer();
|
||||
Assert.Throws<KeyNotFoundException>(delegate { c.Get<int>("key"); });
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataContainer_Get_Int()
|
||||
{
|
||||
var c = new PersistentDataController.PersistentDataContainer();
|
||||
c.Set<int>("key", 123);
|
||||
Assert.AreEqual(123, c.Get<int>("key"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataContainer_Get_String()
|
||||
{
|
||||
var c = new PersistentDataController.PersistentDataContainer();
|
||||
c.Set<string>("key", "value");
|
||||
Assert.AreEqual("value", c.Get<string>("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<Struct>("key", s);
|
||||
Assert.AreEqual(s, c.Get<Struct>("key"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataContainer_Get_Enum()
|
||||
{
|
||||
var c = new PersistentDataController.PersistentDataContainer();
|
||||
var e = Enum.CIRCLE;
|
||||
c.Set<Enum>("key", e);
|
||||
Assert.AreEqual(e, c.Get<Enum>("key"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataContainer_Remove_Invalid()
|
||||
{
|
||||
var c = new PersistentDataController.PersistentDataContainer();
|
||||
c.Set<int>("key", 123);
|
||||
Assert.Throws<KeyNotFoundException>(delegate { c.Remove("KEY"); });
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataContainer_Remove_Empty()
|
||||
{
|
||||
var c = new PersistentDataController.PersistentDataContainer();
|
||||
Assert.Throws<KeyNotFoundException>(delegate { c.Remove("key"); });
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataContainer_Remove_Int()
|
||||
{
|
||||
var c = new PersistentDataController.PersistentDataContainer();
|
||||
c.Set<int>("key", 123);
|
||||
c.Remove("key");
|
||||
Assert.Throws<KeyNotFoundException>(delegate { c.Get<int>("key"); });
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataContainer_Remove_String()
|
||||
{
|
||||
var c = new PersistentDataController.PersistentDataContainer();
|
||||
c.Set<string>("key", "value");
|
||||
c.Remove("key");
|
||||
Assert.Throws<KeyNotFoundException>(delegate { c.Get<string>("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<Struct>("key", s);
|
||||
c.Remove("key");
|
||||
Assert.Throws<KeyNotFoundException>(delegate { c.Get<Struct>("key"); });
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataContainer_Remove_Enum()
|
||||
{
|
||||
var c = new PersistentDataController.PersistentDataContainer();
|
||||
c.Set<Enum>("key", Enum.CIRCLE);
|
||||
c.Remove("key");
|
||||
Assert.Throws<KeyNotFoundException>(delegate { c.Get<Enum>("key"); });
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataContainer_Pop_Invalid()
|
||||
{
|
||||
var c = new PersistentDataController.PersistentDataContainer();
|
||||
c.Set<int>("key", 123);
|
||||
Assert.Throws<KeyNotFoundException>(delegate { c.Remove("KEY"); });
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataContainer_Pop_Empty()
|
||||
{
|
||||
var c = new PersistentDataController.PersistentDataContainer();
|
||||
Assert.Throws<KeyNotFoundException>(delegate { c.Remove("KEY"); });
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataContainer_Pop_Int()
|
||||
{
|
||||
var c = new PersistentDataController.PersistentDataContainer();
|
||||
c.Set<int>("key", 123);
|
||||
Assert.AreEqual(123, c.Pop<int>("key"));
|
||||
Assert.Throws<KeyNotFoundException>(delegate { c.Get<int>("key"); });
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataContainer_Pop_String()
|
||||
{
|
||||
var c = new PersistentDataController.PersistentDataContainer();
|
||||
c.Set<string>("key", "value");
|
||||
Assert.AreEqual("value", c.Pop<string>("key"));
|
||||
Assert.Throws<KeyNotFoundException>(delegate { c.Get<string>("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<Struct>("key", s);
|
||||
Assert.AreEqual(s, c.Pop<Struct>("key"));
|
||||
Assert.Throws<KeyNotFoundException>(delegate { c.Get<Struct>("key"); });
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataContainer_Pop_Enum()
|
||||
{
|
||||
var c = new PersistentDataController.PersistentDataContainer();
|
||||
c.Set<Enum>("key", Enum.CIRCLE);
|
||||
Assert.AreEqual(Enum.CIRCLE, c.Pop<Enum>("key"));
|
||||
Assert.Throws<KeyNotFoundException>(delegate { c.Get<Enum>("key"); });
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Test_PersistentDataContainer_Has_ValidKey()
|
||||
{
|
||||
var c = new PersistentDataController.PersistentDataContainer();
|
||||
Assert.IsFalse(c.Has("key"));
|
||||
c.Set<int>("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<int>("key", 123);
|
||||
Assert.IsFalse(c.Has("KEY"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 56873c5649b881846a54e2a2aa5ce499
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -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
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1a4ef95cbacdca459433eb2ddc05755
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user