Add formatting rules

This commit is contained in:
Dries Van Schuylenbergh
2023-03-10 09:21:11 +00:00
parent 6d762a63f7
commit 26f3322e4e
30 changed files with 975 additions and 160 deletions

View File

@@ -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();

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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