From afc1b3e7fa1fb7e1cb67862e3d99ab1388e263c1 Mon Sep 17 00:00:00 2001
From: Thibaut Monseigne <thibaut.monseigne@inria.fr>
Date: Fri, 19 Feb 2021 10:09:10 +0100
Subject: [PATCH] =?UTF-8?q?:sparkles:=20Add=20possibilit=C3=A9=20to=20just?=
 =?UTF-8?q?=20search=20stream=20and=20quit?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 OV/OVInlets.cs | 352 +++++++++++++++++++++++++------------------------
 1 file changed, 182 insertions(+), 170 deletions(-)

diff --git a/OV/OVInlets.cs b/OV/OVInlets.cs
index a77cbb4..d87f9b3 100644
--- a/OV/OVInlets.cs
+++ b/OV/OVInlets.cs
@@ -4,173 +4,185 @@ using UnityEngine;
 
 namespace LSL4Unity.OV
 {
-	/// <summary> Base Inlet for OpenViBE Link. </summary>
-	/// <seealso cref="MonoBehaviour" />
-	public abstract class OVInlet<T> : MonoBehaviour
-	{
-		private enum UpdateMoment { FixedUpdate, Update, OnDemand }
-
-		[SerializeField] private UpdateMoment moment     = UpdateMoment.Update;
-		[SerializeField] private string       streamName = "ovSignal";
-
-		public string StreamName => streamName;
-
-		protected liblsl.StreamInlet        inlet;
-		private   liblsl.ContinuousResolver resolver;
-
-		private   bool readyToResolve   = true;
-		protected int  expectedChannels = 0;
-		protected T[]  samples;
-
-
-		/// <summary> Start is called before the first frame update. </summary>
-		private void Start()
-		{
-			bool hasAName = streamName.Length != 0;
-
-			if (!hasAName)
-			{
-				Debug.LogError("Inlet has to specify a name or a type before it is able to lookup a stream.");
-				enabled = false;
-				return;
-			}
-
-			Debug.Log("Creating LSL resolver for stream " + streamName);
-			resolver = new liblsl.ContinuousResolver("name", streamName);
-
-			StartCoroutine(ResolveExpectedStream());
-		}
-
-		/// <summary> Fixupdate is called once per physics framerate. </summary>
-		private void FixedUpdate()
-		{
-			if (moment == UpdateMoment.FixedUpdate && inlet != null) { PullSamples(); }
-		}
-
-		/// <summary> Update is called once per frame. </summary>
-		private void Update()
-		{
-			if (moment == UpdateMoment.Update && inlet != null) { PullSamples(); }
-		}
-
-		/// <summary> ForceUpdate is called when it's needed. </summary>
-		public void ForceUpdate() { PullSamples(); }
-
-		/// <summary> Resolves the stream. </summary>
-		/// <returns></returns>
-		private IEnumerator ResolveExpectedStream()
-		{
-			yield return new WaitUntil(() => readyToResolve); // False mutex to wait Found Stream before search an other
-			readyToResolve = false;                           // Avoïd double resolver
-
-			liblsl.StreamInfo[] results = resolver.Results();
-			yield return new WaitUntil(() => results.Length > 0);
-
-			Debug.Log($"Resolving Stream : Name = {streamName}, Steam Info Name = {results[0].Name()}, Stream Info Type = ({results[0].Type()}");
-
-			inlet            = new liblsl.StreamInlet(results[0]);
-			expectedChannels = inlet.Info().ChannelCount();
-
-			readyToResolve = true;
-			yield return null;
-		}
-
-		/// <summary> Pull the samples. </summary>
-		protected abstract void PullSamples();
-
-		/// <summary> Override this method in the subclass to specify what should happen when samples are available. </summary>
-		/// <param name="input"> The Incomming Sample. </param>
-		/// <param name="time"> The current Time. </param>
-		protected abstract void Process(T[] input, double time);
-	}
-
-	/// <summary> Float Inlet for OpenViBE Link. </summary>
-	/// <seealso cref="OVInlet{T}" />
-	public abstract class OVFloatInlet : OVInlet<float>
-	{
-		/// <inheritdoc cref="OVInlet{T}.PullSamples"/>
-		protected override void PullSamples()
-		{
-			samples = new float[expectedChannels];
-
-			try
-			{
-				double lastTimeStamp = inlet.PullSample(samples, 0.0f);
-
-				if (Math.Abs(lastTimeStamp) > Constants.TOLERANCE)
-				{
-					// do not miss the first one found
-					Process(samples, lastTimeStamp);
-					// pull as long samples are available
-					while (Math.Abs(lastTimeStamp = inlet.PullSample(samples, 0.0f)) > Constants.TOLERANCE) { Process(samples, lastTimeStamp); }
-				}
-			}
-			catch (ArgumentException e)
-			{
-				Debug.LogError("An Error on pulling samples deactivating LSL inlet on...", this);
-				enabled = false;
-				Debug.LogException(e, this);
-			}
-		}
-	}
-
-	/// <summary> Double Inlet for OpenViBE Link. </summary>
-	/// <seealso cref="OVInlet{T}" />
-	public abstract class OVDoubleInlet : OVInlet<double>
-	{
-		/// <inheritdoc cref="OVInlet{T}.PullSamples"/>
-		protected override void PullSamples()
-		{
-			samples = new double[expectedChannels];
-
-			try
-			{
-				double lastTimeStamp = inlet.PullSample(samples, 0.0f);
-
-				if (Math.Abs(lastTimeStamp) > Constants.TOLERANCE)
-				{
-					// do not miss the first one found
-					Process(samples, lastTimeStamp);
-					// pull as long samples are available
-					while (Math.Abs(lastTimeStamp = inlet.PullSample(samples, 0.0f)) > Constants.TOLERANCE) { Process(samples, lastTimeStamp); }
-				}
-			}
-			catch (ArgumentException e)
-			{
-				Debug.LogError("An Error on pulling samples deactivating LSL inlet on...", this);
-				enabled = false;
-				Debug.LogException(e, this);
-			}
-		}
-	}
-
-	/// <summary> Int Inlet for OpenViBE Link. </summary>
-	/// <seealso cref="OVInlet{T}" />
-	public abstract class OVIntInlet : OVInlet<int>
-	{
-		/// <inheritdoc cref="OVInlet{T}.PullSamples"/>
-		protected override void PullSamples()
-		{
-			samples = new int[expectedChannels];
-
-			try
-			{
-				double lastTimeStamp = inlet.PullSample(samples, 0.0f);
-
-				if (Math.Abs(lastTimeStamp) > Constants.TOLERANCE)
-				{
-					// do not miss the first one found
-					Process(samples, lastTimeStamp);
-					// pull as long samples are available
-					while (Math.Abs(lastTimeStamp = inlet.PullSample(samples, 0.0f)) > Constants.TOLERANCE) { Process(samples, lastTimeStamp); }
-				}
-			}
-			catch (ArgumentException e)
-			{
-				Debug.LogError("An Error on pulling samples deactivating LSL inlet on...", this);
-				enabled = false;
-				Debug.LogException(e, this);
-			}
-		}
-	}
-}
+    /// <summary> Base Inlet for OpenViBE Link. </summary>
+    /// <seealso cref="MonoBehaviour" />
+    public abstract class OVInlet<T> : MonoBehaviour
+    {
+        private enum UpdateMoment { FixedUpdate, Update, OnDemand }
+
+        [SerializeField] private UpdateMoment moment     = UpdateMoment.Update;
+        [SerializeField] private string       streamName = "ovSignal";
+        [SerializeField] private bool         waitStream = true;
+
+        public string StreamName => streamName;
+
+        protected liblsl.StreamInlet        inlet;
+        private   liblsl.ContinuousResolver resolver;
+
+        private   bool readyToResolve   = true;
+        protected int  expectedChannels = 0;
+        protected T[]  samples;
+
+
+        /// <summary> Start is called before the first frame update. </summary>
+        private void Start()
+        {
+            bool hasAName = streamName.Length != 0;
+
+            if (!hasAName)
+            {
+                Debug.LogError("Inlet has to specify a name or a type before it is able to lookup a stream.");
+                enabled = false;
+                return;
+            }
+
+            Debug.Log("Creating LSL resolver for stream " + streamName);
+            resolver = new liblsl.ContinuousResolver("name", streamName);
+            ResolveStream();
+        }
+
+        /// <summary> Fixupdate is called once per physics framerate. </summary>
+        private void FixedUpdate()
+        {
+            if (moment == UpdateMoment.FixedUpdate && inlet != null) { PullSamples(); }
+        }
+
+        /// <summary> Update is called once per frame. </summary>
+        private void Update()
+        {
+            if (moment == UpdateMoment.Update && inlet != null) { PullSamples(); }
+        }
+
+        /// <summary> ForceUpdate is called when it's needed. </summary>
+        public void ForceUpdate() { PullSamples(); }
+
+        /// <summary> Start coroutine to resolve stream. </summary>
+        public void ResolveStream()
+        {
+            if (inlet == null) { StartCoroutine(ResolveExpectedStream()); }
+        }
+
+        /// <summary> Check if inlet is created. </summary>
+        public bool IsSolved() { return (inlet != null); }
+
+        private void CreateInlet(liblsl.StreamInfo result)
+        {
+            Debug.Log($"Resolving Stream : Name = {streamName}, Steam Info Name = {result.Name()}, Stream Info Type = ({result.Type()}");
+            inlet            = new liblsl.StreamInlet(result);
+            expectedChannels = inlet.Info().ChannelCount();
+        }
+
+        /// <summary> Resolves the stream. </summary>
+        /// <returns></returns>
+        private IEnumerator ResolveExpectedStream()
+        {
+            Debug.Log($"private IEnumerator ResolveExpectedStream()");
+            yield return new WaitUntil(() => readyToResolve); // False mutex to wait Found Stream before search an other
+            readyToResolve = false;                           // Avoïd double resolver
+
+            liblsl.StreamInfo[] results = resolver.Results();
+            if (waitStream) { yield return new WaitUntil(() => results.Length > 0); }
+            if (results.Length > 0) { CreateInlet(results[0]); }
+            readyToResolve = true;
+            yield return null;
+        }
+
+        /// <summary> Pull the samples. </summary>
+        protected abstract void PullSamples();
+
+        /// <summary> Override this method in the subclass to specify what should happen when samples are available. </summary>
+        /// <param name="input"> The Incomming Sample. </param>
+        /// <param name="time"> The current Time. </param>
+        protected abstract void Process(T[] input, double time);
+    }
+
+    /// <summary> Float Inlet for OpenViBE Link. </summary>
+    /// <seealso cref="OVInlet{T}" />
+    public abstract class OVFloatInlet : OVInlet<float>
+    {
+        /// <inheritdoc cref="OVInlet{T}.PullSamples"/>
+        protected override void PullSamples()
+        {
+            samples = new float[expectedChannels];
+
+            try
+            {
+                double lastTimeStamp = inlet.PullSample(samples, 0.0f);
+
+                if (Math.Abs(lastTimeStamp) > Constants.TOLERANCE)
+                {
+                    // do not miss the first one found
+                    Process(samples, lastTimeStamp);
+                    // pull as long samples are available
+                    while (Math.Abs(lastTimeStamp = inlet.PullSample(samples, 0.0f)) > Constants.TOLERANCE) { Process(samples, lastTimeStamp); }
+                }
+            }
+            catch (ArgumentException e)
+            {
+                Debug.LogError("An Error on pulling samples deactivating LSL inlet on...", this);
+                enabled = false;
+                Debug.LogException(e, this);
+            }
+        }
+    }
+
+    /// <summary> Double Inlet for OpenViBE Link. </summary>
+    /// <seealso cref="OVInlet{T}" />
+    public abstract class OVDoubleInlet : OVInlet<double>
+    {
+        /// <inheritdoc cref="OVInlet{T}.PullSamples"/>
+        protected override void PullSamples()
+        {
+            samples = new double[expectedChannels];
+
+            try
+            {
+                double lastTimeStamp = inlet.PullSample(samples, 0.0f);
+
+                if (Math.Abs(lastTimeStamp) > Constants.TOLERANCE)
+                {
+                    // do not miss the first one found
+                    Process(samples, lastTimeStamp);
+                    // pull as long samples are available
+                    while (Math.Abs(lastTimeStamp = inlet.PullSample(samples, 0.0f)) > Constants.TOLERANCE) { Process(samples, lastTimeStamp); }
+                }
+            }
+            catch (ArgumentException e)
+            {
+                Debug.LogError("An Error on pulling samples deactivating LSL inlet on...", this);
+                enabled = false;
+                Debug.LogException(e, this);
+            }
+        }
+    }
+
+    /// <summary> Int Inlet for OpenViBE Link. </summary>
+    /// <seealso cref="OVInlet{T}" />
+    public abstract class OVIntInlet : OVInlet<int>
+    {
+        /// <inheritdoc cref="OVInlet{T}.PullSamples"/>
+        protected override void PullSamples()
+        {
+            samples = new int[expectedChannels];
+
+            try
+            {
+                double lastTimeStamp = inlet.PullSample(samples, 0.0f);
+
+                if (Math.Abs(lastTimeStamp) > Constants.TOLERANCE)
+                {
+                    // do not miss the first one found
+                    Process(samples, lastTimeStamp);
+                    // pull as long samples are available
+                    while (Math.Abs(lastTimeStamp = inlet.PullSample(samples, 0.0f)) > Constants.TOLERANCE) { Process(samples, lastTimeStamp); }
+                }
+            }
+            catch (ArgumentException e)
+            {
+                Debug.LogError("An Error on pulling samples deactivating LSL inlet on...", this);
+                enabled = false;
+                Debug.LogException(e, this);
+            }
+        }
+    }
+}
\ No newline at end of file
-- 
GitLab