WingMan – Blame information for rev 10
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
10 | office | 1 | using System; |
2 | using System.Collections.Concurrent; |
||
5 | office | 3 | using System.Collections.Generic; |
4 | using System.IO; |
||
5 | using System.Linq; |
||
6 | using System.Threading; |
||
7 | using System.Threading.Tasks; |
||
8 | using MQTTnet; |
||
9 | using WingMan.Communication; |
||
10 | |||
11 | namespace WingMan.MouseKey |
||
12 | { |
||
10 | office | 13 | public class KeyBindingsSynchronizer : IDisposable |
5 | office | 14 | { |
10 | office | 15 | public delegate void MouseKeyBindingsSynchronized(object sender, KeyBindingsSynchronizerEventArgs e); |
5 | office | 16 | |
10 | office | 17 | public KeyBindingsSynchronizer(LocalKeyBindings localKeyBindings, MqttCommunication mqttCommunication, |
7 | office | 18 | TaskScheduler taskScheduler, CancellationToken cancellationToken) |
5 | office | 19 | { |
10 | office | 20 | LocalKeyBindings = localKeyBindings; |
9 | office | 21 | MqttCommunication = mqttCommunication; |
7 | office | 22 | CancellationToken = cancellationToken; |
23 | TaskScheduler = taskScheduler; |
||
5 | office | 24 | |
10 | office | 25 | SynchronizedMouseKeyBindings = new ConcurrentDictionary<string, List<KeyBinding>>(); |
5 | office | 26 | |
10 | office | 27 | MqttCommunication.OnMessageReceived += MqttCommunicationOnMessageReceived; |
5 | office | 28 | |
10 | office | 29 | Task.Run(PeriodicSynchronize, CancellationToken); |
5 | office | 30 | } |
31 | |||
10 | office | 32 | private LocalKeyBindings LocalKeyBindings { get; } |
7 | office | 33 | |
10 | office | 34 | private ConcurrentDictionary<string, List<KeyBinding>> SynchronizedMouseKeyBindings { get; } |
7 | office | 35 | |
9 | office | 36 | private MqttCommunication MqttCommunication { get; } |
7 | office | 37 | |
38 | private CancellationToken CancellationToken { get; } |
||
39 | private TaskScheduler TaskScheduler { get; } |
||
10 | office | 40 | |
41 | public void Dispose() |
||
42 | { |
||
43 | MqttCommunication.OnMessageReceived -= MqttCommunicationOnMessageReceived; |
||
44 | } |
||
45 | |||
7 | office | 46 | public event MouseKeyBindingsSynchronized OnMouseKeyBindingsSynchronized; |
47 | |||
10 | office | 48 | private async void MqttCommunicationOnMessageReceived(object sender, |
7 | office | 49 | MqttApplicationMessageReceivedEventArgs e) |
5 | office | 50 | { |
51 | if (e.ApplicationMessage.Topic != "exchange") |
||
52 | return; |
||
53 | |||
54 | using (var memoryStream = new MemoryStream(e.ApplicationMessage.Payload)) |
||
55 | { |
||
56 | memoryStream.Position = 0L; |
||
57 | |||
7 | office | 58 | var mouseKeyBindingsExchange = |
10 | office | 59 | (KeyBindingExchange) KeyBindingExchange.XmlSerializer.Deserialize(memoryStream); |
5 | office | 60 | |
10 | office | 61 | // Do not add own bindings. |
62 | if (string.Equals(mouseKeyBindingsExchange.Nick, MqttCommunication.Nick)) |
||
63 | return; |
||
64 | |||
5 | office | 65 | if (SynchronizedMouseKeyBindings.TryGetValue(mouseKeyBindingsExchange.Nick, out var mouseKeyBinding) && |
10 | office | 66 | mouseKeyBinding.SequenceEqual(mouseKeyBindingsExchange.KeyBindings)) |
5 | office | 67 | return; |
68 | |||
7 | office | 69 | await Task.Delay(0) |
70 | .ContinueWith( |
||
71 | _ => OnMouseKeyBindingsSynchronized?.Invoke(sender, |
||
10 | office | 72 | new KeyBindingsSynchronizerEventArgs( |
7 | office | 73 | mouseKeyBindingsExchange)), |
74 | CancellationToken, TaskContinuationOptions.None, TaskScheduler); |
||
10 | office | 75 | |
76 | // Nick does not exist so the bindings will be added. |
||
77 | SynchronizedMouseKeyBindings.AddOrUpdate(mouseKeyBindingsExchange.Nick, |
||
78 | mouseKeyBindingsExchange.KeyBindings, (s, list) => mouseKeyBindingsExchange.KeyBindings); |
||
5 | office | 79 | } |
80 | } |
||
81 | |||
10 | office | 82 | private async Task PeriodicSynchronize() |
5 | office | 83 | { |
84 | do |
||
85 | { |
||
10 | office | 86 | await Task.Delay(1000, CancellationToken); |
5 | office | 87 | |
9 | office | 88 | if (!MqttCommunication.Running) |
5 | office | 89 | continue; |
90 | |||
91 | using (var memoryStream = new MemoryStream()) |
||
92 | { |
||
10 | office | 93 | KeyBindingExchange.XmlSerializer.Serialize(memoryStream, |
94 | new KeyBindingExchange(MqttCommunication.Nick, LocalKeyBindings.Bindings)); |
||
5 | office | 95 | |
96 | memoryStream.Position = 0L; |
||
97 | |||
10 | office | 98 | await MqttCommunication.Broadcast("exchange", memoryStream.ToArray()); |
5 | office | 99 | } |
7 | office | 100 | } while (!CancellationToken.IsCancellationRequested); |
5 | office | 101 | } |
102 | } |
||
103 | } |