From 1673f3b96139f1d2d39e46a55148efa576858950 Mon Sep 17 00:00:00 2001 From: AndresFRJ98 Date: Wed, 24 Jan 2018 21:35:50 +0000 Subject: [PATCH] Refactoring --- .../FizzyoFramework/FizzyoAchievements.cs | 316 ++++++++++ .../FizzyoFramework/FizzyoAchievements.meta | 12 + .../FizzyoFramework/FizzyoAnalytics.cs | 4 + .../FizzyoFramework/FizzyoAnalytics.cs.meta | 24 +- .../FizzyoFramework/FizzyoBreathRecognizer.cs | 593 +++++++++--------- .../FizzyoBreathRecognizer.cs.meta | 24 +- .../FizzyoFramework/FizzyoCalibration.cs | 40 +- .../FizzyoFramework/FizzyoCalibration.cs.meta | 24 +- .../Scripts/FizzyoFramework/FizzyoDevice.cs | 28 +- .../FizzyoFramework/FizzyoDevice.cs.meta | 24 +- .../FizzyoFramework/FizzyoFramework.cs | 85 ++- .../FizzyoFramework/FizzyoFramework.cs.meta | 24 +- .../Scripts/FizzyoFramework/FizzyoUser.cs | 31 +- .../FizzyoFramework/FizzyoUser.cs.meta | 24 +- 14 files changed, 858 insertions(+), 395 deletions(-) create mode 100644 Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoAchievements.cs create mode 100644 Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoAchievements.meta diff --git a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoAchievements.cs b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoAchievements.cs new file mode 100644 index 0000000..b6ce2fa --- /dev/null +++ b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoAchievements.cs @@ -0,0 +1,316 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; + +namespace Fizzyo +{ + + // Serializable which holds high score data + [System.Serializable] + public class AllHighscoreData + { + public HighscoreData[] highscores; + + } + + // Serializable which holds individual high score data + [System.Serializable] + public class HighscoreData + { + public string tag; + public int score; + public bool belongsToUser; + } + + // Serializable which holds achievement data + + [System.Serializable] + public class AllAchievementData + { + public AchievementData[] achievements; + } + + // Serializable that is used to pull and hold the data of each Achievement in the Achievements.json file + [System.Serializable] + public class AchievementData + { + public string category; + public string id; + public string title; + public string description; + public int points; + public int unlock; + public int unlockProgress; + public int unlockRequirement; + public string dependency; + public string unlockedOn; + } + + // Serializable which holds calibration data + [System.Serializable] + public class CalibrationData + { + public string calibratedOn; + public float pressure; + public int time; + } + + + /// + /// Used to unlock Fizzyo achievements and post high scores in the Fizzyo rest API + /// + + public class FizzyoAchievements + { + /// + /// Array of type AchievementData which holds all the achievements that the game has to offer. + /// + public AchievementData[] allAchievements; + /// + /// Array of type AchievementData which holds the achievements the user has unlocked. + /// + public AchievementData[] unlockedAchievements; + + + + /// + /// Loads all game achievements and the users unlocked achievements and achievement progres. + /// + /// + /// A JSON formatted string containing the list of achievements + /// + public FizzyoRequestReturnType LoadAchievements() + { + //Get all achievements from server + string getAchievements = "https://api.fizzyo-ucl.co.uk/api/v1/games/" + FizzyoFramework.Instance.gameID + "/achievements"; + + Dictionary headers = new Dictionary(); + headers.Add("Authorization", "Bearer " + FizzyoFramework.Instance.User.AccessToken); + WWW sendGetAchievements = new WWW(getAchievements, null, headers); + + while (!sendGetAchievements.isDone) { } + + string achievementsJSONData = sendGetAchievements.text; + allAchievements = JsonUtility.FromJson(achievementsJSONData).achievements; + + //get unlocked achievements + string getUnlock = "https://api.fizzyo-ucl.co.uk/api/v1/users/" + FizzyoFramework.Instance.User.UserID + "/unlocked-achievements/" + FizzyoFramework.Instance.gameID; + + headers = new Dictionary(); + headers.Add("Authorization", "Bearer " + FizzyoFramework.Instance.User.AccessToken); + WWW sendGetUnlock = new WWW(getUnlock, null, headers); + + while (!sendGetUnlock.isDone) { } + + if(sendGetUnlock.error != null) + { + return FizzyoRequestReturnType.FAILED_TO_CONNECT; + } + + string unlockedJSONData = sendGetUnlock.text; + unlockedAchievements = JsonUtility.FromJson(unlockedJSONData).achievements; + + + return FizzyoRequestReturnType.SUCCESS; + + } + + internal void Load() + { + LoadAchievements(); + } + + + /// + /// Loads in the top 20 highscores for the current game + /// + /// + /// A JSON formatted string containing tag and score for the top 20 scores of the game + /// + public FizzyoRequestReturnType GetHighscores() + { + string getHighscores = "https://api.fizzyo-ucl.co.uk/api/v1/games/" + PlayerPrefs.GetString("gameId") + "/highscores"; + + Dictionary headers = new Dictionary(); + headers.Add("Authorization", "Bearer " + PlayerPrefs.GetString("accessToken")); + WWW sendGetHighscores = new WWW(getHighscores, null, headers); + + while (!sendGetHighscores.isDone) { } + + if (sendGetHighscores.error != null) + { + return FizzyoRequestReturnType.FAILED_TO_CONNECT; + } + + return FizzyoRequestReturnType.SUCCESS; + } + + + + + /// + /// Uploads a players Score + /// + /// + /// String - "High Score Upload Complete" - If upload completes + /// String - "High Score Upload Failed" - If upload fails + /// + public FizzyoRequestReturnType PostScore(int score) + { + string uploadScore = "https://api.fizzyo-ucl.co.uk/api/v1/games/" + PlayerPrefs.GetString("gameId") + "/highscores"; + + WWWForm form = new WWWForm(); + form.AddField("gameSecret", PlayerPrefs.GetString("gameSecret")); + form.AddField("userId", PlayerPrefs.GetString("userId")); + form.AddField("score", score); + Dictionary headers = form.headers; + headers["Authorization"] = "Bearer " + PlayerPrefs.GetString("accessToken"); + + byte[] rawData = form.data; + + WWW sendPostUnlock = new WWW(uploadScore, rawData, headers); + + while (!sendPostUnlock.isDone) { }; + + if (sendPostUnlock.error != null) + { + return FizzyoRequestReturnType.FAILED_TO_CONNECT; + } + + return FizzyoRequestReturnType.SUCCESS; + } + + + /// + /// Unlocks the achievement specified in the parameter, its achievementID. + /// + /// + /// String - "Achievement Upload Complete" - If upload completes + /// String - "Achievement Upload Failed" - If upload fails + /// + /// + public FizzyoRequestReturnType UnlockAchievement(string achievementId) + { + string unlockAchievement = "https://api.fizzyo-ucl.co.uk/api/v1/games/" + PlayerPrefs.GetString("gameId") + "/achievements/" + achievementId + "/unlock" ; + + WWWForm form = new WWWForm(); + form.AddField("gameSecret", PlayerPrefs.GetString("gameSecret")); + form.AddField("userId", PlayerPrefs.GetString("userId")); + form.AddField("achievementId", achievementId); + Dictionary headers = form.headers; + headers["Authorization"] = "Bearer " + PlayerPrefs.GetString("accessToken"); + + byte[] rawData = form.data; + + WWW sendPostUnlock = new WWW(unlockAchievement, rawData, headers); + + while (!sendPostUnlock.isDone) { }; + + if (sendPostUnlock.error != null) + { + return FizzyoRequestReturnType.FAILED_TO_CONNECT; + //TODO add upload que here + } + return FizzyoRequestReturnType.SUCCESS; + } + + /// + /// Uploads a players achievements for a session + /// + /// + /// String - "Achievement Upload Complete" - If upload completes + /// String - "Achievement Upload Failed" - If upload fails + /// + private FizzyoRequestReturnType PostAchievements() + { + string achievementsToUpload = PlayerPrefs.GetString("achievementsToUpload"); + + if (achievementsToUpload != "") + { + + string[] achievementsToUploadArray = achievementsToUpload.Split(','); + + for (int i = 0; i < achievementsToUploadArray.Length; i++) + { + + if (achievementsToUploadArray[i] != "") + { + + string postUnlock; + + postUnlock = "https://api.fizzyo-ucl.co.uk/api/v1/game/" + PlayerPrefs.GetString("gameId") + "/achievements/" + achievementsToUploadArray[i] + "/unlock"; + + WWWForm form = new WWWForm(); + + form.AddField("gameSecret", PlayerPrefs.GetString("gameSecret")); + form.AddField("userId", PlayerPrefs.GetString("userId")); + + Dictionary headers = form.headers; + headers["Authorization"] = "Bearer " + PlayerPrefs.GetString("accessToken"); + + byte[] rawData = form.data; + + WWW sendPostUnlock = new WWW(postUnlock, rawData, headers); + + while (!sendPostUnlock.isDone) { } + + if (sendPostUnlock.error != null) + { + return FizzyoRequestReturnType.FAILED_TO_CONNECT; + } + + } + + } + + } + + string achievementsToProgress = PlayerPrefs.GetString("achievementsToProgress"); + + string[] achievementsToProgressArray = achievementsToProgress.Split(','); + + AllAchievementData allUserProgress = JsonUtility.FromJson(PlayerPrefs.GetString(PlayerPrefs.GetString("userId") + "AchievementProgress")); + AllAchievementData allAchievements = JsonUtility.FromJson(PlayerPrefs.GetString("achievements")); + + // Add achievement progress to player preferences + for (int i = 0; i < achievementsToProgressArray.Length; i++) + { + + if (achievementsToProgressArray[i] != "") + { + + for (int j = 0; j < allUserProgress.achievements.Length; j++) + { + + if (allUserProgress.achievements[j].id == achievementsToProgressArray[i]) + { + for (int k = 0; k < allAchievements.achievements.Length; k++) + { + + if (allUserProgress.achievements[j].id == allAchievements.achievements[k].id) + { + allUserProgress.achievements[j].unlockProgress = allAchievements.achievements[k].unlockProgress; + string newAllData = JsonUtility.ToJson(allUserProgress); + PlayerPrefs.SetString(PlayerPrefs.GetString("userId") + "AchievementProgress", newAllData); + break; + } + + } + + break; + } + + } + + } + + } + return FizzyoRequestReturnType.SUCCESS; + } + + } + +} + diff --git a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoAchievements.meta b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoAchievements.meta new file mode 100644 index 0000000..ae748e0 --- /dev/null +++ b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoAchievements.meta @@ -0,0 +1,12 @@ +fileFormatVersion: 2 +guid: 4abe950c0647f934287b80702b38f82e +timeCreated: 1506958952 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoAnalytics.cs b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoAnalytics.cs index cc6168c..6be281d 100644 --- a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoAnalytics.cs +++ b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoAnalytics.cs @@ -6,6 +6,10 @@ namespace Fizzyo { + /// + /// An instance of this class can be created to send game analytics once a session is over. + /// This class is waiting for the developments of the API endpoints to be created. + /// public class FizzyoAnalytics { diff --git a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoAnalytics.cs.meta b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoAnalytics.cs.meta index 6e542dc..d1c3746 100644 --- a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoAnalytics.cs.meta +++ b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoAnalytics.cs.meta @@ -1,12 +1,12 @@ -fileFormatVersion: 2 -guid: dc5831fa0c3ab204aa1904866ca3c029 -timeCreated: 1507803556 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: dc5831fa0c3ab204aa1904866ca3c029 +timeCreated: 1507803556 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoBreathRecognizer.cs b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoBreathRecognizer.cs index dee0bd3..a57d6e3 100644 --- a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoBreathRecognizer.cs +++ b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoBreathRecognizer.cs @@ -3,368 +3,393 @@ using System.Linq; using System.Text; using UnityEngine; - -public class Session +namespace Fizzyo { - // Various session parameters - public int setCount; - public int breathCount; - public int goodBreathCount; - public int badBreathCount; - public int score; - public int startTime; - /// - /// Constructor for a session - /// - /// - /// Integer holding the amount of sets that are to be completed in this session - /// - /// - /// Integer holding the amount of breaths that are to be completed in each set - /// - public Session(int setCount, int breathCount) + //Deprecated? + public class Session { + // Various session parameters + public int setCount; + public int breathCount; + public int goodBreathCount; + public int badBreathCount; + public int score; + public int startTime; + + /// + /// Constructor for a session + /// + /// + /// Integer holding the amount of sets that are to be completed in this session + /// + /// + /// Integer holding the amount of breaths that are to be completed in each set + /// + public Session(int setCount, int breathCount) + { - this.setCount = setCount; - this.breathCount = breathCount; + this.setCount = setCount; + this.breathCount = breathCount; - DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc); - TimeSpan diff = DateTime.UtcNow - origin; - this.startTime = (int)Math.Floor(diff.TotalSeconds); + DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc); + TimeSpan diff = DateTime.UtcNow - origin; + this.startTime = (int)Math.Floor(diff.TotalSeconds); - } + } - /// - /// Used to upload a session and achievements gained within this session - /// - /// - /// Integer holding the amount of good breaths completed in this session - /// - /// - /// Integer holding the amount of bad breaths completed in this session - /// - /// /// - /// Integer holding the score for this session - /// - public bool SessionUpload(int goodBreathCount, int badBreathCount, int score) - { + /// + /// Used to upload a session and achievements gained within this session. + /// + /// + /// Integer holding the amount of good breaths completed in this session + /// + /// + /// Integer holding the amount of bad breaths completed in this session + /// + /// /// + /// Integer holding the score for this session + /// + public bool SessionUpload(int goodBreathCount, int badBreathCount, int score) + { - //return Data.Upload.Session(goodBreathCount, badBreathCount, score, startTime, setCount, breathCount); - return true; + //return Data.Upload.Session(goodBreathCount, badBreathCount, score, startTime, setCount, breathCount); + return true; + } } -} -/// -/// Provides data about the current breath to the receiver when the ExhalationComplete event fires -/// -public class ExhalationCompleteEventArgs : EventArgs -{ - private float breathLength = 0; - private int breathCount = 0; - private float exhaledVolume = 0; - private bool isBreathFull = false; - private float breathPercentage = 0; - private int breathQuality = 0; - - public ExhalationCompleteEventArgs(float breathLength, int breathCount, float exhaledVolume, bool isBreathFull, float breathPercentage, int breathQuality) + /// + /// Provides data about the current breath to the receiver when the ExhalationComplete event fires + /// + public class ExhalationCompleteEventArgs : EventArgs { - this.breathLength = breathLength; - this.breathCount = breathCount; - this.exhaledVolume = exhaledVolume; - this.isBreathFull = isBreathFull; - this.breathPercentage = breathPercentage; - this.breathQuality = breathQuality; + private float breathLength = 0; + private int breathCount = 0; + private float exhaledVolume = 0; + private bool isBreathFull = false; + private float breathPercentage = 0; + private int breathQuality = 0; + + public ExhalationCompleteEventArgs(float breathLength, int breathCount, float exhaledVolume, bool isBreathFull, float breathPercentage, int breathQuality) + { + this.breathLength = breathLength; + this.breathCount = breathCount; + this.exhaledVolume = exhaledVolume; + this.isBreathFull = isBreathFull; + this.breathPercentage = breathPercentage; + this.breathQuality = breathQuality; - } + } - /// The length of the exhaled breath in seconds - public float Breathlength - { - get + /// The length of the exhaled breath in seconds + public float Breathlength { - return breathLength; + get + { + return breathLength; + } } - } - /// The total number of exhaled breaths this session - public int BreathCount - { - get + /// The total number of exhaled breaths this session + public int BreathCount { - return breathCount; + get + { + return breathCount; + } } - } - /// The total exhaled volume of this breath - public float ExhaledVolume - { - get + /// The total exhaled volume of this breath + public float ExhaledVolume { - return exhaledVolume; + get + { + return exhaledVolume; + } } - } - /// Returns true if the breath was 100% completed - public bool IsBreathFull - { - get + /// Returns true if the breath was 100% completed + public bool IsBreathFull { - return isBreathFull; + get + { + return isBreathFull; + } } - } - /// Returns true if the breath was 100% completed - public int BreathQuality - { - get + /// Returns true if the breath was 100% completed + public int BreathQuality { - return breathQuality; + get + { + return breathQuality; + } } - } - /// Returns true if the breath was 100% completed - public float BreathPercentage - { - get + /// Returns true if the breath was 100% completed + public float BreathPercentage { - return breathPercentage; + get + { + return breathPercentage; + } } } -} - -public delegate void ExhalationCompleteEventHandler(object sender, ExhalationCompleteEventArgs e); -public delegate void ExhalationStartedEventHandler(object sender); - -/// -/// Breath Analyser class decouples the logic of recognizing breaths from a stream of pressure samples -/// from acting on the recognition. To use: -/// -/// 1. Create an instance of BreathAnalyser: BreathAnalyser breathAnalyser = new BreathAnalyser() -/// 2. Set the calibration properties: MaxPressure and MaxBreathLength -/// 3. Register for the ExhalationCompleteEvent: breathAnalyser.ExhalationComplete += ExhalationCompleteHandler -/// 4. Add pressure samples in the update loop: AddSample(Time.DeltaTime, pressure) -/// 5. The event will fire at the end of an exhaled breath and provide information for: -/// -/// a) BreathLength -/// b) BreathCount -/// c) ExhaledVolume -/// d) IsBreathFull -/// -/// 6. You can interrogate the breath analyser at any time to determine: -/// -/// a) BreathLength -/// b) BreathCount -/// c) ExhaledVolume -/// d) IsExhaling -/// e) MaxPressure -/// f) MaxBreathLength -/// -/// The algorithm for determining whether a breath is fully completed is encapsulated in the method IsBreathFull() -/// and currently returns true if the average breath pressure and breath length is within 80% of the max. -/// -public class BreathRecogniser -{ - private float breathLength = 0; - private int breathCount = 0; - private float exhaledVolume = 0; - private bool isExhaling = false; - private float maxPressure = 0; - private float maxBreathLength = 0; - private const float kTollerance = 0.80f; - private float minBreathThreshold = .05f; - private float breathPercentage = 0; - - public event ExhalationCompleteEventHandler BreathComplete; - public event ExhalationStartedEventHandler BreathStarted; - - - - public BreathRecogniser() + + public delegate void ExhalationCompleteEventHandler(object sender, ExhalationCompleteEventArgs e); + public delegate void ExhalationStartedEventHandler(object sender); + + /// + /// Breath Analyser class decouples the logic of recognizing breaths from a stream of pressure samples + /// from acting on the recognition. To use: + /// + /// 1. Create an instance of BreathAnalyser: BreathAnalyser breathAnalyser = new BreathAnalyser() + /// 2. Set the calibration properties: MaxPressure and MaxBreathLength + /// 3. Register for the ExhalationCompleteEvent: breathAnalyser.ExhalationComplete += ExhalationCompleteHandler + /// 4. Add pressure samples in the update loop: AddSample(Time.DeltaTime, pressure) + /// 5. The event will fire at the end of an exhaled breath and provide information for: + /// + /// a) BreathLength + /// b) BreathCount + /// c) ExhaledVolume + /// d) IsBreathFull + /// + /// You can interrogate the breath analyser at any time to determine: + /// + /// a) BreathLength + /// b) BreathCount + /// c) ExhaledVolume + /// d) IsExhaling + /// e) MaxPressure + /// f) MaxBreathLength + /// + /// The algorithm for determining whether a breath is fully completed is encapsulated in the method IsBreathFull() + /// and currently returns true if the average breath pressure and breath length is within 80% of the max. + /// + public class BreathRecogniser { + private float breathLength = 0; + private int breathCount = 0; + private float exhaledVolume = 0; + private bool isExhaling = false; + private float maxPressure = 0; + private float maxBreathLength = 0; + private const float kTollerance = 0.80f; + private float minBreathThreshold = .05f; + private float breathPercentage = 0; + + public event ExhalationCompleteEventHandler BreathComplete; + public event ExhalationStartedEventHandler BreathStarted; + + + + public BreathRecogniser() + { - } + } - /// The length of the current exhaled breath in seconds - public float BreathLength - { - get + /// The length of the current exhaled breath in seconds + public float BreathLength { - return this.breathLength; + get + { + return this.breathLength; + } } - } - /// The total number of exhaled breaths this session - public int BreathCount - { - get + /// The total number of exhaled breaths this session + public int BreathCount { - return this.breathCount; + get + { + return this.breathCount; + } } - } - /// The total exhaled volume for this breath - public float ExhaledVolume - { - get + /// The total exhaled volume for this breath + public float ExhaledVolume { - return this.exhaledVolume; + get + { + return this.exhaledVolume; + } } - } - /// True if the user is exhaling - public bool IsExhaling - { - get + /// True if the user is exhaling + public bool IsExhaling { - return this.isExhaling; + get + { + return this.isExhaling; + } } - } - /// The maximum pressure recorded during calibration - public float MaxPressure - { - get + /// The maximum pressure recorded during calibration + public float MaxPressure { - return this.maxPressure; + get + { + return this.maxPressure; + } + set + { + this.maxPressure = value; + } } - set + + /// The maximum breath length recorded during calibration + public float MaxBreathLength { - this.maxPressure = value; + get + { + return this.maxBreathLength; + } + set + { + this.maxBreathLength = value; + } } - } - /// The maximum breath length recorded during calibration - public float MaxBreathLength - { - get + /// True if the user is exhaling + public float BreathPercentage { - return this.maxBreathLength; + get + { + return this.breathPercentage; + } } - set + + /// + /// Adds a sample to the BreathAnalyser + /// + /// Float value indicating the delta time + /// Float value indicating breath strength + public void AddSample(float dt, float value) { - this.maxBreathLength = value; + + if (this.isExhaling && value < this.minBreathThreshold) + { + // Notify the delegate that the exhaled breath is complete + bool isBreathFull = this.IsBreathFull(this.breathLength, this.maxBreathLength, this.exhaledVolume, this.maxPressure); + int breathQuality = GetBreathQuality(this.breathPercentage); + ExhalationCompleteEventArgs eventArgs = new ExhalationCompleteEventArgs( + this.breathLength, + this.breathCount, + this.exhaledVolume, + isBreathFull, + this.breathPercentage, + breathQuality); + this.OnExhalationComplete(this, eventArgs); + + // Reset the state + this.breathLength = 0; + this.exhaledVolume = 0; + this.isExhaling = false; + this.breathCount++; + this.breathPercentage = 0; + } + else if (value >= this.minBreathThreshold) + { + if (!this.isExhaling) + { + OnExhalationStarted(this); + } + + this.isExhaling = true; + this.exhaledVolume += dt * value; + this.breathLength += dt; + this.breathPercentage = this.breathLength / (BreathRecogniser.kTollerance * this.maxBreathLength); + } } - } - /// True if the user is exhaling - public float BreathPercentage - { - get + /// + /// Returns true if the breath was within the threshold of a 'good breath' + /// + + public bool IsBreathFull(float breathLength, float maxBreathLength, float exhaledVolume, float maxPressure) { - return this.breathPercentage; + bool isBreathFull = false; + + // Is the breath the right within 80% of the correct length + isBreathFull = breathLength > BreathRecogniser.kTollerance * maxBreathLength; + + // Is the average pressure within 80% of the max pressure + if (this.breathLength > 0) + { + isBreathFull = isBreathFull && ((exhaledVolume / breathLength) > BreathRecogniser.kTollerance * maxPressure); + } + + return isBreathFull; } - } - /// Adds a sample to the BreathAnalyser - public void AddSample(float dt, float value) - { + /// + /// Returns an integer indicating breath quality (see return values) + /// + /// + /// 0 - Breath was 0 - 25% of the calibrated breath length + /// + /// 1 - Breath was 25% - 50% of the calibrated breath length + /// + /// 2 - Breath was 50 - 75% of the calibrated breath length + /// + /// 3 - Breath was 75% - 100% of the calibrated breath length + /// + /// 4 - Breath was 100% of the calibrated breath length + /// + public int GetBreathQuality(float breathPercentage) + { + int quality = 0; + + if (breathPercentage < 0.5f && breathPercentage > 0.25f) + quality = 1; + else if (breathPercentage < 0.75f && breathPercentage > 0.5f) + quality = 2; + else if (breathPercentage < 1.0f && breathPercentage > 0.75f) + quality = 3; + else if (breathPercentage >= 1.0f) + quality = 4; + + return quality; + } - if (this.isExhaling && value < this.minBreathThreshold) + /// + /// Resest the BreathAnalyser + /// + public void ResetSession() { - // Notify the delegate that the exhaled breath is complete - bool isBreathFull = this.IsBreathFull(this.breathLength, this.maxBreathLength, this.exhaledVolume, this.maxPressure); - int breathQuality = GetBreathQuality(this.breathPercentage); - ExhalationCompleteEventArgs eventArgs = new ExhalationCompleteEventArgs( - this.breathLength, - this.breathCount, - this.exhaledVolume, - isBreathFull, - this.breathPercentage, - breathQuality); - this.OnExhalationComplete(this, eventArgs); - - // Reset the state this.breathLength = 0; + this.breathCount = 0; this.exhaledVolume = 0; this.isExhaling = false; - this.breathCount++; this.breathPercentage = 0; } - else if (value >= this.minBreathThreshold) + + /// + /// Invoke the event - called whenever exhalation finishes + /// + protected virtual void OnExhalationComplete(object sender, ExhalationCompleteEventArgs e) { - if (!this.isExhaling) + if (BreathComplete != null) { - OnExhalationStarted(this); + BreathComplete(this, e); } - - this.isExhaling = true; - this.exhaledVolume += dt * value; - this.breathLength += dt; - this.breathPercentage = this.breathLength / (BreathRecogniser.kTollerance * this.maxBreathLength); } - } - - /// Returns true if the breath was within the toterance of a 'good breath' - public bool IsBreathFull(float breathLength, float maxBreathLength, float exhaledVolume, float maxPressure) - { - bool isBreathFull = false; - - // Is the breath the right within 80% of the correct length - isBreathFull = breathLength > BreathRecogniser.kTollerance * maxBreathLength; - - // Is the average pressure within 80% of the max pressure - if (this.breathLength > 0) - { - isBreathFull = isBreathFull && ((exhaledVolume / breathLength) > BreathRecogniser.kTollerance * maxPressure); - } - - return isBreathFull; - } - - /// Returns an integer that corresponds to the following: - /// 0 - Breath was 0 - 25% of the calibrated breath length - /// 1 - Breath was 25% - 50% of the calibrated breath length - /// 2 - Breath was 50 - 75% of the calibrated breath length - /// 3 - Breath was 75% - 100% of the calibrated breath length - /// 4 - Breath was 100% of the calibrated breath length - public int GetBreathQuality(float breathPercentage) - { - int quality = 0; - - if (breathPercentage < 0.5f && breathPercentage > 0.25f) - quality = 1; - else if (breathPercentage < 0.75f && breathPercentage > 0.5f) - quality = 2; - else if (breathPercentage < 1.0f && breathPercentage > 0.75f) - quality = 3; - else if (breathPercentage >= 1.0f) - quality = 4; - - return quality; - } - /// Resest the BreathAnalyser - public void ResetSession() - { - this.breathLength = 0; - this.breathCount = 0; - this.exhaledVolume = 0; - this.isExhaling = false; - this.breathPercentage = 0; - } - /// Invoke the event - called whenever exhalation finishes - protected virtual void OnExhalationComplete(object sender, ExhalationCompleteEventArgs e) - { - if (BreathComplete != null) + /// + /// Invoke the event - called whenever exhalation starts + /// + protected virtual void OnExhalationStarted(object sender) { - BreathComplete(this, e); + if (BreathStarted != null) + { + BreathStarted(this); + } } - } - /// Invoke the event - called whenever exhalation starts - protected virtual void OnExhalationStarted(object sender) - { - if (BreathStarted != null) - { - BreathStarted(this); - } } - - } \ No newline at end of file diff --git a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoBreathRecognizer.cs.meta b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoBreathRecognizer.cs.meta index 2da77d0..81264d5 100644 --- a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoBreathRecognizer.cs.meta +++ b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoBreathRecognizer.cs.meta @@ -1,12 +1,12 @@ -fileFormatVersion: 2 -guid: 8e26caedf69f26d4fad45e7c7983157d -timeCreated: 1507113811 -licenseType: Pro -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 8e26caedf69f26d4fad45e7c7983157d +timeCreated: 1507113811 +licenseType: Pro +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoCalibration.cs b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoCalibration.cs index 2d1b2bc..4d9e449 100644 --- a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoCalibration.cs +++ b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoCalibration.cs @@ -14,16 +14,24 @@ public class Calibration : MonoBehaviour // Time that current breath has been held for private float breathLength; - // How many calibration steps have been completed + /// + /// How many calibration steps have been completed + /// public int calibrationStep = 1; - // How many calibration steps need to be completed + /// + /// How many calibration steps are required + /// public int requiredSteps = 3; - // Status of calibration + /// + /// Status of calibration + /// public string calibrationStatus; - // A color reflecting of the status of the calibration + /// + /// A color reflecting the status of calibration + /// public Color calibrationColor; // List that holds pressure readings from calibration @@ -44,21 +52,31 @@ public class Calibration : MonoBehaviour // Breath has to be above this to register private float minPressureThreshold = 0.1f; - // Pressure used for calibration from device + /// + /// Pressure used for calibration from device + /// public float pressure; - // If true calibration script is running + + /// + /// If true calibration script is running + /// public bool calibrating = false; - // If true calibration is finished + /// + /// If true calibration is finished + /// public bool calibrationFinished = false; /// - /// Used to get input from the device to get a pressure and time value that can be used in the breath framework, according to the breathing capacity of the user - /// Pressure is a float value that determines how hard the user needs to blow into the device to constitute a good breath - /// Time is an integer value that determines how long the user needs to blow into the device to constitute a good breath - /// Calibration pressure and time are saved in the player preferences as "calPressure" and "calTime" + /// Used to get input from the device to get a pressure and time value that can be used in the breath framework, according to the breathing capacity of the user. + /// + /// Pressure is a float value that determines how hard the user needs to blow into the device to constitute a good breath. + /// + /// Time is an integer value that determines how long the user needs to blow into the device to constitute a good breath. + /// + /// Calibration pressure and time are saved in the player preferences as "calPressure" and "calTime". /// public void Calibrate() { diff --git a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoCalibration.cs.meta b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoCalibration.cs.meta index dcfbcff..458ef40 100644 --- a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoCalibration.cs.meta +++ b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoCalibration.cs.meta @@ -1,12 +1,12 @@ -fileFormatVersion: 2 -guid: 917ba54383e55a54597bda719356fdd1 -timeCreated: 1507291839 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 917ba54383e55a54597bda719356fdd1 +timeCreated: 1507291839 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoDevice.cs b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoDevice.cs index 230a771..383e41e 100644 --- a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoDevice.cs +++ b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoDevice.cs @@ -10,18 +10,29 @@ namespace Fizzyo { + /// + /// Class responsible for parsing data from the Fizzyo device + /// public class FizzyoDevice { - // True if pulling data from internal file + /// + /// True if pulling data from an internal file. Useful for testing. + /// public bool useRecordedData = false; - // True if looping through recorded data + /// + /// True if looping through recorded data. Useful for testing + /// public bool loop = true; - // Data path of recorded data + /// + /// Path of the recorded data + /// public string recordedDataPath = "Fizzyo/Data/FizzyoData_3min.fiz"; - //this si the maxmimun pressure to expect from the device, all incomming values will be mapped to it. + /// + /// This is the maxmimun pressure to expect from the device, all incomming values will be mapped to it. + /// public float maxPressureCalibrated = 1.0f; //private static object threadLock = new System.Object(); @@ -37,6 +48,9 @@ public class FizzyoDevice private Timer pollTimer; #endif + /// + /// If true, indicates the device has been already calibrated. + /// public bool Calibrated = false; public FizzyoDevice() @@ -81,6 +95,9 @@ public float Pressure() } } + /// + /// Checks if the button in the fizzyo device is being pushed down. + /// public bool ButtonDown() { return Input.GetButtonDown("Fire1"); @@ -132,6 +149,9 @@ void PollLoggedData(object o, System.EventArgs e) } #endif + /// + /// Changes the maximum callibrated pressure to the specified value. Will set the Calibrated boolean to true. + /// public void SetCalibrationPressure(float maxPressure) { maxPressureCalibrated = maxPressure; diff --git a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoDevice.cs.meta b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoDevice.cs.meta index 4bfba1b..d363691 100644 --- a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoDevice.cs.meta +++ b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoDevice.cs.meta @@ -1,12 +1,12 @@ -fileFormatVersion: 2 -guid: 47e62f5e25656ef47b7637e3bf6b9b81 -timeCreated: 1489178901 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 47e62f5e25656ef47b7637e3bf6b9b81 +timeCreated: 1489178901 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoFramework.cs b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoFramework.cs index 536e918..99081f8 100644 --- a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoFramework.cs +++ b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoFramework.cs @@ -18,37 +18,62 @@ public enum FizzyoRequestReturnType { SUCCESS, INCORRECT_TOKEN, FAILED_TO_CONNEC /// /// Interface class for Fizzyo Framework /// + public class FizzyoFramework : MonoBehaviour { [Header("Script Behaviour")] [Tooltip("Automatically show login screen at start of game.")] + /// + ///Set to true, shows login screen at start of the game + /// public bool showLoginAutomatically = true; [Tooltip("Automatically show gamer tag editor if user does not have this set.")] + /// + ///Set to true, shows login screen at start of the game + /// public bool showSetGamerTagAutomatically = false; [Tooltip("Automatically show calibration screen if never calibratd by user.")] + /// + ///Set to true, shows calibration screen if there has never been a calibration + /// public bool showCalibrateAutomatically = true; [Tooltip("Game ID given by Fizzyo API.")] + /// + ///The game ID given by the Fizzyo API + /// public string gameID = "87f2ae03-d34f-4045-a308-feb746e857b2"; [Tooltip("Game secret given by Fizzyo API.")] + /// + ///The game secret given by the Fizzyo API + /// public string gameSecret = "7BErm0wMvbmXMpq6ANBNLnAaYAlO1nqVqM15wNJAPdRom7lYyKKOEzqeGyOXpZKn"; [Header("Test Harness")] [Tooltip("Use test harness data.")] + /// + ///Set false, enables use of test data instead of live data + /// public bool useTestHarnessData = false; //Use test harness instead of live data public enum TestHarnessData { p1_acapella, p1_pep, p2_acapella }; + /// + ///The type of data used for testing + /// public TestHarnessData testHarnessDataFile = TestHarnessData.p1_acapella; + /// + ///The singleton instance of the Fizzyo Framework + /// public static FizzyoFramework _instance = null; public FizzyoUser User { get; set; } public FizzyoDevice Device { get; set; } - public FizzyoAchievments Achievments { get; set; } + public FizzyoAchievements Achievements { get; set; } public BreathRecogniser Recogniser { get; set; } private static object _lock = new object(); @@ -122,7 +147,7 @@ private FizzyoFramework() User = new FizzyoUser(); Device = new FizzyoDevice(); Recogniser = new BreathRecogniser(); - Achievments = new FizzyoAchievments(); + Achievements = new FizzyoAchievements(); } @@ -137,7 +162,7 @@ void Start() DontDestroyOnLoad(gameObject); Load(); - + if (useTestHarnessData) { @@ -166,43 +191,59 @@ private void Update() Recogniser.AddSample(Time.deltaTime, Device.Pressure()); } - + } /// - /// Loads the user data from the Fizzyo API + /// Loads the user data from the Fizzyo API. + /// /// PlayerPrefs holds the users information in the following configuration: - /// "online" - Integer - 0 or 1 - Tells the developer if the user is playing offline or online - /// "calDone" - Integer - 0 or 1 - Tells the developer if the user has completed calibration - /// "achievments" - String - Holds the achievements for the game and, if the user is online, tells the developer - /// which achievements have been unlocked - /// "achievmentsToUpload" - String - Holds the achievements that have been unlocked in the current session - /// Current players userID + "AchievementProgress" - String - Holds data on the achievement progress that the user has made in this game + /// + /// "online" - Integer - 0 or 1 - Tells the developer if the user is playing offline or online + /// + /// "calDone" - Integer - 0 or 1 - Tells the developer if the user has completed calibration + /// + /// "achievements" - String - Holds the achievements for the game and, if the user is online, tells the developer + /// which achievements have been unlocked + /// + /// "achievementsToUpload" - String - Holds the achievements that have been unlocked in the current session + /// + /// Current players userID + "AchievementProgress" - String - Holds data on the achievement progress that the user has made in this game + /// /// "accessToken" - String - Holds the access token that is aquired for the current user + /// /// "tagDone" - Integer - 0 or 1 - Tells the developer if the user has completed setting a tag + /// /// "userTag" - String - Holds the user tag + /// /// "calPressure" - Float - Holds the pressure that the user has set in their calibration + /// /// "calTime" - Integer - Holds the breath length that the user has set in their calibration + /// /// "userId" - String - Holds the user Id that is aquired for the current user + /// /// "gameId" - String - Holds the game Id for this specific game + /// /// "gameSecret" - String - Holds the game secret for this specific game + /// /// "userLoaded" - Integer - 0 or 1 - Shows if the users access token was loaded + /// /// "calLoaded" - Integer - 0 or 1 - Shows if the users calibration data was loaded + /// /// "achLoaded" - Integer - 0 or 1 - Shows if the users achievement data was loaded + /// /// "tagLoaded" - Integer - 0 or 1 - Shows if the users tag was loaded + /// /// - /// - /// String that contains the current games ID - /// - /// - /// String that contains the current games secret - /// + /// String that contains the current games ID + /// String that contains the current games secret /// /// true if data is loaded and playing online - /// false if daa is not loaded and playing offline - /// + /// + /// false if data is not loaded and playing offline + /// public bool Load() { //Login to server @@ -211,7 +252,7 @@ public bool Load() { LoginReturnType loginResult = User.Login(); - + if (loginResult != LoginReturnType.SUCCESS) { PlayOffline(); @@ -225,9 +266,9 @@ public bool Load() } User.Load(); - Achievments.Load(); + Achievements.Load(); + - return true; diff --git a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoFramework.cs.meta b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoFramework.cs.meta index 96279a0..71dac73 100644 --- a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoFramework.cs.meta +++ b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoFramework.cs.meta @@ -1,12 +1,12 @@ -fileFormatVersion: 2 -guid: bc2c607f2ff22354b9193ee107173be7 -timeCreated: 1503486155 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: bc2c607f2ff22354b9193ee107173be7 +timeCreated: 1503486155 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoUser.cs b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoUser.cs index 08d0674..0076874 100644 --- a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoUser.cs +++ b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoUser.cs @@ -1,4 +1,4 @@ -using System; + using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -49,6 +49,9 @@ public enum LoginReturnType { SUCCESS, INCORRECT, FAILED_TO_CONNECT } public enum UserTagReturnType { SUCCESS, NOT_SET, FAILED_TO_CONNECT, BANNED_TAG } public enum CalibrationReturnType { SUCCESS, NOT_SET, FAILED_TO_CONNECT} + /// + /// Class that handles correct identification of each user, thanks to the use of Windows Live authentication + /// public class FizzyoUser { @@ -63,10 +66,21 @@ public class FizzyoUser private string patientRecordId; private string token; + /// + /// Indicates whether someone is logged in or not + /// public bool loggedIn = false; + /// + /// String holding the username of the account logging in + /// public string username; - + /// + /// Testing variables, by default, username should be : test-patient + /// public string testUsername = "test-patient"; + /// + /// Testing variables, by default, password should be : FizzyoTesting2017 + /// public string testPassword = "FizzyoTesting2017"; public string UserID { get; internal set; } @@ -78,6 +92,9 @@ public class FizzyoUser private bool userTagSet; private bool calibrationSet; + /// + /// Method that begins the login process. + /// public LoginReturnType Login() { @@ -102,6 +119,9 @@ public LoginReturnType Login() } + /// + /// Logs out the user. TO BE IMPLEMENTED + /// public void Logout() { @@ -264,6 +284,9 @@ public async Task RequestAccessToken(string code) #endif + /// + /// Function that runs the methods responsible for loading user tags and calibration data. + /// public void Load() { @@ -492,10 +515,14 @@ public CalibrationReturnType Calibration(float pressure, float time) /// /// /// Integer that holds the amount of breaths that were completed in the session + /// /// /// String - "Session Upload Complete /nAchievement Upload Complete" - If session upload completes and achievement upload completes + /// /// String - "Session Upload Complete /nAchievement Upload Failed" - If session upload completes and achievement upload fails + /// /// String - "Session Upload Failed /nAchievement Upload Complete" - If session upload fails and achievement upload completes + /// /// String - "Session Upload Failed /nAchievement Upload Failed" - If session upload fails and achievement upload fails /// public static string Session(int goodBreathCount, int badBreathCount, int score, int startTime, int setCount, int breathCount) diff --git a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoUser.cs.meta b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoUser.cs.meta index 3c7ffe4..fffc690 100644 --- a/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoUser.cs.meta +++ b/Assets/Fizzyo/Scripts/FizzyoFramework/FizzyoUser.cs.meta @@ -1,12 +1,12 @@ -fileFormatVersion: 2 -guid: 6867fbc1c328a1e4f95ecd935dba8535 -timeCreated: 1506958952 -licenseType: Free -MonoImporter: - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +fileFormatVersion: 2 +guid: 6867fbc1c328a1e4f95ecd935dba8535 +timeCreated: 1506958952 +licenseType: Free +MonoImporter: + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: