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