diff --git a/GazeWebSocketServer/Program.cs b/GazeWebSocketServer/Program.cs index 7e8753c..f821768 100644 --- a/GazeWebSocketServer/Program.cs +++ b/GazeWebSocketServer/Program.cs @@ -16,18 +16,17 @@ namespace GazeWebSocketServer if (args.Length > 0 && args[0] == "-d") { tracker = new FakeTracker(600); - tracker.GazeDataAvailable += OnGazeDataAvailable; //TODO: Extend interface usage - //tracker.GazeDataProcessor.OutputFrequency = config.OutputFrequency; } else { - TobiiEyeTracker tobiiEyeTracker = new TobiiEyeTracker(config.TrackerSerialNumber); - tobiiEyeTracker.ConnectionEvent += OnConnectionEstablished; - tobiiEyeTracker.ConnectionTimeout += OnConnectionTimeout; - tobiiEyeTracker.GazeDataAvailable += OnGazeDataAvailable; - tobiiEyeTracker.Connect(); + tracker = new TobiiEyeTracker(config.TrackerSerialNumber); } + tracker.ConnectionEvent += OnConnectionEstablished; + tracker.ConnectionTimeout += OnConnectionTimeout; + tracker.GazeDataAvailable += OnGazeDataAvailable; + tracker.Connect(); + gazeServer = new GazeServer(config.WebSocketPort, config.WebSocketEndpoint); gazeServer.Start(); Console.ReadLine(); @@ -52,7 +51,8 @@ namespace GazeWebSocketServer { Console.WriteLine($"Tracker {sender.SerialNumber} connected."); ConfigurationData config = ConfigurationData.ParseToObject(); - sender.SetTrackingFrequency(config.TrackerFrequency); + sender.TrackingFrequency = config.TrackerFrequency; + sender.OutputFrequency = config.OutputFrequency; } } } \ No newline at end of file diff --git a/TrackerBridge/DSP/GazeDecimator.cs b/TrackerBridge/DSP/GazeDecimator.cs index c68ee86..f897e9c 100644 --- a/TrackerBridge/DSP/GazeDecimator.cs +++ b/TrackerBridge/DSP/GazeDecimator.cs @@ -16,6 +16,7 @@ namespace TrackerBridge.DSP private readonly Object outputLock = new Object(); private readonly Object valueCountLock = new Object(); private Int64 valueCount; + private Task timerTask; private Int64 ValueCount { get { @@ -47,10 +48,10 @@ namespace TrackerBridge.DSP } } - public GazeDecimator(Single outputFrequency) + public GazeDecimator(GazeDataProcessor dataProcessor) { - this.outputFrequency = outputFrequency; - Task.Run(() => TriggerOutput(outputFrequency)); + outputFrequency = dataProcessor.OutputFrequency; + Task timerTask = Task.Run(() => TriggerOutput(outputFrequency)); } public void Input(GazeData input, Object sender = null) { @@ -89,5 +90,13 @@ namespace TrackerBridge.DSP timer.AutoReset = true; timer.Start(); } + + public void Update(GazeDataProcessor dataProcessor) + { + outputFrequency = dataProcessor.OutputFrequency; + //timerTask.Dispose(); //TODO: Implement proper cancellation + //TODO: Fix memory leak + timerTask = Task.Run(() => TriggerOutput(outputFrequency)); + } } } diff --git a/TrackerBridge/DSP/IGazeFilter.cs b/TrackerBridge/DSP/IGazeFilter.cs index c23c6e7..f09b9e2 100644 --- a/TrackerBridge/DSP/IGazeFilter.cs +++ b/TrackerBridge/DSP/IGazeFilter.cs @@ -11,5 +11,6 @@ namespace TrackerBridge.DSP event GazeDataHandler OutputAvailable; void Input(GazeData input, Object sender = null); void Reset(); + void Update(GazeDataProcessor dataProcessor); } } diff --git a/TrackerBridge/FakeTracker.cs b/TrackerBridge/FakeTracker.cs index 6a0ba06..629867b 100644 --- a/TrackerBridge/FakeTracker.cs +++ b/TrackerBridge/FakeTracker.cs @@ -8,30 +8,48 @@ namespace TrackerBridge { public class FakeTracker : IBridgeTracker { - + public event ConnectionEventHandler ConnectionEvent; + public event ConnectionEventHandler ConnectionTimeout; public event GazeDataHandler GazeDataAvailable { add { - GazeDataProcessor.GazeDataProcessed += value; + gazeDataProcessor.GazeDataProcessed += value; } remove { - GazeDataProcessor.GazeDataProcessed -= value; + gazeDataProcessor.GazeDataProcessed -= value; } } - public event EventHandler TrackingFrequencyChanged; + private readonly GazeDataProcessor gazeDataProcessor; + private Task timerTask; private Single trackerFrequency; - public String SerialNumber => throw new NotImplementedException(); - public GazeDataProcessor GazeDataProcessor { get; } + public Single OutputFrequency { + get => gazeDataProcessor.OutputFrequency; + set => gazeDataProcessor.OutputFrequency = value; + } + public String SerialNumber => "Fake"; + public Single TrackingFrequency { + get { + return trackerFrequency; + } + set { + //timerTask.Dispose(); //TODO: Proper cancellation + //TODO: Fix memory leak + timerTask = Task.Run(() => SimulateGazeDataHz(value)); + } + } public FakeTracker(Single frequency) { trackerFrequency = frequency; - GazeDataProcessor = new GazeDataProcessor(this); - //GazeDataProcessor.OutputFrequency = 1; - Task.Run(() => SimulateGazeDataHz(frequency)); + gazeDataProcessor = new GazeDataProcessor(); } + public void Connect() + { + timerTask = Task.Run(() => SimulateGazeDataHz(trackerFrequency)); + ConnectionEvent?.Invoke(this); + } private void SimulateGazeDataHz(Single frequency) { System.Timers.Timer timer = new System.Timers.Timer(1000.0 / frequency); //TODO: Implement Dispose @@ -39,19 +57,10 @@ namespace TrackerBridge { Point mousePosition = Control.MousePosition; GazeData data = new GazeData(mousePosition.X, mousePosition.Y, mousePosition.X, mousePosition.Y, 0, 0); - GazeDataProcessor.Process(this, data); + gazeDataProcessor.Process(this, data); }; timer.AutoReset = true; timer.Start(); } - - public Single GetTrackingFrequency() - { - return trackerFrequency; - } - public void SetTrackingFrequency(Single value) - { - throw new NotImplementedException(); - } } } diff --git a/TrackerBridge/GazeDataProcessor.cs b/TrackerBridge/GazeDataProcessor.cs index 943fb62..0515968 100644 --- a/TrackerBridge/GazeDataProcessor.cs +++ b/TrackerBridge/GazeDataProcessor.cs @@ -33,13 +33,13 @@ namespace TrackerBridge } } - public GazeDataProcessor(IBridgeTracker tracker) + public GazeDataProcessor() { - tracker.TrackingFrequencyChanged += OnTrackingFrequencyChanged; + outputFrequency = 60; //Default screenHeight = Convert.ToSingle(SystemParameters.PrimaryScreenHeight); screenWidth = Convert.ToSingle(SystemParameters.PrimaryScreenWidth); gazeFilters = new IGazeFilter[1]; - gazeFilters[0] = new GazeDecimator(60); //TODO: Refactor frequency passthrough + gazeFilters[0] = new GazeDecimator(this); //TODO: Refactor frequency passthrough //Chain filters for(Int32 index= 0; index < gazeFilters.Length-1; index++) @@ -52,6 +52,7 @@ namespace TrackerBridge { foreach (IGazeFilter filter in gazeFilters) { + filter.Update(this); filter.Reset(); } } @@ -71,16 +72,5 @@ namespace TrackerBridge { gazeFilters[0].Input(input); } - private void OnTrackingFrequencyChanged(Object sender, Single frequency) - { - foreach(IGazeFilter filter in gazeFilters) - { - if(filter.GetType() == typeof(GazeDecimator)) - { - GazeDecimator decimator = (GazeDecimator)filter; - throw new NotImplementedException(); - } - } - } } } diff --git a/TrackerBridge/IBridgeTracker.cs b/TrackerBridge/IBridgeTracker.cs index 328fe8e..b76d7ed 100644 --- a/TrackerBridge/IBridgeTracker.cs +++ b/TrackerBridge/IBridgeTracker.cs @@ -11,12 +11,14 @@ namespace TrackerBridge public interface IBridgeTracker { + event ConnectionEventHandler ConnectionEvent; + event ConnectionEventHandler ConnectionTimeout; event GazeDataHandler GazeDataAvailable; - event EventHandler TrackingFrequencyChanged; - GazeDataProcessor GazeDataProcessor { get;} + + Single OutputFrequency { get; set; } String SerialNumber { get; } + Single TrackingFrequency { get; set; } - Single GetTrackingFrequency(); - void SetTrackingFrequency(Single value); + void Connect(); } } diff --git a/TrackerBridge/TobiiEyeTracker.cs b/TrackerBridge/TobiiEyeTracker.cs index db6d4a2..9c22721 100644 --- a/TrackerBridge/TobiiEyeTracker.cs +++ b/TrackerBridge/TobiiEyeTracker.cs @@ -13,55 +13,55 @@ namespace TrackerBridge public event ConnectionEventHandler ConnectionTimeout; public event GazeDataHandler GazeDataAvailable { add { - GazeDataProcessor.GazeDataProcessed += value; + gazeDataProcessor.GazeDataProcessed += value; } remove { - GazeDataProcessor.GazeDataProcessed -= value; + gazeDataProcessor.GazeDataProcessed -= value; } } - public event EventHandler TrackingFrequencyChanged; + private readonly GazeDataProcessor gazeDataProcessor; private IEyeTracker eyeTracker = null; - public GazeDataProcessor GazeDataProcessor { get; } public Boolean IsConnected { get; private set; } = false; + public Single OutputFrequency { + get => gazeDataProcessor.OutputFrequency; + set => gazeDataProcessor.OutputFrequency = value; + } public String SerialNumber { get; private set; } = null; + public Single TrackingFrequency { + get { + if (eyeTracker != null) + { + return eyeTracker.GetGazeOutputFrequency(); + } + else + { + return 0f; + } + } + set { + if (eyeTracker != null && eyeTracker.GetAllGazeOutputFrequencies().Contains(value)) + { + eyeTracker.SetGazeOutputFrequency(value); + } + } + } public TobiiEyeTracker() { - GazeDataProcessor = new GazeDataProcessor(this); + gazeDataProcessor = new GazeDataProcessor(); } - public TobiiEyeTracker(String serialNumber) : this() { SerialNumber = serialNumber; } + public void Connect() { Task task = new Task(() => InitiateConnection()); task.Start(); } - - public Single GetTrackingFrequency() - { - if (eyeTracker != null) - { - return eyeTracker.GetGazeOutputFrequency(); - } - else - { - throw new NullReferenceException(); - } - } - - public void SetTrackingFrequency(float value) - { - if (eyeTracker != null && eyeTracker.GetAllGazeOutputFrequencies().Contains(value)) - { - eyeTracker.SetGazeOutputFrequency(value); - } - } - private void InitiateConnection() { DateTime time = DateTime.Now; @@ -98,16 +98,10 @@ namespace TrackerBridge ConnectionTimeout?.Invoke(this); } } - eyeTracker.GazeDataReceived += GazeDataProcessor.Process; - eyeTracker.GazeOutputFrequencyChanged += OnGazeOutputFrequencyChanged; + eyeTracker.GazeDataReceived += gazeDataProcessor.Process; SerialNumber = eyeTracker.SerialNumber; - SetTrackingFrequency(600f); + TrackingFrequency = 600f; ConnectionEvent?.Invoke(this); } - - private void OnGazeOutputFrequencyChanged(Object sender, GazeOutputFrequencyEventArgs e) - { - TrackingFrequencyChanged?.Invoke(this, e.GazeOutputFrequency); - } } } \ No newline at end of file