WingMan – Blame information for rev 36
?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; |
||
36 | office | 8 | using ProtoBuf; |
5 | office | 9 | using WingMan.Communication; |
10 | |||
14 | office | 11 | namespace WingMan.Bindings |
5 | office | 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 | |
36 | office | 25 | SynchronizedMouseKeyBindings = new ConcurrentDictionary<string, List<string>>(); |
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 | |
36 | office | 34 | private ConcurrentDictionary<string, List<string>> 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, |
35 | office | 49 | MqttCommunicationMessageReceivedEventArgs e) |
5 | office | 50 | { |
35 | office | 51 | if (e.Topic != "exchange") |
5 | office | 52 | return; |
53 | |||
35 | office | 54 | using (var memoryStream = new MemoryStream()) |
5 | office | 55 | { |
35 | office | 56 | await e.PayloadStream.CopyToAsync(memoryStream); |
57 | |||
5 | office | 58 | memoryStream.Position = 0L; |
59 | |||
7 | office | 60 | var mouseKeyBindingsExchange = |
36 | office | 61 | Serializer.Deserialize<KeyBindingExchange>(memoryStream); |
5 | office | 62 | |
10 | office | 63 | // Do not add own bindings. |
64 | if (string.Equals(mouseKeyBindingsExchange.Nick, MqttCommunication.Nick)) |
||
65 | return; |
||
66 | |||
5 | office | 67 | if (SynchronizedMouseKeyBindings.TryGetValue(mouseKeyBindingsExchange.Nick, out var mouseKeyBinding) && |
10 | office | 68 | mouseKeyBinding.SequenceEqual(mouseKeyBindingsExchange.KeyBindings)) |
5 | office | 69 | return; |
70 | |||
7 | office | 71 | await Task.Delay(0) |
72 | .ContinueWith( |
||
73 | _ => OnMouseKeyBindingsSynchronized?.Invoke(sender, |
||
10 | office | 74 | new KeyBindingsSynchronizerEventArgs( |
7 | office | 75 | mouseKeyBindingsExchange)), |
76 | CancellationToken, TaskContinuationOptions.None, TaskScheduler); |
||
10 | office | 77 | |
78 | // Nick does not exist so the bindings will be added. |
||
79 | SynchronizedMouseKeyBindings.AddOrUpdate(mouseKeyBindingsExchange.Nick, |
||
80 | mouseKeyBindingsExchange.KeyBindings, (s, list) => mouseKeyBindingsExchange.KeyBindings); |
||
5 | office | 81 | } |
82 | } |
||
83 | |||
10 | office | 84 | private async Task PeriodicSynchronize() |
5 | office | 85 | { |
86 | do |
||
87 | { |
||
10 | office | 88 | await Task.Delay(1000, CancellationToken); |
5 | office | 89 | |
9 | office | 90 | if (!MqttCommunication.Running) |
5 | office | 91 | continue; |
92 | |||
93 | using (var memoryStream = new MemoryStream()) |
||
94 | { |
||
36 | office | 95 | Serializer.Serialize(memoryStream, |
96 | new KeyBindingExchange(MqttCommunication.Nick, |
||
97 | LocalKeyBindings.Bindings.Select(binding => binding.Name).ToList())); |
||
5 | office | 98 | |
99 | memoryStream.Position = 0L; |
||
100 | |||
10 | office | 101 | await MqttCommunication.Broadcast("exchange", memoryStream.ToArray()); |
5 | office | 102 | } |
7 | office | 103 | } while (!CancellationToken.IsCancellationRequested); |
5 | office | 104 | } |
105 | } |
||
35 | office | 106 | } |