8 |
8 |
|
9 |
9 |
namespace DeltaRobotVr
|
10 |
10 |
{
|
|
11 |
|
|
12 |
/// <summary>
|
|
13 |
/// Singleton class responsible for communication with the Deltarobot server.
|
|
14 |
/// </summary>
|
11 |
15 |
public sealed class Client
|
12 |
16 |
{
|
13 |
17 |
// singleton instance
|
... | ... | |
63 |
67 |
private long _curveCounter = 0;
|
64 |
68 |
|
65 |
69 |
private volatile bool _isConnected;
|
66 |
|
private volatile string _eotMsg = string.Empty;
|
|
70 |
private volatile string _eotReason = string.Empty;
|
67 |
71 |
|
68 |
72 |
private readonly object _reconnectTimeLock = new object();
|
69 |
73 |
private DateTime _reconnectTime = DateTime.Now;
|
... | ... | |
76 |
80 |
{
|
77 |
81 |
}
|
78 |
82 |
|
|
83 |
/// <summary>
|
|
84 |
/// Starts the client thread and connects to the server.
|
|
85 |
/// </summary>
|
79 |
86 |
public void Start()
|
80 |
87 |
{
|
81 |
88 |
IsRunning = true;
|
... | ... | |
83 |
90 |
_thread.Start();
|
84 |
91 |
}
|
85 |
92 |
|
|
93 |
/// <summary>
|
|
94 |
/// Gracefully stops the client thread. Blocks until the thread actually stops.
|
|
95 |
/// </summary>
|
86 |
96 |
public void Stop()
|
87 |
97 |
{
|
88 |
98 |
IsRunning = false;
|
... | ... | |
93 |
103 |
}
|
94 |
104 |
}
|
95 |
105 |
|
96 |
|
public string EotMsg
|
|
106 |
/// <summary>
|
|
107 |
/// Contains a reason received in an end-of-transmission message.
|
|
108 |
/// </summary>
|
|
109 |
public string EotReason
|
97 |
110 |
{
|
98 |
|
get => _eotMsg;
|
99 |
|
private set => _eotMsg = value;
|
|
111 |
get => _eotReason;
|
|
112 |
private set => _eotReason = value;
|
100 |
113 |
}
|
101 |
114 |
|
|
115 |
/// <summary>
|
|
116 |
/// Whether the client is currently maintaining an active connection to the server.
|
|
117 |
/// </summary>
|
102 |
118 |
public bool IsConnected
|
103 |
119 |
{
|
104 |
120 |
get => _isConnected;
|
105 |
121 |
private set => _isConnected = value;
|
106 |
122 |
}
|
107 |
123 |
|
|
124 |
/// <summary>
|
|
125 |
/// Current position of the actuator (in server's world space).
|
|
126 |
/// </summary>
|
108 |
127 |
public Single3 ActuatorPosition
|
109 |
128 |
{
|
110 |
129 |
get
|
... | ... | |
123 |
142 |
}
|
124 |
143 |
}
|
125 |
144 |
|
126 |
|
public Single3 CurrentDirectionVector
|
|
145 |
/// <summary>
|
|
146 |
/// The actual direction the actuator is currently moving in.
|
|
147 |
/// </summary>
|
|
148 |
public Single3 ActualDirectionVector
|
127 |
149 |
{
|
128 |
150 |
get
|
129 |
151 |
{
|
... | ... | |
141 |
163 |
}
|
142 |
164 |
}
|
143 |
165 |
|
144 |
|
public Single3 DesiredDirectionVector
|
|
166 |
/// <summary>
|
|
167 |
/// The target direction the actuator should be moving in so that it draws the curve.
|
|
168 |
/// </summary>
|
|
169 |
public Single3 TargetDirectionVector
|
145 |
170 |
{
|
146 |
171 |
get
|
147 |
172 |
{
|
... | ... | |
159 |
184 |
}
|
160 |
185 |
}
|
161 |
186 |
|
|
187 |
/// <summary>
|
|
188 |
/// The current exercise curve.
|
|
189 |
/// </summary>
|
162 |
190 |
public Single3[] Curve
|
163 |
191 |
{
|
164 |
192 |
get
|
... | ... | |
177 |
205 |
}
|
178 |
206 |
}
|
179 |
207 |
|
|
208 |
/// <summary>
|
|
209 |
/// A counter used to determine whether the curve has changed. The curve remains the same while the counter is
|
|
210 |
/// the same.
|
|
211 |
/// </summary>
|
180 |
212 |
public long CurveCounter
|
181 |
213 |
{
|
182 |
214 |
get
|
... | ... | |
195 |
227 |
}
|
196 |
228 |
}
|
197 |
229 |
|
|
230 |
/// <summary>
|
|
231 |
/// Whether the client thread should keep on reading data from the server.
|
|
232 |
/// </summary>
|
198 |
233 |
public bool IsRunning
|
199 |
234 |
{
|
200 |
235 |
get {
|
... | ... | |
212 |
247 |
}
|
213 |
248 |
}
|
214 |
249 |
|
|
250 |
/// <summary>
|
|
251 |
/// The time at which the client will attempt to reconnect to the server again.
|
|
252 |
/// </summary>
|
215 |
253 |
public DateTime ReconnectTime
|
216 |
254 |
{
|
217 |
255 |
get
|
... | ... | |
230 |
268 |
}
|
231 |
269 |
}
|
232 |
270 |
|
|
271 |
/// <summary>
|
|
272 |
/// The client thread function.
|
|
273 |
/// </summary>
|
233 |
274 |
private void ThreadProcedure()
|
234 |
275 |
{
|
235 |
276 |
while (IsRunning)
|
... | ... | |
294 |
335 |
ProcessEot(reader);
|
295 |
336 |
break;
|
296 |
337 |
case CurrentActuatorPositionId:
|
297 |
|
ProcessCurrentActuatorPosition(reader);
|
|
338 |
ProcessActuatorPosition(reader);
|
298 |
339 |
break;
|
299 |
340 |
case CurrentDirectionVectorId:
|
300 |
|
ProcessCurrentDirectionVector(reader);
|
|
341 |
ProcessActualDirectionVector(reader);
|
301 |
342 |
break;
|
302 |
343 |
case DesiredDirectionVectorId:
|
303 |
|
ProcessDesiredDirectionVector(reader);
|
|
344 |
ProcessTargetDirectionVector(reader);
|
304 |
345 |
break;
|
305 |
346 |
case CurveId:
|
306 |
347 |
ProcessCurve(reader);
|
... | ... | |
373 |
414 |
reader.ReadBytes((int) numberOfBytes);
|
374 |
415 |
}
|
375 |
416 |
|
376 |
|
private void ProcessCurrentActuatorPosition(BinaryReader reader)
|
|
417 |
private void ProcessActuatorPosition(BinaryReader reader)
|
377 |
418 |
{
|
378 |
419 |
var x = reader.ReadSingle();
|
379 |
420 |
var y = reader.ReadSingle();
|
... | ... | |
383 |
424 |
ActuatorPosition = new Single3(x, y, z);
|
384 |
425 |
}
|
385 |
426 |
|
386 |
|
private void ProcessCurrentDirectionVector(BinaryReader reader)
|
|
427 |
private void ProcessActualDirectionVector(BinaryReader reader)
|
387 |
428 |
{
|
388 |
429 |
var x = reader.ReadSingle();
|
389 |
430 |
var y = reader.ReadSingle();
|
390 |
431 |
var z = reader.ReadSingle();
|
391 |
432 |
reader.ReadSingle(); // skip unused
|
392 |
433 |
|
393 |
|
CurrentDirectionVector = new Single3(x, y, z);
|
|
434 |
ActualDirectionVector = new Single3(x, y, z);
|
394 |
435 |
}
|
395 |
436 |
|
396 |
|
private void ProcessDesiredDirectionVector(BinaryReader reader)
|
|
437 |
private void ProcessTargetDirectionVector(BinaryReader reader)
|
397 |
438 |
{
|
398 |
439 |
var x = reader.ReadSingle();
|
399 |
440 |
var y = reader.ReadSingle();
|
400 |
441 |
var z = reader.ReadSingle();
|
401 |
442 |
reader.ReadSingle(); // skip unused
|
402 |
443 |
|
403 |
|
DesiredDirectionVector = new Single3(x, y, z);
|
|
444 |
TargetDirectionVector = new Single3(x, y, z);
|
404 |
445 |
}
|
405 |
446 |
|
406 |
447 |
private void ProcessCurve(BinaryReader reader)
|
... | ... | |
428 |
469 |
{
|
429 |
470 |
UInt32 numberOfBytes = reader.ReadUInt32();
|
430 |
471 |
Byte[] buffer = reader.ReadBytes((int) numberOfBytes);
|
431 |
|
EotMsg = Encoding.ASCII.GetString(buffer);
|
|
472 |
EotReason = Encoding.ASCII.GetString(buffer);
|
432 |
473 |
IsConnected = false;
|
433 |
474 |
}
|
434 |
475 |
|
Re #8906 - Client refactor + doc comments (2)