From 7fe6d62207f1edf25a465ca5aad5ec44f6e0dbe0 Mon Sep 17 00:00:00 2001
From: Thibaut Monseigne <thibaut.monseigne@inria.fr>
Date: Tue, 9 Nov 2021 10:42:29 +0100
Subject: [PATCH] :sparkles: Add Rotation and continuous stream search

---
 Assets/Editor/BuildConfig.cs       |  52 +++++------
 Assets/Editor/BuildHooks.cs        | 133 ++++++++++++++---------------
 Assets/Scenes/main.unity           |   5 +-
 Assets/Scripts/Controller.cs       |  12 ++-
 Assets/Scripts/FloatInlet.cs       |  24 +++---
 Assets/Scripts/StimulationInlet.cs |  30 +++----
 6 files changed, 132 insertions(+), 124 deletions(-)

diff --git a/Assets/Editor/BuildConfig.cs b/Assets/Editor/BuildConfig.cs
index ed09abe..9432f43 100644
--- a/Assets/Editor/BuildConfig.cs
+++ b/Assets/Editor/BuildConfig.cs
@@ -15,37 +15,37 @@ using UnityEditor.Build.Reporting;
 
 namespace OVGames.HelloWorld.Editor
 {
-	/// <summary> Wrapper of <see cref="BuildPlayerOptions"/> with improved build path configuration. </summary>
-	public sealed class BuildConfig
-	{
-		/// <summary> Gets or sets the location of the build directory, relative to the project root directory. </summary>
-		/// <value> The location of the build directory. </value>
-		public string DirectoryPath { get; set; }
+/// <summary> Wrapper of <see cref="BuildPlayerOptions"/> with improved build path configuration. </summary>
+public sealed class BuildConfig
+{
+	/// <summary> Gets or sets the location of the build directory, relative to the project root directory. </summary>
+	/// <value> The location of the build directory. </value>
+	public string DirectoryPath { get; set; }
 
-		/// <summary> Gets or set the location of the application to build, relative to <see cref="DirectoryPath"/>. </summary>
-		/// <value> The location of the application to build, relative to <see cref="DirectoryPath"/>. </value>
-		public string RelativeFilePath { get; set; }
+	/// <summary> Gets or set the location of the application to build, relative to <see cref="DirectoryPath"/>. </summary>
+	/// <value> The location of the application to build, relative to <see cref="DirectoryPath"/>. </value>
+	public string RelativeFilePath { get; set; }
 
-		/// <summary> Gets or sets the <see cref="Action"/> to execute after
-		/// <see cref="BuildPipeline.BuildPlayer(BuildPlayerOptions)"/> with the <see cref="BuildReport"/>. </summary>
-		/// <value> the <see cref="Action"/> to execute after build. </value>
-		public Action<BuildReport> AfterBuild { get; set; }
+	/// <summary> Gets or sets the <see cref="Action"/> to execute after
+	/// <see cref="BuildPipeline.BuildPlayer(BuildPlayerOptions)"/> with the <see cref="BuildReport"/>. </summary>
+	/// <value> the <see cref="Action"/> to execute after build. </value>
+	public Action<BuildReport> AfterBuild { get; set; }
 
-		/// <summary> The build options. </summary>
-		/// <value> The build options. </value>
-		private BuildPlayerOptions options = new BuildPlayerOptions();
+	/// <summary> The build options. </summary>
+	/// <value> The build options. </value>
+	private BuildPlayerOptions options = new BuildPlayerOptions();
 
-		/// <summary> Gets or sets the options for <see cref="BuildPipeline.BuildPlayer(BuildPlayerOptions)"/>. </summary>
-		/// <remarks> <see cref="BuildPlayerOptions.locationPathName"/> is automatically set to
-		/// <see cref="DirectoryPath"/> + <see cref="RelativeFilePath"/>. </remarks>
-		public BuildPlayerOptions Options
+	/// <summary> Gets or sets the options for <see cref="BuildPipeline.BuildPlayer(BuildPlayerOptions)"/>. </summary>
+	/// <remarks> <see cref="BuildPlayerOptions.locationPathName"/> is automatically set to
+	/// <see cref="DirectoryPath"/> + <see cref="RelativeFilePath"/>. </remarks>
+	public BuildPlayerOptions Options
+	{
+		get
 		{
-			get
-			{
-				options.locationPathName = DirectoryPath + RelativeFilePath;
-				return options;
-			}
-			set => options = value;
+			options.locationPathName = DirectoryPath + RelativeFilePath;
+			return options;
 		}
+		set => options = value;
 	}
 }
+}
diff --git a/Assets/Editor/BuildHooks.cs b/Assets/Editor/BuildHooks.cs
index b00afeb..1c6b3da 100644
--- a/Assets/Editor/BuildHooks.cs
+++ b/Assets/Editor/BuildHooks.cs
@@ -18,92 +18,89 @@ using UnityEditor;
 
 namespace OVGames.HelloWorld.Editor
 {
-	/// <summary> Build and/or run for different <see cref="BuildTarget"/>. Supported platforms are <see cref="BuildTarget.StandaloneWindows64"/>. </summary>
-	public static class BuildHooks
-	{
-		/// <summary> Path to the builds, relative to the project root folder. </summary>
-		private const string BUILD_PATH = "Builds/";
+/// <summary> Build and/or run for different <see cref="BuildTarget"/>. Supported platforms are <see cref="BuildTarget.StandaloneWindows64"/>. </summary>
+public static class BuildHooks
+{
+	/// <summary> Path to the builds, relative to the project root folder. </summary>
+	private const string BUILD_PATH = "Builds/";
 
-		/// <summary> Name of the build. /// </summary>
-		private const string FILENAME = "Hello World";
+	/// <summary> Name of the build. /// </summary>
+	private const string FILENAME = "Hello World";
 
-		/// <summary> The path of the scene to build, relative to the project root folder. </summary>
-		private static readonly string[] scenesPath = { "Assets/Scenes/main.unity" };
+	/// <summary> The path of the scene to build, relative to the project root folder. </summary>
+	private static readonly string[] scenesPath = { "Assets/Scenes/main.unity" };
 
-		/// <summary> List of <see cref="BuildConfig"/> for supported <see cref="BuildTarget"/>. </summary>
-		private static readonly Dictionary<BuildTarget, BuildConfig> configs = new Dictionary<BuildTarget, BuildConfig>
+	/// <summary> List of <see cref="BuildConfig"/> for supported <see cref="BuildTarget"/>. </summary>
+	private static readonly Dictionary<BuildTarget, BuildConfig> configs = new Dictionary<BuildTarget, BuildConfig>
+																		   {
 																			   {
+																				   BuildTarget.StandaloneWindows64,
+																				   new BuildConfig
 																				   {
-																					   BuildTarget.StandaloneWindows64,
-																					   new BuildConfig
-																					   {
-																						   DirectoryPath    = BUILD_PATH + "Windows/",
-																						   RelativeFilePath = FILENAME + ".exe",
-																						   Options = new BuildPlayerOptions
-																									 {
-																										 scenes = scenesPath,
-																										 target = BuildTarget.StandaloneWindows64
-																									 },
-																						   AfterBuild = buildReport => { }
-																					   }
+																					   DirectoryPath    = BUILD_PATH + "Windows/",
+																					   RelativeFilePath = FILENAME + ".exe",
+																					   Options = new BuildPlayerOptions
+																								 {
+																									 scenes = scenesPath,
+																									 target = BuildTarget.StandaloneWindows64
+																								 },
+																					   AfterBuild = buildReport => { }
 																				   }
-																			   };
+																			   }
+																		   };
 
-		/// <summary> Calls <see cref="BuildWindows"/>. </summary>
-		[MenuItem("OVGames/Hello World/Build for all platforms", priority = 0)]
-		public static void BuildAll() { BuildWindows(); }
+	/// <summary> Calls <see cref="BuildWindows"/>. </summary>
+	[MenuItem("OVGames/Hello World/Build for all platforms", priority = 0)]
+	public static void BuildAll() { BuildWindows(); }
 
-		/// <summary> Calls <see cref="BuildRunWindows"/>. </summary>
-		[MenuItem("OVGames/Hello World/Build and Run all platforms", priority = 1)]
-		public static void BuildRundAll() { BuildRunWindows(); }
+	/// <summary> Calls <see cref="BuildRunWindows"/>. </summary>
+	[MenuItem("OVGames/Hello World/Build and Run all platforms", priority = 1)]
+	public static void BuildRundAll() { BuildRunWindows(); }
 
-		/// <summary> Calls <see cref="Build(BuildTarget, bool)"/> to build for <see cref="BuildTarget.StandaloneWindows64"/>. </summary>
-		[MenuItem("OVGames/Hello World/Build for Windows", priority = 100)]
-		public static void BuildWindows() { Build( /*BuildTarget.StandaloneWindows64, andRun: false*/); }
+	/// <summary> Calls <see cref="Build(BuildTarget, bool)"/> to build for <see cref="BuildTarget.StandaloneWindows64"/>. </summary>
+	[MenuItem("OVGames/Hello World/Build for Windows", priority = 100)]
+	public static void BuildWindows() { Build( /*BuildTarget.StandaloneWindows64, andRun: false*/); }
 
-		/// <summary> Calls <see cref="Build(BuildTarget, bool)"/> to build and run for <see cref="BuildTarget.StandaloneWindows64"/>. </summary>
-		[MenuItem("OVGames/Hello World/Build and Run for Windows", priority = 101)]
-		public static void BuildRunWindows() { Build(BuildTarget.StandaloneWindows64, andRun: true); }
-
-		/// <summary> Build for the specified <see cref="BuildTarget"/>. </summary>
-		/// <param name="target"> The <see cref="BuildTarget"/> to build. </param>
-		/// <param name="andRun"> Automatically run or not the build. </param>
-		private static void Build(BuildTarget target = BuildTarget.StandaloneWindows64, bool andRun = false)
-		{
-			// Get configuration
-			if (!configs.TryGetValue(target, out var configuration))
-			{
-				throw new ArgumentException($"The {target} platform is not supported.", nameof(target));
-			}
+	/// <summary> Calls <see cref="Build(BuildTarget, bool)"/> to build and run for <see cref="BuildTarget.StandaloneWindows64"/>. </summary>
+	[MenuItem("OVGames/Hello World/Build and Run for Windows", priority = 101)]
+	public static void BuildRunWindows() { Build(BuildTarget.StandaloneWindows64, andRun: true); }
 
-			// Clear previous build
-			var path = new DirectoryInfo(configuration.DirectoryPath);
-			if (path.Exists) { path.Delete(recursive: true); }
+	/// <summary> Build for the specified <see cref="BuildTarget"/>. </summary>
+	/// <param name="target"> The <see cref="BuildTarget"/> to build. </param>
+	/// <param name="andRun"> Automatically run or not the build. </param>
+	private static void Build(BuildTarget target = BuildTarget.StandaloneWindows64, bool andRun = false)
+	{
+		// Get configuration
+		if (!configs.TryGetValue(target, out var configuration)) { throw new ArgumentException($"The {target} platform is not supported.", nameof(target)); }
 
-			// Update build options
-			var options = configuration.Options;
-			options.options |= BuildOptions.StrictMode;
+		// Clear previous build
+		var path = new DirectoryInfo(configuration.DirectoryPath);
+		if (path.Exists) { path.Delete(recursive: true); }
 
-			if (andRun) { options.options |= BuildOptions.AutoRunPlayer; }
+		// Update build options
+		var options = configuration.Options;
+		options.options |= BuildOptions.StrictMode;
 
-			configuration.Options = options;
+		if (andRun) { options.options |= BuildOptions.AutoRunPlayer; }
 
-			// Build
-			var report = BuildPipeline.BuildPlayer(configuration.Options);
+		configuration.Options = options;
 
-			var summary = new StringBuilder();
-			summary.AppendLine($"Build {target} target {report.summary.result}");
-			foreach (var step in report.steps)
-			{
-				summary.AppendLine();
-				summary.AppendLine(step.ToString());
+		// Build
+		var report = BuildPipeline.BuildPlayer(configuration.Options);
 
-				foreach (var message in step.messages) { summary.AppendLine($"{message.type}: {message.content}"); }
-			}
-			Debug.Log(summary);
+		var summary = new StringBuilder();
+		summary.AppendLine($"Build {target} target {report.summary.result}");
+		foreach (var step in report.steps)
+		{
+			summary.AppendLine();
+			summary.AppendLine(step.ToString());
 
-			// After build
-			configuration.AfterBuild?.Invoke(report);
+			foreach (var message in step.messages) { summary.AppendLine($"{message.type}: {message.content}"); }
 		}
+		Debug.Log(summary);
+
+		// After build
+		configuration.AfterBuild?.Invoke(report);
 	}
 }
+}
diff --git a/Assets/Scenes/main.unity b/Assets/Scenes/main.unity
index 2f5e892..2586d2e 100644
--- a/Assets/Scenes/main.unity
+++ b/Assets/Scenes/main.unity
@@ -38,7 +38,7 @@ RenderSettings:
   m_ReflectionIntensity: 1
   m_CustomReflection: {fileID: 0}
   m_Sun: {fileID: 0}
-  m_IndirectSpecularColor: {r: 0.4465782, g: 0.49641252, b: 0.5748167, a: 1}
+  m_IndirectSpecularColor: {r: 0.44657826, g: 0.49641263, b: 0.57481676, a: 1}
   m_UseRadianceAmbientProbe: 0
 --- !u!157 &3
 LightmapSettings:
@@ -215,6 +215,7 @@ MonoBehaviour:
   m_Script: {fileID: 11500000, guid: 3fccaf98eee689c43b2b0a573f7f5e21, type: 3}
   m_Name: 
   m_EditorClassIdentifier: 
+  rotationAxis: {x: 10, y: 10, z: 10}
   scale: 1
   signalInlet: {fileID: 102141085}
   stimInlet: {fileID: 102141084}
@@ -232,6 +233,7 @@ MonoBehaviour:
   m_EditorClassIdentifier: 
   moment: 1
   streamName: ovMarkers
+  waitStream: 0
 --- !u!114 &102141085
 MonoBehaviour:
   m_ObjectHideFlags: 0
@@ -246,6 +248,7 @@ MonoBehaviour:
   m_EditorClassIdentifier: 
   moment: 1
   streamName: ovSignal
+  waitStream: 0
 --- !u!1 &208898348
 GameObject:
   m_ObjectHideFlags: 0
diff --git a/Assets/Scripts/Controller.cs b/Assets/Scripts/Controller.cs
index d344d4f..277ffa8 100644
--- a/Assets/Scripts/Controller.cs
+++ b/Assets/Scripts/Controller.cs
@@ -27,7 +27,8 @@ public class Controller : MonoBehaviour
 	private                 Material material;
 
 	// Settings
-	[SerializeField] private float            scale = 1;
+	[SerializeField] private Vector3          rotationAxis = new Vector3(10.0F, 10.0F, 10.0F);
+	[SerializeField] private float            scale        = 1;
 	[SerializeField] private FloatInlet       signalInlet;
 	[SerializeField] private StimulationInlet stimInlet;
 
@@ -43,10 +44,17 @@ public class Controller : MonoBehaviour
 			Application.Quit();
 		}
 
+		// Check Stream
+		if (!signalInlet.IsSolved()) { signalInlet.ResolveStream(); }
+		if (!stimInlet.IsSolved()) { stimInlet.ResolveStream(); }
+
+		// Rotate the cube
+		transform.Rotate(rotationAxis * Time.deltaTime);
+
 		// Change Scale
 		if (signalInlet.LastSample != null && signalInlet.LastSample.Length > 0)
 		{
-			float value = Math.Abs(signalInlet.LastSample[0]) * scale;
+			var value = Math.Abs(signalInlet.LastSample[0]) * scale;
 			if (value > 1e-6) { transform.localScale = new Vector3(value, value, value); }
 		}
 
diff --git a/Assets/Scripts/FloatInlet.cs b/Assets/Scripts/FloatInlet.cs
index f559cb7..4aed2f7 100644
--- a/Assets/Scripts/FloatInlet.cs
+++ b/Assets/Scripts/FloatInlet.cs
@@ -13,17 +13,17 @@ using LSL4Unity.OV;
 
 namespace OVGames.HelloWorld
 {
-	/// <summary> An example of implementation for an Inlet receiving Float values for OpenViBE Link. </summary>
-	/// <seealso cref="OVFloatInlet" />
-	public class FloatInlet : OVFloatInlet
-	{
-		/// <summary> Member that contains the last sample. </summary>
-		/// <value> The last sample. </value>
-		public float[] LastSample { get; private set; }
+/// <summary> An example of implementation for an Inlet receiving Float values for OpenViBE Link. </summary>
+/// <seealso cref="OVFloatInlet" />
+public class FloatInlet : OVFloatInlet
+{
+	/// <summary> Member that contains the last sample. </summary>
+	/// <value> The last sample. </value>
+	public float[] LastSample { get; private set; }
 
-		/// <summary> Process when samples are available. </summary>
-		/// <param name="input"> The Incomming Sample. </param>
-		/// <param name="time"> The current Time. </param>
-		protected override void Process(float[] input, double time) { LastSample = input; }
-	}
+	/// <summary> Process when samples are available. </summary>
+	/// <param name="input"> The Incomming Sample. </param>
+	/// <param name="time"> The current Time. </param>
+	protected override void Process(float[] input, double time) { LastSample = input; }
+}
 }
diff --git a/Assets/Scripts/StimulationInlet.cs b/Assets/Scripts/StimulationInlet.cs
index 0618679..9c41ead 100644
--- a/Assets/Scripts/StimulationInlet.cs
+++ b/Assets/Scripts/StimulationInlet.cs
@@ -14,21 +14,21 @@ using UnityEngine;
 
 namespace OVGames.HelloWorld
 {
-	/// <summary> Implementation for an Inlet receiving Stimulations (int) from OpenViBE. </summary>
-	/// <seealso cref="OVIntInlet" />
-	public class StimulationInlet : OVIntInlet
-	{
-		/// <summary> Member that contains the last sample. </summary>
-		/// <value> The last sample. </value>
-		public int[] LastSample { get; set; }
+/// <summary> Implementation for an Inlet receiving Stimulations (int) from OpenViBE. </summary>
+/// <seealso cref="OVIntInlet" />
+public class StimulationInlet : OVIntInlet
+{
+	/// <summary> Member that contains the last sample. </summary>
+	/// <value> The last sample. </value>
+	public int[] LastSample { get; set; }
 
-		/// <summary> Process when samples are available. </summary>
-		/// <param name="input"> The Incomming Sample. </param>
-		/// <param name="time"> The current Time. </param>
-		protected override void Process(int[] input, double time)
-		{
-			LastSample = input;
-			Debug.Log($"Got {input.Length} ints at {time}");
-		}
+	/// <summary> Process when samples are available. </summary>
+	/// <param name="input"> The Incomming Sample. </param>
+	/// <param name="time"> The current Time. </param>
+	protected override void Process(int[] input, double time)
+	{
+		LastSample = input;
+		Debug.Log($"Got {input.Length} ints at {time}");
 	}
 }
+}
-- 
GitLab