WingMan – Rev 5
?pathlinks?
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MQTTnet;
using MQTTnet.Extensions.ManagedClient;
using WingMan.Communication;
namespace WingMan.MouseKey
{
public class MouseKeyBindingsSynchronizer
{
public delegate void MouseKeyBindingsSynchronized(object sender, MouseKeyBindingsSynchronizedEventArgs e);
public event MouseKeyBindingsSynchronized OnMouseKeyBindingsSynchronized;
private MouseKeyBindings MouseKeyBindings { get; set; }
private ConcurrentDictionary<string, List<MouseKeyBindingExchange>> SynchronizedMouseKeyBindings { get; set; }
private MQTTCommunication MQTTCommunication { get; set; }
private CancellationTokenSource SynchronizationCancellationTokenSource { get; set; }
public MouseKeyBindingsSynchronizer(MouseKeyBindings mouseKeyBindings, MQTTCommunication MQTTCommunication)
{
MouseKeyBindings = mouseKeyBindings;
this.MQTTCommunication = MQTTCommunication;
SynchronizedMouseKeyBindings = new ConcurrentDictionary<string, List<MouseKeyBindingExchange>>();
MQTTCommunication.OnMessageReceived += MqttCommunicationOnOnMessageReceived;
SynchronizationCancellationTokenSource = new CancellationTokenSource();
Task.Run(Synchronize, SynchronizationCancellationTokenSource.Token);
}
private 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 = (MouseKeyBindingsExchange)MouseKeyBindingsExchange.XmlSerializer.Deserialize(memoryStream);
if (SynchronizedMouseKeyBindings.TryGetValue(mouseKeyBindingsExchange.Nick, out var mouseKeyBinding) &&
mouseKeyBinding.SequenceEqual(mouseKeyBindingsExchange.ExchangeBindings))
return;
// Nick does not exist so the bindings will be added.
SynchronizedMouseKeyBindings.AddOrUpdate(mouseKeyBindingsExchange.Nick,
mouseKeyBindingsExchange.ExchangeBindings, (s, list) => mouseKeyBindingsExchange.ExchangeBindings);
OnMouseKeyBindingsSynchronized?.Invoke(sender,
new MouseKeyBindingsSynchronizedEventArgs(
mouseKeyBindingsExchange.ExchangeBindings));
}
}
private async Task Synchronize()
{
do
{
await Task.Delay(1000).ConfigureAwait(false);
if (!MouseKeyBindings.Bindings.Any())
continue;
using (var memoryStream = new MemoryStream())
{
MouseKeyBindingsExchange.XmlSerializer.Serialize(memoryStream, new MouseKeyBindingsExchange(MQTTCommunication.Nick, MouseKeyBindings));
memoryStream.Position = 0L;
await MQTTCommunication.Broadcast("exchange", memoryStream.ToArray()).ConfigureAwait(false);
}
} while (!SynchronizationCancellationTokenSource.Token.IsCancellationRequested);
}
}
}