-
Notifications
You must be signed in to change notification settings - Fork 1
/
OSDInterface.cs
108 lines (91 loc) · 3.3 KB
/
OSDInterface.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
using System.Diagnostics;
namespace INAV_SIM_OSD
{
internal class OSDInterface
{
private readonly Dictionary<string, string> PROCESS_NAMES = new Dictionary<string, string>()
{
{"RealFlight64", "RealFlight" },
{"RealFlight", "RealFlight" },
{"X-Plane", "X-Plane" }
};
private SynchronizationContext? _synchronizationContext;
private readonly TaskScheduler _scheduler;
private CancellationTokenSource _cts;
private readonly MSP _msp;
private OSD? _osd;
public event EventHandler? Disconnect;
public OSDInterface()
{
_scheduler = TaskScheduler.Default;
_synchronizationContext = SynchronizationContext.Current;
_cts = new();
_msp = new();
_msp.FrameReceived += Msp_FrameReceived;
}
protected virtual void OnDisconnect()
{
Disconnect?.Invoke(this, EventArgs.Empty);
}
private void Msp_FrameReceived(object? sender, EventArgs e)
{
if (_msp.ReceivedFrame.State == MSP.State.COMMAND_RECEIVED && _msp.ReceivedFrame.Command == MSP.MSP_DISPLAYPORT)
_osd?.Decode(_msp.ReceivedFrame.Buffer, _msp.ReceivedFrame.DataSize);
}
public async Task StartAsync(string? connection, string? font)
{
if (string.IsNullOrEmpty(connection))
throw new ArgumentNullException(nameof(connection));
if (string.IsNullOrEmpty(font))
throw new ArgumentNullException(nameof(font));
_cts = new CancellationTokenSource();
Process? procces;
try
{
procces = Process.GetProcesses().Where(p => PROCESS_NAMES.ContainsKey(p.ProcessName)).First();
}
catch
{
throw new Exception("Unable to detect simulator.");
}
_osd = new(procces.MainWindowHandle)
{
FontName = font
};
_ = Task.Factory.StartNew(() =>
{
_osd.Run(_scheduler);
}, _cts.Token, TaskCreationOptions.LongRunning, _scheduler);
_msp.SetConnection(connection);
_msp.Open();
await Task.Factory.StartNew(() =>
{
DateTime start = DateTime.Now;
while (!_cts.IsCancellationRequested)
{
try
{
if (DateTime.Now - start > TimeSpan.FromMilliseconds(125))
{
_msp.SendReceive(_cts.Token);
_osd.Show = true;
}
}
catch
{
_osd.Show = false;
Stop();
_synchronizationContext?.Post(new SendOrPostCallback(_ => OnDisconnect()), null);
break;
}
}
}, _cts.Token, TaskCreationOptions.LongRunning, _scheduler);
}
public void Stop()
{
_cts.Cancel();
_osd?.Close();
_msp.ClosePort();
}
}
}