WingMan – Blame information for rev 36

Subversion Repositories:
Rev:
Rev Author Line No. Line
10 office 1 using System;
2 using System.IO;
3 using System.Threading;
4 using System.Threading.Tasks;
19 office 5 using WindowsInput;
6 using WindowsInput.Native;
36 office 7 using ProtoBuf;
10 office 8 using WingMan.Communication;
14 office 9 using WingMan.Utilities;
10 office 10  
14 office 11 namespace WingMan.Bindings
10 office 12 {
13 public class KeySimulator : IDisposable
14 {
15 public delegate void MouseKeyBindingExecuting(object sender, KeyBindingExecutingEventArgs args);
16  
17 public KeySimulator(LocalKeyBindings localLocalKeyBindings, MqttCommunication mqttCommunication,
18 TaskScheduler formTaskScheduler, CancellationToken cancellationToken)
19 {
20 LocalLocalKeyBindings = localLocalKeyBindings;
21 MqttCommunication = mqttCommunication;
22 TaskScheduler = formTaskScheduler;
23 CancellationToken = cancellationToken;
24  
25 MqttCommunication.OnMessageReceived += OnMqttMessageReceived;
19 office 26  
27 InputSimulator = new InputSimulator();
10 office 28 }
29  
21 office 30 private InputSimulator InputSimulator { get; }
19 office 31  
10 office 32 private MqttCommunication MqttCommunication { get; }
33 private TaskScheduler TaskScheduler { get; }
34 private CancellationToken CancellationToken { get; }
35 private LocalKeyBindings LocalLocalKeyBindings { get; }
36  
37 public void Dispose()
38 {
39 MqttCommunication.OnMessageReceived -= OnMqttMessageReceived;
40 }
41  
42 public event MouseKeyBindingExecuting OnMouseKeyBindingExecuting;
43  
35 office 44 private async void OnMqttMessageReceived(object sender, MqttCommunicationMessageReceivedEventArgs e)
10 office 45 {
35 office 46 if (e.Topic != "execute")
10 office 47 return;
48  
35 office 49 using (var memoryStream = new MemoryStream())
10 office 50 {
35 office 51 await e.PayloadStream.CopyToAsync(memoryStream);
52  
53 memoryStream.Position = 0L;
54  
10 office 55 var executeMouseKeyBinding =
36 office 56 Serializer.Deserialize<ExecuteKeyBinding>(memoryStream);
10 office 57  
58 // Do not process own mouse key bindings.
59 if (!string.Equals(executeMouseKeyBinding.Nick, MqttCommunication.Nick, StringComparison.Ordinal))
60 return;
61  
62 await Task.Delay(0, CancellationToken)
63 .ContinueWith(
64 _ => OnMouseKeyBindingExecuting?.Invoke(sender,
65 new KeyBindingExecutingEventArgs(executeMouseKeyBinding.Nick,
66 executeMouseKeyBinding.Name)),
67 CancellationToken,
68 TaskContinuationOptions.None, TaskScheduler);
69  
21 office 70 #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
71 Task.Run(() => Simulate(executeMouseKeyBinding), CancellationToken);
72 #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
10 office 73 }
74 }
75  
20 office 76 private void Simulate(ExecuteKeyBinding executeBinding)
10 office 77 {
78 foreach (var localBinding in LocalLocalKeyBindings.Bindings)
79 {
80 if (!string.Equals(localBinding.Name, executeBinding.Name, StringComparison.Ordinal))
81 continue;
82  
24 office 83 // Skip any key bindings that are not enabled.
84 if (!localBinding.Enabled)
85 continue;
86  
22 office 87 // Key down
10 office 88 foreach (var key in localBinding.Keys)
89 {
21 office 90 if (!KeyConversion.StringToKeys.TryGetValue(key, out var press))
10 office 91 continue;
92  
22 office 93 InputSimulator.Keyboard.KeyDown((VirtualKeyCode) press);
19 office 94 }
22 office 95  
96 // Key up
97 foreach (var key in localBinding.Keys)
98 {
99 if (!KeyConversion.StringToKeys.TryGetValue(key, out var press))
100 continue;
101  
23 office 102 InputSimulator.Keyboard.KeyUp((VirtualKeyCode) press);
22 office 103 }
10 office 104 }
105 }
106 }
35 office 107 }