Commit 241680ff by Stefan Schreistetter

Refactored. Timer task memory leaks are to be fixed.

parent b55d8fdf
...@@ -16,18 +16,17 @@ namespace GazeWebSocketServer ...@@ -16,18 +16,17 @@ namespace GazeWebSocketServer
if (args.Length > 0 && args[0] == "-d") if (args.Length > 0 && args[0] == "-d")
{ {
tracker = new FakeTracker(600); tracker = new FakeTracker(600);
tracker.GazeDataAvailable += OnGazeDataAvailable; //TODO: Extend interface usage
//tracker.GazeDataProcessor.OutputFrequency = config.OutputFrequency;
} }
else else
{ {
TobiiEyeTracker tobiiEyeTracker = new TobiiEyeTracker(config.TrackerSerialNumber); tracker = new TobiiEyeTracker(config.TrackerSerialNumber);
tobiiEyeTracker.ConnectionEvent += OnConnectionEstablished;
tobiiEyeTracker.ConnectionTimeout += OnConnectionTimeout;
tobiiEyeTracker.GazeDataAvailable += OnGazeDataAvailable;
tobiiEyeTracker.Connect();
} }
tracker.ConnectionEvent += OnConnectionEstablished;
tracker.ConnectionTimeout += OnConnectionTimeout;
tracker.GazeDataAvailable += OnGazeDataAvailable;
tracker.Connect();
gazeServer = new GazeServer(config.WebSocketPort, config.WebSocketEndpoint); gazeServer = new GazeServer(config.WebSocketPort, config.WebSocketEndpoint);
gazeServer.Start(); gazeServer.Start();
Console.ReadLine(); Console.ReadLine();
...@@ -52,7 +51,8 @@ namespace GazeWebSocketServer ...@@ -52,7 +51,8 @@ namespace GazeWebSocketServer
{ {
Console.WriteLine($"Tracker {sender.SerialNumber} connected."); Console.WriteLine($"Tracker {sender.SerialNumber} connected.");
ConfigurationData config = ConfigurationData.ParseToObject(); ConfigurationData config = ConfigurationData.ParseToObject();
sender.SetTrackingFrequency(config.TrackerFrequency); sender.TrackingFrequency = config.TrackerFrequency;
sender.OutputFrequency = config.OutputFrequency;
} }
} }
} }
\ No newline at end of file
...@@ -16,6 +16,7 @@ namespace TrackerBridge.DSP ...@@ -16,6 +16,7 @@ namespace TrackerBridge.DSP
private readonly Object outputLock = new Object(); private readonly Object outputLock = new Object();
private readonly Object valueCountLock = new Object(); private readonly Object valueCountLock = new Object();
private Int64 valueCount; private Int64 valueCount;
private Task timerTask;
private Int64 ValueCount { private Int64 ValueCount {
get { get {
...@@ -47,10 +48,10 @@ namespace TrackerBridge.DSP ...@@ -47,10 +48,10 @@ namespace TrackerBridge.DSP
} }
} }
public GazeDecimator(Single outputFrequency) public GazeDecimator(GazeDataProcessor dataProcessor)
{ {
this.outputFrequency = outputFrequency; outputFrequency = dataProcessor.OutputFrequency;
Task.Run(() => TriggerOutput(outputFrequency)); Task timerTask = Task.Run(() => TriggerOutput(outputFrequency));
} }
public void Input(GazeData input, Object sender = null) public void Input(GazeData input, Object sender = null)
{ {
...@@ -89,5 +90,13 @@ namespace TrackerBridge.DSP ...@@ -89,5 +90,13 @@ namespace TrackerBridge.DSP
timer.AutoReset = true; timer.AutoReset = true;
timer.Start(); 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));
}
} }
} }
...@@ -11,5 +11,6 @@ namespace TrackerBridge.DSP ...@@ -11,5 +11,6 @@ namespace TrackerBridge.DSP
event GazeDataHandler OutputAvailable; event GazeDataHandler OutputAvailable;
void Input(GazeData input, Object sender = null); void Input(GazeData input, Object sender = null);
void Reset(); void Reset();
void Update(GazeDataProcessor dataProcessor);
} }
} }
...@@ -8,30 +8,48 @@ namespace TrackerBridge ...@@ -8,30 +8,48 @@ namespace TrackerBridge
{ {
public class FakeTracker : IBridgeTracker public class FakeTracker : IBridgeTracker
{ {
public event ConnectionEventHandler ConnectionEvent;
public event ConnectionEventHandler ConnectionTimeout;
public event GazeDataHandler GazeDataAvailable { public event GazeDataHandler GazeDataAvailable {
add { add {
GazeDataProcessor.GazeDataProcessed += value; gazeDataProcessor.GazeDataProcessed += value;
} }
remove { remove {
GazeDataProcessor.GazeDataProcessed -= value; gazeDataProcessor.GazeDataProcessed -= value;
} }
} }
public event EventHandler<Single> TrackingFrequencyChanged;
private readonly GazeDataProcessor gazeDataProcessor;
private Task timerTask;
private Single trackerFrequency; 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) public FakeTracker(Single frequency)
{ {
trackerFrequency = frequency; trackerFrequency = frequency;
GazeDataProcessor = new GazeDataProcessor(this); gazeDataProcessor = new GazeDataProcessor();
//GazeDataProcessor.OutputFrequency = 1;
Task.Run(() => SimulateGazeDataHz(frequency));
} }
public void Connect()
{
timerTask = Task.Run(() => SimulateGazeDataHz(trackerFrequency));
ConnectionEvent?.Invoke(this);
}
private void SimulateGazeDataHz(Single frequency) private void SimulateGazeDataHz(Single frequency)
{ {
System.Timers.Timer timer = new System.Timers.Timer(1000.0 / frequency); //TODO: Implement Dispose System.Timers.Timer timer = new System.Timers.Timer(1000.0 / frequency); //TODO: Implement Dispose
...@@ -39,19 +57,10 @@ namespace TrackerBridge ...@@ -39,19 +57,10 @@ namespace TrackerBridge
{ {
Point mousePosition = Control.MousePosition; Point mousePosition = Control.MousePosition;
GazeData data = new GazeData(mousePosition.X, mousePosition.Y, mousePosition.X, mousePosition.Y, 0, 0); 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.AutoReset = true;
timer.Start(); timer.Start();
} }
public Single GetTrackingFrequency()
{
return trackerFrequency;
}
public void SetTrackingFrequency(Single value)
{
throw new NotImplementedException();
}
} }
} }
...@@ -33,13 +33,13 @@ namespace TrackerBridge ...@@ -33,13 +33,13 @@ namespace TrackerBridge
} }
} }
public GazeDataProcessor(IBridgeTracker tracker) public GazeDataProcessor()
{ {
tracker.TrackingFrequencyChanged += OnTrackingFrequencyChanged; outputFrequency = 60; //Default
screenHeight = Convert.ToSingle(SystemParameters.PrimaryScreenHeight); screenHeight = Convert.ToSingle(SystemParameters.PrimaryScreenHeight);
screenWidth = Convert.ToSingle(SystemParameters.PrimaryScreenWidth); screenWidth = Convert.ToSingle(SystemParameters.PrimaryScreenWidth);
gazeFilters = new IGazeFilter[1]; gazeFilters = new IGazeFilter[1];
gazeFilters[0] = new GazeDecimator(60); //TODO: Refactor frequency passthrough gazeFilters[0] = new GazeDecimator(this); //TODO: Refactor frequency passthrough
//Chain filters //Chain filters
for(Int32 index= 0; index < gazeFilters.Length-1; index++) for(Int32 index= 0; index < gazeFilters.Length-1; index++)
...@@ -52,6 +52,7 @@ namespace TrackerBridge ...@@ -52,6 +52,7 @@ namespace TrackerBridge
{ {
foreach (IGazeFilter filter in gazeFilters) foreach (IGazeFilter filter in gazeFilters)
{ {
filter.Update(this);
filter.Reset(); filter.Reset();
} }
} }
...@@ -71,16 +72,5 @@ namespace TrackerBridge ...@@ -71,16 +72,5 @@ namespace TrackerBridge
{ {
gazeFilters[0].Input(input); 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();
}
}
}
} }
} }
...@@ -11,12 +11,14 @@ namespace TrackerBridge ...@@ -11,12 +11,14 @@ namespace TrackerBridge
public interface IBridgeTracker public interface IBridgeTracker
{ {
event ConnectionEventHandler ConnectionEvent;
event ConnectionEventHandler ConnectionTimeout;
event GazeDataHandler GazeDataAvailable; event GazeDataHandler GazeDataAvailable;
event EventHandler<Single> TrackingFrequencyChanged;
GazeDataProcessor GazeDataProcessor { get;} Single OutputFrequency { get; set; }
String SerialNumber { get; } String SerialNumber { get; }
Single TrackingFrequency { get; set; }
Single GetTrackingFrequency(); void Connect();
void SetTrackingFrequency(Single value);
} }
} }
...@@ -13,55 +13,55 @@ namespace TrackerBridge ...@@ -13,55 +13,55 @@ namespace TrackerBridge
public event ConnectionEventHandler ConnectionTimeout; public event ConnectionEventHandler ConnectionTimeout;
public event GazeDataHandler GazeDataAvailable { public event GazeDataHandler GazeDataAvailable {
add { add {
GazeDataProcessor.GazeDataProcessed += value; gazeDataProcessor.GazeDataProcessed += value;
} }
remove { remove {
GazeDataProcessor.GazeDataProcessed -= value; gazeDataProcessor.GazeDataProcessed -= value;
} }
} }
public event EventHandler<Single> TrackingFrequencyChanged;
private readonly GazeDataProcessor gazeDataProcessor;
private IEyeTracker eyeTracker = null; private IEyeTracker eyeTracker = null;
public GazeDataProcessor GazeDataProcessor { get; }
public Boolean IsConnected { get; private set; } = false; public Boolean IsConnected { get; private set; } = false;
public String SerialNumber { get; private set; } = null; public Single OutputFrequency {
get => gazeDataProcessor.OutputFrequency;
public TobiiEyeTracker() set => gazeDataProcessor.OutputFrequency = value;
{
GazeDataProcessor = new GazeDataProcessor(this);
}
public TobiiEyeTracker(String serialNumber) : this()
{
SerialNumber = serialNumber;
} }
public void Connect() public String SerialNumber { get; private set; } = null;
{ public Single TrackingFrequency {
Task task = new Task(() => InitiateConnection()); get {
task.Start();
}
public Single GetTrackingFrequency()
{
if (eyeTracker != null) if (eyeTracker != null)
{ {
return eyeTracker.GetGazeOutputFrequency(); return eyeTracker.GetGazeOutputFrequency();
} }
else else
{ {
throw new NullReferenceException(); return 0f;
} }
} }
set {
public void SetTrackingFrequency(float value)
{
if (eyeTracker != null && eyeTracker.GetAllGazeOutputFrequencies().Contains(value)) if (eyeTracker != null && eyeTracker.GetAllGazeOutputFrequencies().Contains(value))
{ {
eyeTracker.SetGazeOutputFrequency(value); eyeTracker.SetGazeOutputFrequency(value);
} }
} }
}
public TobiiEyeTracker()
{
gazeDataProcessor = new GazeDataProcessor();
}
public TobiiEyeTracker(String serialNumber) : this()
{
SerialNumber = serialNumber;
}
public void Connect()
{
Task task = new Task(() => InitiateConnection());
task.Start();
}
private void InitiateConnection() private void InitiateConnection()
{ {
DateTime time = DateTime.Now; DateTime time = DateTime.Now;
...@@ -98,16 +98,10 @@ namespace TrackerBridge ...@@ -98,16 +98,10 @@ namespace TrackerBridge
ConnectionTimeout?.Invoke(this); ConnectionTimeout?.Invoke(this);
} }
} }
eyeTracker.GazeDataReceived += GazeDataProcessor.Process; eyeTracker.GazeDataReceived += gazeDataProcessor.Process;
eyeTracker.GazeOutputFrequencyChanged += OnGazeOutputFrequencyChanged;
SerialNumber = eyeTracker.SerialNumber; SerialNumber = eyeTracker.SerialNumber;
SetTrackingFrequency(600f); TrackingFrequency = 600f;
ConnectionEvent?.Invoke(this); ConnectionEvent?.Invoke(this);
} }
private void OnGazeOutputFrequencyChanged(Object sender, GazeOutputFrequencyEventArgs e)
{
TrackingFrequencyChanged?.Invoke(this, e.GazeOutputFrequency);
}
} }
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment