Add formatting rules
This commit is contained in:
@@ -4,15 +4,26 @@ using System.IO;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// A class for holding all progress belonging to a user
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
// Can not be created from Editor
|
||||
public class Progress
|
||||
{
|
||||
/// <summary>
|
||||
/// A helper class for handling the stored progress
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
// Helper class to serialize into byte[]
|
||||
protected class DataEntry
|
||||
{
|
||||
/// <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> bytes = new List<byte>();
|
||||
|
||||
public DataEntry(string key, byte[] data)
|
||||
@@ -22,13 +33,21 @@ public class Progress
|
||||
}
|
||||
}
|
||||
|
||||
[Header("Course or Minigame")]
|
||||
/// <summary>
|
||||
/// Entries in the <c>Progress</c> object
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
// values belonging to a certain key, in List (which can be serialized)
|
||||
private List<DataEntry> entries = new List<DataEntry>();
|
||||
|
||||
|
||||
// Add new `key` := `value`, returns `true` if successful
|
||||
/// <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 AddOrUpdate<T>(string key, T data)
|
||||
{
|
||||
if (data == null)
|
||||
@@ -55,6 +74,13 @@ public class Progress
|
||||
}
|
||||
|
||||
// Get the value of type `T` belonging to `key`
|
||||
/// <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>
|
||||
public T Get<T>(string key)
|
||||
{
|
||||
BinaryFormatter bf = new BinaryFormatter();
|
||||
|
||||
@@ -2,29 +2,45 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// A class holding all information of a user
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class User
|
||||
{
|
||||
[Header("Personal data")]
|
||||
// User nickname
|
||||
/// <summary>
|
||||
/// User nickname
|
||||
/// </summary>
|
||||
public string username;
|
||||
// User avatar
|
||||
|
||||
/// <summary>
|
||||
/// The avatar of the user
|
||||
/// </summary>
|
||||
public Sprite avatar;
|
||||
|
||||
[Header("Personal settings")]
|
||||
// TODO: set personal settings and preferences
|
||||
|
||||
[Header("Progress")]
|
||||
// Total playtime
|
||||
/// <summary>
|
||||
/// The total playtime of the user
|
||||
/// </summary>
|
||||
/// <remarks>TODO: needs to be implemented</remarks>
|
||||
public double playtime;
|
||||
|
||||
/// <summary>
|
||||
/// List of courses a user started/completed
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
// List of courses a user started/completed
|
||||
public List<Progress> courses = new List<Progress>();
|
||||
|
||||
/// <summary>
|
||||
/// List of minigames a user played
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
// List of minigames a user played
|
||||
public List<Progress> minigames = new List<Progress>();
|
||||
|
||||
// Get a list of all recently started courses, returns a list of tuples of `<CourseIndex idx, float courseProgress>`
|
||||
/// <summary>
|
||||
/// Get a list of all recently started courses
|
||||
/// </summary>
|
||||
/// <returns>A <c>List</c> of <c>Tuples</c>, containing the <c>CourseIndex</c>
|
||||
/// and a <c>float</c> holding the progress (value between 0 and 1) of the user in this course</returns>
|
||||
public List<Tuple<CourseIndex, float>> GetRecentCourses()
|
||||
{
|
||||
// TODO: return better results (for now only return all courses)
|
||||
@@ -38,7 +54,11 @@ public class User
|
||||
return recentCourses;
|
||||
}
|
||||
|
||||
// Get a list of all recommended courses, returns a list of tuples of `<CourseIndex idx, float courseProgress>`
|
||||
/// <summary>
|
||||
/// Get a list of all recommended courses
|
||||
/// </summary>
|
||||
/// <returns>A <c>List</c> of <c>Tuples</c>, containing the <c>CourseIndex</c>
|
||||
/// and a <c>float</c> holding the progress (value between 0 and 1) of the user in this course</returns>
|
||||
public List<Tuple<CourseIndex, float>> GetRecommendedCourses()
|
||||
{
|
||||
List<Tuple<CourseIndex, float>> recommenedCourses = new List<Tuple<CourseIndex, float>>();
|
||||
@@ -59,4 +79,24 @@ public class User
|
||||
|
||||
return recommenedCourses;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the progress of a certain course
|
||||
/// </summary>
|
||||
/// <param name="courseIndex">Index of course</param>
|
||||
/// <returns><c>Progress</c> belonging to the <c>courseIndex</c>, <c>null</c> if course was not found</returns>
|
||||
public Progress GetCourseProgress(CourseIndex courseIndex)
|
||||
{
|
||||
return courses.Find((p) => p.Get<CourseIndex>("courseIndex") == courseIndex);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the progress of certain minigame
|
||||
/// </summary>
|
||||
/// <param name="minigameIndex">Index of the minigame</param>
|
||||
/// <returns><c>Progress</c> belonging to the <c>minigameIndex</c>, <c>null</c> if minigame was not found</returns>
|
||||
public Progress GetMinigameProgress(MinigameIndex minigameIndex)
|
||||
{
|
||||
return minigames.Find((p) => p.Get<MinigameIndex>("minigameIndex") == minigameIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,34 +5,56 @@ using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEngine.UI;
|
||||
|
||||
/// <summary>
|
||||
/// UserCreationScreen scene manager
|
||||
/// </summary>
|
||||
public class UserCreationScreen : MonoBehaviour
|
||||
{
|
||||
// Max length of a username
|
||||
/// <summary>
|
||||
/// Maximum lenght of a username
|
||||
/// </summary>
|
||||
private const int MAX_USERNAME_LENGTH = 12;
|
||||
|
||||
[Header("UI References")]
|
||||
// Reference to the input text field for username
|
||||
/// <summary>
|
||||
/// Reference to the input text field for username
|
||||
/// </summary>
|
||||
public TMP_InputField inputName;
|
||||
// Reference to the avatar-list container
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the avatar-list container
|
||||
/// </summary>
|
||||
public Transform avatarsContainer;
|
||||
|
||||
[Header("Prefab")]
|
||||
// Avatar prefab
|
||||
/// <summary>
|
||||
/// Avatar prefab
|
||||
/// </summary>
|
||||
public GameObject avatarPrefab;
|
||||
// List of all sprites that are supported as avatars
|
||||
|
||||
/// <summary>
|
||||
/// List of all sprites that are supported as avatars
|
||||
/// </summary>
|
||||
public List<Sprite> sprites = new List<Sprite>();
|
||||
|
||||
[Header("Users List")]
|
||||
// Reference to the UserList ScriptableObject
|
||||
/// <summary>
|
||||
/// Reference to the UserList ScriptableObject
|
||||
/// </summary>
|
||||
public UserList users;
|
||||
|
||||
/// <summary>
|
||||
/// Current selected avatar
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
// Current selected avatar
|
||||
private int selectedAvatar = 0;
|
||||
// List of references to avatar background sprites (so we can color them nicely)
|
||||
|
||||
/// <summary>
|
||||
/// List of references to avatar background sprites (so we can color them nicely)
|
||||
/// </summary>
|
||||
private List<Image> avatars = new List<Image>();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Start is called before the first frame update
|
||||
/// </summary>
|
||||
void Start()
|
||||
{
|
||||
for (int i = 0; i < sprites.Count; i++)
|
||||
@@ -60,7 +82,10 @@ public class UserCreationScreen : MonoBehaviour
|
||||
}
|
||||
}
|
||||
|
||||
// Update the current selected avatar
|
||||
/// <summary>
|
||||
/// Update the current selected avatar
|
||||
/// </summary>
|
||||
/// <param name="newAvatar">Index to the new avatar in the <c>this.avatars</c> list</param>
|
||||
private void UpdateAvatar(int newAvatar)
|
||||
{
|
||||
avatars[selectedAvatar].color = Color.gray;
|
||||
@@ -68,13 +93,20 @@ public class UserCreationScreen : MonoBehaviour
|
||||
avatars[selectedAvatar].color = Color.blue;
|
||||
}
|
||||
|
||||
// Check if a given string is a correct username (using Regex)
|
||||
/// <summary>
|
||||
/// Check if a given string is a correct username (using Regex)
|
||||
/// </summary>
|
||||
/// <param name="username">The username to be checked</param>
|
||||
/// <returns><c>true</c> if the username was valid, <c>false</c> otherwise</returns>
|
||||
static public bool IsValidUsername(string username)
|
||||
{
|
||||
return new Regex($@"^[abcdefghijklmnopqrstuvwxyz]{{1,{MAX_USERNAME_LENGTH}}}$").IsMatch(username);
|
||||
}
|
||||
|
||||
// Create a new user (will be called by button)
|
||||
/// <summary>
|
||||
/// Create a new user
|
||||
/// (this method will be called by a button callback)
|
||||
/// </summary>
|
||||
public void CreateUser()
|
||||
{
|
||||
string username = inputName.text;
|
||||
|
||||
@@ -3,31 +3,55 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Keep track of all users
|
||||
/// </summary>
|
||||
[CreateAssetMenu(menuName = "Create new Scriptable/UserList")]
|
||||
public class UserList : ScriptableObject
|
||||
{
|
||||
// Serializable UserList content
|
||||
/// <summary>
|
||||
/// Helper class to enable serialization of the UserList class
|
||||
/// (<c>ScriptableObkect</c>s cannot be serialized)
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class StoredUserList
|
||||
{
|
||||
/// <summary>
|
||||
/// The index of the current/last logged in user in the <c>storedUsers</c> list
|
||||
/// </summary>
|
||||
public int currentUserIndex;
|
||||
/// <summary>
|
||||
/// A list containing all users (which can be serialized)
|
||||
/// </summary>
|
||||
public List<User> storedUsers = new List<User>();
|
||||
}
|
||||
[Header("Users")]
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the serializable version of <c>UserList</c>
|
||||
/// </summary>
|
||||
[SerializeField]
|
||||
// Reference to serializable version of UserList
|
||||
private StoredUserList storedUserList = new StoredUserList();
|
||||
|
||||
// Path to .json file
|
||||
/// <summary>
|
||||
/// Path of the <c>.json</c>-file to store all serialized data
|
||||
/// </summary>
|
||||
public static string PATH = null;
|
||||
|
||||
/// <summary>
|
||||
/// OnEnable will make sure the <c>PATH</c>-variable is correctly initialized
|
||||
/// </summary>
|
||||
void OnEnable()
|
||||
{
|
||||
PATH = $"{Application.dataPath}/users.json";
|
||||
Load();
|
||||
}
|
||||
|
||||
// Create a new User
|
||||
/// <summary>
|
||||
/// Create a new user
|
||||
/// </summary>
|
||||
/// <param name="name">The username of the new user</param>
|
||||
/// <param name="avatar">Reference to the user avatar</param>
|
||||
/// <returns>A newly created user</returns>
|
||||
public User CreateNewUser(string name, Sprite avatar)
|
||||
{
|
||||
User user = new User();
|
||||
@@ -36,7 +60,12 @@ public class UserList : ScriptableObject
|
||||
return user;
|
||||
}
|
||||
|
||||
// Create a new User and add to list
|
||||
/// <summary>
|
||||
/// Create a new user and save (add to list)
|
||||
/// </summary>
|
||||
/// <param name="name">The username of the new user</param>
|
||||
/// <param name="avatar">Reference to the user avatar</param>
|
||||
/// <returns>A newly created user</returns>
|
||||
public User CreateAndAddNewUser(string name, Sprite avatar)
|
||||
{
|
||||
User user = CreateNewUser(name, avatar);
|
||||
@@ -45,7 +74,11 @@ public class UserList : ScriptableObject
|
||||
return user;
|
||||
}
|
||||
|
||||
// Get user by username, returns `null` if no user can be found with such name
|
||||
/// <summary>
|
||||
/// Get a user by username
|
||||
/// </summary>
|
||||
/// <param name="username">The username of the user</param>
|
||||
/// <returns><c>User</c>-object if a user with such username was found, <c>null</c> otherwise</returns>
|
||||
public User GetUserByUsername(string username)
|
||||
{
|
||||
foreach (User user in storedUserList.storedUsers)
|
||||
@@ -54,19 +87,27 @@ public class UserList : ScriptableObject
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get a list of all users
|
||||
/// <summary>
|
||||
/// Get a list of all users currently stored
|
||||
/// </summary>
|
||||
/// <returns>A list of all users</returns>
|
||||
public List<User> GetUsers()
|
||||
{
|
||||
return storedUserList.storedUsers;
|
||||
}
|
||||
|
||||
// Get the current active user
|
||||
/// <summary>
|
||||
/// Get the current logged in user
|
||||
/// </summary>
|
||||
/// <returns>The current logged in user</returns>
|
||||
public User GetCurrentUser()
|
||||
{
|
||||
return storedUserList.storedUsers[storedUserList.currentUserIndex];
|
||||
}
|
||||
|
||||
// Save the userList
|
||||
/// <summary>
|
||||
/// Save the users
|
||||
/// </summary>
|
||||
public void Save()
|
||||
{
|
||||
string json = JsonUtility.ToJson(storedUserList);
|
||||
@@ -74,7 +115,9 @@ public class UserList : ScriptableObject
|
||||
File.WriteAllText(PATH, json);
|
||||
}
|
||||
|
||||
// Load the userList into this object
|
||||
/// <summary>
|
||||
/// Override the current content of the userlist by what is stored on disk
|
||||
/// </summary>
|
||||
public void Load()
|
||||
{
|
||||
try
|
||||
|
||||
Reference in New Issue
Block a user