/trunk/WingMan/MouseKey/MouseKeyBinding.cs |
@@ -0,0 +1,48 @@ |
using System; |
using System.Collections.Generic; |
using System.Linq; |
|
namespace WingMan.MouseKey |
{ |
public class MouseKeyBinding : IEquatable<MouseKeyBinding> |
{ |
public MouseKeyBinding() |
{ |
} |
|
public MouseKeyBinding(string name, List<string> keys) : this() |
{ |
Name = name; |
Keys = keys; |
} |
|
public string DisplayName => $"{Name} ({string.Join(" + ", Keys.ToArray())})"; |
|
public string Name { get; set; } = string.Empty; |
|
public List<string> Keys { get; set; } = new List<string>(); |
|
public bool Equals(MouseKeyBinding other) |
{ |
if (ReferenceEquals(null, other)) return false; |
if (ReferenceEquals(this, other)) return true; |
return string.Equals(Name, other.Name) && Keys.SequenceEqual(other.Keys); |
} |
|
public override bool Equals(object obj) |
{ |
if (ReferenceEquals(null, obj)) return false; |
if (ReferenceEquals(this, obj)) return true; |
if (obj.GetType() != GetType()) return false; |
return Equals((MouseKeyBinding) obj); |
} |
|
public override int GetHashCode() |
{ |
unchecked |
{ |
return ((Name != null ? Name.GetHashCode() : 0) * 397) ^ (Keys != null ? Keys.GetHashCode() : 0); |
} |
} |
} |
} |
/trunk/WingMan/MouseKey/MouseKeyBindingsSynchronizer.cs |
@@ -0,0 +1,92 @@ |
using System.Collections.Concurrent; |
using System.Collections.Generic; |
using System.IO; |
using System.Linq; |
using System.Threading; |
using System.Threading.Tasks; |
using MQTTnet; |
using WingMan.Communication; |
|
namespace WingMan.MouseKey |
{ |
public class MouseKeyBindingsSynchronizer |
{ |
public delegate void MouseKeyBindingsSynchronized(object sender, MouseKeyBindingsSynchronizedEventArgs e); |
|
public MouseKeyBindingsSynchronizer(MouseKeyBindings mouseKeyBindings, MqttCommunication mqttCommunication, |
TaskScheduler taskScheduler, CancellationToken cancellationToken) |
{ |
MouseKeyBindings = mouseKeyBindings; |
MqttCommunication = mqttCommunication; |
CancellationToken = cancellationToken; |
TaskScheduler = taskScheduler; |
|
SynchronizedMouseKeyBindings = new ConcurrentDictionary<string, List<MouseKeyBinding>>(); |
|
mqttCommunication.OnMessageReceived += MqttCommunicationOnOnMessageReceived; |
|
Task.Run(Synchronize, CancellationToken); |
} |
|
private MouseKeyBindings MouseKeyBindings { get; } |
|
private ConcurrentDictionary<string, List<MouseKeyBinding>> SynchronizedMouseKeyBindings { get; } |
|
private MqttCommunication MqttCommunication { get; } |
|
private CancellationToken CancellationToken { get; } |
private TaskScheduler TaskScheduler { get; } |
public event MouseKeyBindingsSynchronized OnMouseKeyBindingsSynchronized; |
|
private async void MqttCommunicationOnOnMessageReceived(object sender, |
MqttApplicationMessageReceivedEventArgs e) |
{ |
if (e.ApplicationMessage.Topic != "exchange") |
return; |
|
using (var memoryStream = new MemoryStream(e.ApplicationMessage.Payload)) |
{ |
memoryStream.Position = 0L; |
|
var mouseKeyBindingsExchange = |
(MouseKeyBindingExchange) MouseKeyBindingExchange.XmlSerializer.Deserialize(memoryStream); |
|
if (SynchronizedMouseKeyBindings.TryGetValue(mouseKeyBindingsExchange.Nick, out var mouseKeyBinding) && |
mouseKeyBinding.SequenceEqual(mouseKeyBindingsExchange.MouseKeyBindings)) |
return; |
|
// Nick does not exist so the bindings will be added. |
SynchronizedMouseKeyBindings.AddOrUpdate(mouseKeyBindingsExchange.Nick, |
mouseKeyBindingsExchange.MouseKeyBindings, (s, list) => mouseKeyBindingsExchange.MouseKeyBindings); |
|
await Task.Delay(0) |
.ContinueWith( |
_ => OnMouseKeyBindingsSynchronized?.Invoke(sender, |
new MouseKeyBindingsSynchronizedEventArgs( |
mouseKeyBindingsExchange)), |
CancellationToken, TaskContinuationOptions.None, TaskScheduler); |
} |
} |
|
private async Task Synchronize() |
{ |
do |
{ |
await Task.Delay(1000, CancellationToken).ConfigureAwait(false); |
|
if (!MqttCommunication.Running) |
continue; |
|
using (var memoryStream = new MemoryStream()) |
{ |
MouseKeyBindingExchange.XmlSerializer.Serialize(memoryStream, |
new MouseKeyBindingExchange(MqttCommunication.Nick, MouseKeyBindings.Bindings)); |
|
memoryStream.Position = 0L; |
|
await MqttCommunication.Broadcast("exchange", memoryStream.ToArray()).ConfigureAwait(false); |
} |
} while (!CancellationToken.IsCancellationRequested); |
} |
} |
} |