-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathExtPlaneInterface.cs
153 lines (120 loc) · 4.08 KB
/
ExtPlaneInterface.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
using System;
using System.Globalization;
using ExtPlaneNet.Commands;
using System.Net.Sockets;
using System.Threading.Tasks;
using System.Threading;
using ExtPlaneNet.InputProcessors;
namespace ExtPlaneNet
{
public class ExtPlaneInterface
{
public string Host { get; set; }
public int Port { get; set; }
public float UpdateInterval { get; set; }
protected readonly IDataRefRepository DataRefs = new DataRefRepository();
protected readonly ICommandQueue Commands = new CommandQueue();
protected readonly InputHandler InputHandler = new InputHandler();
protected TcpClient Socket { get; set; }
protected Task SenderTask { get; set; }
protected Task ReceiverTask { get; set; }
protected CancellationTokenSource CancellationSource { get; set; }
public ExtPlaneInterface(string host = "localhost", int port = 51000, float updateInterval = 0.33f)
{
Host = host;
Port = port;
UpdateInterval = updateInterval;
InputHandler.AddInputProcessor(new VersionProcessor());
InputHandler.AddInputProcessor(new DataRefProcessor(DataRefs));
}
public void Connect()
{
if (Socket != null)
throw new InvalidOperationException("Can't connect: already connected");
try
{
Socket = new TcpClient(Host, Port);
}
catch (SocketException)
{
Socket = null;
throw;
}
CancellationSource = new CancellationTokenSource();
SenderTask = Task.Factory.StartNew(() => new Sender(Socket.GetStream(), Commands, CancellationSource.Token).Run(), CancellationSource.Token);
ReceiverTask = Task.Factory.StartNew(() => new Receiver(Socket.GetStream(), InputHandler, CancellationSource.Token).Run(), CancellationSource.Token);
}
public void Disconnect()
{
CancellationSource.Cancel();
if (SenderTask != null)
{
SenderTask.Wait();
SenderTask = null;
}
if (ReceiverTask != null)
{
ReceiverTask.Wait();
ReceiverTask = null;
}
if (Socket != null)
{
Socket.Close();
Socket = null;
}
}
public void Subscribe<T>(string dataRef, float accuracy = 0.0f, Action<DataRef<T>> changed = null)
{
if (string.IsNullOrWhiteSpace(dataRef))
throw new ArgumentNullException("dataRef");
if (DataRefs.Contains(dataRef))
throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Can't subscribe to dataref: dataref {0} already subscribed to", dataRef));
var refObj = new DataRef<T>(dataRef, accuracy);
if (changed != null)
refObj.Changed += (o, e) => changed(e);
DataRefs.Add<T>(refObj);
Commands.Enqueue(new SubscribeCommand(dataRef, accuracy));
}
public void Unsubscribe(string dataRef)
{
if (string.IsNullOrWhiteSpace(dataRef))
throw new ArgumentNullException("dataRef");
DataRefs.Remove(dataRef);
Commands.Enqueue(new UnsubscribeCommand(dataRef));
}
public DataRef<T> GetDataRef<T>(string dataRef)
{
if (string.IsNullOrWhiteSpace(dataRef))
throw new ArgumentNullException("dataRef");
if (!DataRefs.Contains(dataRef))
throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Can't get dataref value: dataref {0} isn't subscribed to", dataRef));
return DataRefs.Get<T>(dataRef);
}
public void SetDataRef<T>(string dataRef, T value)
{
if (string.IsNullOrWhiteSpace(dataRef))
throw new ArgumentNullException("dataRef");
if (!DataRefs.Contains(dataRef))
throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Can't set dataref value: dataref {0} isn't subscribed to", dataRef));
Commands.Enqueue(new SetDataRefCommand<T>(dataRef, value));
}
public void PressKey(int keyId)
{
Commands.Enqueue(new KeyStrokeCommand(keyId));
}
public void PressButton(int buttonId)
{
Commands.Enqueue(new ButtonPressCommand(buttonId));
}
public void ReleaseButton(int buttonId)
{
Commands.Enqueue(new ButtonReleaseCommand(buttonId));
}
public void SendCommand(string command, CommandType commandType)
{
if (string.IsNullOrWhiteSpace(command))
throw new ArgumentNullException("dataRef");
Commands.Enqueue(new XPlaneCommand(command, commandType));
}
}
}