WingMan

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 4  →  ?path2? @ 5
/trunk/WingMan/MouseKey/MouseKeyBinding.cs
@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace WingMan
{
public class 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>();
}
}
/trunk/WingMan/MouseKey/MouseKeyBindingExchange.cs
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace WingMan.MouseKey
{
public class MouseKeyBindingExchange
{
public string Nick { get; set; }
 
public List<string> Names { get; set; }
}
}
/trunk/WingMan/MouseKey/MouseKeyBindings.cs
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
 
namespace WingMan
{
public class MouseKeyBindings
{
public MouseKeyBindings()
{
 
}
public MouseKeyBindings(List<MouseKeyBinding> bindings) : this()
{
Bindings = bindings;
}
 
public List<MouseKeyBinding> Bindings { get; set; }
}
}
/trunk/WingMan/MouseKey/MouseKeyBindingsExchange.cs
@@ -0,0 +1,31 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
using WingMan.MouseKey;
 
namespace WingMan
{
public class MouseKeyBindingsExchange
{
[XmlIgnore] public static readonly XmlSerializer XmlSerializer =
new XmlSerializer(typeof(MouseKeyBindingsExchange));
 
public MouseKeyBindingsExchange()
{
}
 
public MouseKeyBindingsExchange(string nick, MouseKeyBindings mouseKeyBindings) : this()
{
Nick = nick;
ExchangeBindings.Add(new MouseKeyBindingExchange
{
Nick = Nick,
Names = mouseKeyBindings.Bindings.Select(binding => binding.Name).ToList()
});
}
 
public string Nick { get; set; } = string.Empty;
 
public List<MouseKeyBindingExchange> ExchangeBindings { get; set; } = new List<MouseKeyBindingExchange>();
}
}
/trunk/WingMan/MouseKey/MouseKeyBindingsSynchronizedEventArgs.cs
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace WingMan.MouseKey
{
public class MouseKeyBindingsSynchronizedEventArgs : EventArgs
{
public List<MouseKeyBindingExchange> ExchangeBindings { get; set; }
 
public MouseKeyBindingsSynchronizedEventArgs(List<MouseKeyBindingExchange> mouseKeyExchangeBindings)
{
ExchangeBindings = mouseKeyExchangeBindings;
}
}
}
/trunk/WingMan/MouseKey/MouseKeyBindingsSynchronizer.cs
@@ -0,0 +1,88 @@
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);
}
}
}