/trunk/WingMan/Bindings/KeySimulator.cs |
@@ -0,0 +1,92 @@ |
using System; |
using System.IO; |
using System.Threading; |
using System.Threading.Tasks; |
using MQTTnet; |
using SimWinInput; |
using WingMan.Communication; |
using WingMan.Utilities; |
|
namespace WingMan.Bindings |
{ |
public class KeySimulator : IDisposable |
{ |
public delegate void MouseKeyBindingExecuting(object sender, KeyBindingExecutingEventArgs args); |
|
public KeySimulator(LocalKeyBindings localLocalKeyBindings, MqttCommunication mqttCommunication, |
TaskScheduler formTaskScheduler, CancellationToken cancellationToken) |
{ |
LocalLocalKeyBindings = localLocalKeyBindings; |
MqttCommunication = mqttCommunication; |
TaskScheduler = formTaskScheduler; |
CancellationToken = cancellationToken; |
|
MqttCommunication.OnMessageReceived += OnMqttMessageReceived; |
} |
|
private MqttCommunication MqttCommunication { get; } |
private TaskScheduler TaskScheduler { get; } |
private CancellationToken CancellationToken { get; } |
private LocalKeyBindings LocalLocalKeyBindings { get; } |
|
public void Dispose() |
{ |
MqttCommunication.OnMessageReceived -= OnMqttMessageReceived; |
} |
|
public event MouseKeyBindingExecuting OnMouseKeyBindingExecuting; |
|
private async void OnMqttMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e) |
{ |
if (e.ApplicationMessage.Topic != "execute") |
return; |
|
using (var memoryStream = new MemoryStream(e.ApplicationMessage.Payload)) |
{ |
var executeMouseKeyBinding = |
(ExecuteKeyBinding) ExecuteKeyBinding.XmlSerializer.Deserialize(memoryStream); |
|
// Do not process own mouse key bindings. |
if (!string.Equals(executeMouseKeyBinding.Nick, MqttCommunication.Nick, StringComparison.Ordinal)) |
return; |
|
await Task.Delay(0, CancellationToken) |
.ContinueWith( |
_ => OnMouseKeyBindingExecuting?.Invoke(sender, |
new KeyBindingExecutingEventArgs(executeMouseKeyBinding.Nick, |
executeMouseKeyBinding.Name)), |
CancellationToken, |
TaskContinuationOptions.None, TaskScheduler); |
|
Simulate(executeMouseKeyBinding); |
} |
} |
|
private void Simulate(ExecuteKeyBinding executeBinding) |
{ |
foreach (var localBinding in LocalLocalKeyBindings.Bindings) |
{ |
if (!string.Equals(localBinding.Name, executeBinding.Name, StringComparison.Ordinal)) |
continue; |
|
// Press |
foreach (var key in localBinding.Keys) |
{ |
if (!KeyConversion.StringToKeys.TryGetValue(key, out var pressKey)) |
continue; |
|
SimKeyboard.KeyDown(pressKey); |
} |
|
// Depress |
foreach (var key in localBinding.Keys) |
{ |
if (!KeyConversion.StringToKeys.TryGetValue(key, out var pressKey)) |
continue; |
|
SimKeyboard.KeyUp(pressKey); |
} |
} |
} |
} |
} |