HamBook – Blame information for rev 38

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using HamBook.Properties;
2 using Org.BouncyCastle.Utilities;
9 office 3 using RJCP.IO.Ports;
1 office 4 using Serilog;
5 using System;
6 using System.Collections.Concurrent;
7 using System.Collections.Generic;
8 using System.IO.Ports;
9 using System.Linq;
10 using System.Reflection;
11 using System.Runtime.CompilerServices;
12 using System.Text;
13 using System.Threading;
14 using System.Threading.Tasks;
15 using System.Windows.Input;
16  
17 namespace HamBook.Radios
18 {
19 public class CatAssemblies : IDisposable
20 {
21 public int Count => _count;
22  
23 private int _count;
9 office 24 private SerialPortStream _serialPort;
1 office 25 private string _radio;
26  
3 office 27 private ConcurrentDictionary<string, Cat> _catCommands;
26 office 28 private SemaphoreSlim _semaphoreSlim;
1 office 29  
30 private CatAssemblies()
31 {
32 _catCommands = new ConcurrentDictionary<string, Cat>();
26 office 33 _semaphoreSlim = new SemaphoreSlim(1, 1);
1 office 34 }
35  
9 office 36 public CatAssemblies(SerialPortStream serialPort, string radio) : this()
1 office 37 {
38 _serialPort = serialPort;
39 _radio = radio;
40  
41 Load(_radio);
42 }
43 public void Dispose()
44 {
45 Unload();
46 }
47  
48 private void Load(string radio)
49 {
50 Interlocked.Exchange(ref _count, 0);
51  
52 foreach (var type in Assembly.GetExecutingAssembly()
53 .GetTypes()
54 .Where(type => type.IsSubclassOf(typeof(Cat)))
55 .Where(type => type.GetCustomAttribute<RadioAttribute>() !=null && type.GetCustomAttribute<RadioAttribute>().Radio == radio))
56 {
57 try
58 {
59 var catCommand = (Cat)type
9 office 60 .GetConstructor(new[] { typeof(SerialPortStream) })
1 office 61 .Invoke(new [] { _serialPort });
62  
63 if (catCommand == null)
64 {
65 throw new ArgumentException(Resources.Could_not_create_assembly);
66 }
67  
68 if (!_catCommands.TryAdd(catCommand.Name, catCommand))
69 {
70 Log.Warning(Resources.Unable_to_register_assembly, catCommand.Name);
71  
72 catCommand.Dispose();
73  
74 continue;
75 }
76  
77 //BindEventHandlers(command);
78  
79 Interlocked.Increment(ref _count);
80 }
81 catch (Exception exception)
82 {
83 Log.Error(exception, Resources.Could_not_instantiate_assembly, type);
84 }
85 }
86  
87 Log.Information(Resources.Registering_commands, Count);
88 }
89  
90 private void Unload()
91 {
92 // Dispose all command assemblies.
93 var list = new List<Cat>(_catCommands.Values);
94  
95 for (var i = 0; i < list.Count; ++i)
96 {
97 try
98 {
99 //UnbindEventHandlers(list[i]);
100  
101 if (list[i] != null)
102 {
103 Log.Debug(Resources.Disposing_assembly, list[i].GetType().Name);
104  
105 list[i]
106 .Dispose();
107  
108 list[i] = null;
109 }
110 }
111 catch (NullReferenceException)
112 {
113 // Already removed.
114 }
115 catch (ObjectDisposedException)
116 {
117 list[i] = null;
118 }
119 catch (Exception exception)
120 {
121 Log.Error(exception, Resources.Error_encountered_while_disposing_object);
122 }
123 }
124  
125 _catCommands.Clear();
126 }
127  
26 office 128 public T CatParse<T>(string command, object[] param)
1 office 129 {
26 office 130 if (_catCommands.TryGetValue(command, out var catCommand))
3 office 131 {
26 office 132 var methodInfo = catCommand.GetType().GetMethod("Parse");
133 if (methodInfo != null)
134 {
135 return (T)methodInfo.Invoke(catCommand, param);
136 }
137  
138 throw new CatCommandException(Resources.CAT_command_method_not_found, command, "Parse");
3 office 139 }
140  
26 office 141 throw new CatCommandException(Resources.CAT_command_not_found, command);
142 }
143  
144 public T CatGetDefault<T>(string command, object[] param)
145 {
146 _semaphoreSlim.Wait();
147  
1 office 148 try
149 {
26 office 150 if (!_serialPort.IsOpen)
1 office 151 {
26 office 152 _serialPort.Open();
153 }
154  
155 try
156 {
157 if (_catCommands.TryGetValue(command, out var catCommand))
1 office 158 {
26 office 159 var methodInfo = catCommand.GetType().GetMethod("GetDefault");
160 if (methodInfo != null)
161 {
162 return (T)methodInfo.Invoke(catCommand, param);
163 }
1 office 164 }
165 }
26 office 166 finally
167 {
168 if (_serialPort.IsOpen)
169 {
170 _serialPort.Flush();
171 _serialPort.Close();
172 }
173 }
1 office 174 }
175 finally
176 {
26 office 177 _semaphoreSlim.Release();
1 office 178 }
9 office 179  
180 return default;
1 office 181 }
182  
26 office 183 public void CatSet<T>(string command, object[] param)
9 office 184 {
26 office 185 _semaphoreSlim.Wait();
186  
187 try
9 office 188 {
26 office 189 if (!_serialPort.IsOpen)
9 office 190 {
26 office 191 _serialPort.Open();
9 office 192 }
11 office 193  
26 office 194 try
195 {
196 if (_catCommands.TryGetValue(command, out var catCommand))
197 {
198 var methodInfo = catCommand.GetType().GetMethod("Set");
199 if (methodInfo != null)
200 {
201 methodInfo.Invoke(catCommand, param);
9 office 202  
26 office 203 return;
204 }
9 office 205  
26 office 206 throw new CatCommandException(Resources.CAT_command_method_not_found, command, "Set");
207 }
3 office 208  
26 office 209 throw new CatCommandException(Resources.CAT_command_not_found, command);
210 }
211 finally
1 office 212 {
26 office 213 if (_serialPort.IsOpen)
1 office 214 {
26 office 215 _serialPort.Flush();
216 _serialPort.Close();
1 office 217 }
218 }
219 }
220 finally
221 {
26 office 222 _semaphoreSlim.Release();
1 office 223 }
224 }
225  
15 office 226 public async Task<U> CatSetAsync<T, U>(string command, object[] param, CancellationToken cancellationToken)
3 office 227 {
26 office 228 await _semaphoreSlim.WaitAsync(cancellationToken);
3 office 229  
230 try
231 {
26 office 232 if (!_serialPort.IsOpen)
3 office 233 {
26 office 234 _serialPort.Open();
235 }
236  
237 try
238 {
239 if (_catCommands.TryGetValue(command, out var catCommand))
3 office 240 {
26 office 241 var methodInfo = catCommand.GetType().GetMethod("SetAsync");
242 if (methodInfo != null)
9 office 243 {
26 office 244 if (methodInfo.GetCustomAttribute<AsyncStateMachineAttribute>() != null)
245 {
246 var parameters = new List<object>();
247 parameters.AddRange(param);
248 parameters.Add(cancellationToken);
9 office 249  
26 office 250 var result = await (Task<U>)methodInfo.Invoke(catCommand, parameters.ToArray());
11 office 251  
26 office 252 return result;
253 }
9 office 254 }
26 office 255 throw new CatCommandException(Resources.CAT_command_method_not_found, command, "SetAsync");
3 office 256 }
26 office 257  
258 throw new CatCommandException(Resources.CAT_command_not_found, command);
3 office 259 }
26 office 260 finally
261 {
262 if (_serialPort.IsOpen)
263 {
264 await _serialPort.FlushAsync(cancellationToken);
265 _serialPort.Close();
266 }
267 }
3 office 268 }
269 finally
270 {
26 office 271 _semaphoreSlim.Release();
3 office 272 }
9 office 273 }
3 office 274  
9 office 275 public void CatWrite<T>(string command, object[] param)
276 {
26 office 277 _semaphoreSlim.Wait();
9 office 278  
279 try
280 {
26 office 281 if (!_serialPort.IsOpen)
9 office 282 {
26 office 283 _serialPort.Open();
284 }
285  
286 try
287 {
288 if (_catCommands.TryGetValue(command, out var catCommand))
9 office 289 {
26 office 290 var methodInfo = catCommand.GetType().GetMethod("Write");
291 if (methodInfo != null)
292 {
293 methodInfo.Invoke(catCommand, param);
11 office 294  
26 office 295 return;
296 }
297  
298 throw new CatCommandException(Resources.CAT_command_method_not_found, command, "Write");
9 office 299 }
11 office 300  
26 office 301 throw new CatCommandException(Resources.CAT_command_not_found, command);
9 office 302 }
26 office 303 finally
304 {
305 if (_serialPort.IsOpen)
306 {
307 _serialPort.Flush();
308 }
309 }
9 office 310 }
311 finally
312 {
26 office 313 _semaphoreSlim.Release();
9 office 314 }
3 office 315 }
316  
9 office 317 public async Task CatWriteAsync<T>(string command, object[] param, CancellationToken cancellationToken)
3 office 318 {
26 office 319 await _semaphoreSlim.WaitAsync(cancellationToken);
3 office 320  
321 try
322 {
26 office 323 if (!_serialPort.IsOpen)
3 office 324 {
26 office 325 _serialPort.Open();
326 }
327  
328 try
329 {
330 if (_catCommands.TryGetValue(command, out var catCommand))
3 office 331 {
26 office 332 var methodInfo = catCommand.GetType().GetMethod("WriteAsync");
333 if (methodInfo != null)
9 office 334 {
26 office 335 if (methodInfo.GetCustomAttribute<AsyncStateMachineAttribute>() != null)
336 {
337 var parameters = new List<object>();
338 parameters.AddRange(param);
339 parameters.Add(cancellationToken);
9 office 340  
26 office 341 await (Task)methodInfo.Invoke(catCommand, parameters.ToArray());
11 office 342  
26 office 343 return;
344 }
9 office 345 }
26 office 346  
347 throw new CatCommandException(Resources.CAT_command_method_not_found, command, "WriteAsync");
3 office 348 }
11 office 349  
26 office 350 throw new CatCommandException(Resources.CAT_command_not_found, command);
3 office 351 }
26 office 352 finally
353 {
354 if (_serialPort.IsOpen)
355 {
356 await _serialPort.FlushAsync(cancellationToken);
357 }
358 }
3 office 359 }
360 finally
361 {
26 office 362 _semaphoreSlim.Release();
3 office 363 }
364 }
365  
38 office 366 public async Task CatWriteAsync(string command, object[] param, CancellationToken cancellationToken)
367 {
368 await _semaphoreSlim.WaitAsync(cancellationToken);
369  
370 try
371 {
372 if (!_serialPort.IsOpen)
373 {
374 _serialPort.Open();
375 }
376  
377 try
378 {
379 if (_catCommands.TryGetValue(command, out var catCommand))
380 {
381 var methodInfo = catCommand.GetType().GetMethod("WriteAsync");
382 if (methodInfo != null)
383 {
384 if (methodInfo.GetCustomAttribute<AsyncStateMachineAttribute>() != null)
385 {
386 var parameters = new List<object>();
387 parameters.AddRange(param);
388 parameters.Add(cancellationToken);
389  
390 await (Task)methodInfo.Invoke(catCommand, parameters.ToArray());
391  
392 return;
393 }
394 }
395  
396 throw new CatCommandException(Resources.CAT_command_method_not_found, command, "WriteAsync");
397 }
398  
399 throw new CatCommandException(Resources.CAT_command_not_found, command);
400 }
401 finally
402 {
403 if (_serialPort.IsOpen)
404 {
405 await _serialPort.FlushAsync(cancellationToken);
406 }
407 }
408 }
409 finally
410 {
411 _semaphoreSlim.Release();
412 }
413 }
414  
1 office 415 public T CatRead<T>(string command, object[] param)
416 {
26 office 417 _semaphoreSlim.Wait();
3 office 418  
1 office 419 try
420 {
26 office 421 if (!_serialPort.IsOpen)
1 office 422 {
26 office 423 _serialPort.Open();
424 }
425  
426 try
427 {
428 if (_catCommands.TryGetValue(command, out var catCommand))
1 office 429 {
26 office 430 var methodInfo = catCommand.GetType().GetMethod("Read");
431 if (methodInfo != null)
432 {
433 return (T)methodInfo.Invoke(catCommand, param);
434 }
435  
436 throw new CatCommandException(Resources.CAT_command_method_not_found, command, "Read");
1 office 437 }
11 office 438  
26 office 439 throw new CatCommandException(Resources.CAT_command_not_found, command);
1 office 440 }
26 office 441 finally
442 {
443 if (_serialPort.IsOpen)
444 {
445 _serialPort.Flush();
446 _serialPort.Close();
447 }
448 }
1 office 449 }
450 finally
451 {
26 office 452 _semaphoreSlim.Release();
1 office 453 }
454 }
455  
9 office 456 public async Task<T> CatReadAsync<T>(string command, object[] param, CancellationToken cancellationToken)
1 office 457 {
26 office 458 await _semaphoreSlim.WaitAsync(cancellationToken);
3 office 459  
1 office 460 try
461 {
26 office 462 if (!_serialPort.IsOpen)
1 office 463 {
26 office 464 _serialPort.Open();
465 }
466  
467 try
468 {
469 if (_catCommands.TryGetValue(command, out var catCommand))
1 office 470 {
26 office 471 var methodInfo = catCommand.GetType().GetMethod("ReadAsync");
472 if (methodInfo != null)
1 office 473 {
26 office 474 if (methodInfo.GetCustomAttribute<AsyncStateMachineAttribute>() != null)
475 {
476 var parameters = new List<object>();
477 parameters.AddRange(param);
478 parameters.Add(cancellationToken);
9 office 479  
27 office 480 var result = await (Task<T>)methodInfo.Invoke(catCommand, parameters.ToArray());
481  
482 return result;
26 office 483 }
1 office 484 }
26 office 485  
486 throw new CatCommandException(Resources.CAT_command_method_not_found, command, "ReadAsync");
1 office 487 }
11 office 488  
26 office 489 throw new CatCommandException(Resources.CAT_command_not_found, command);
1 office 490 }
26 office 491 finally
492 {
493 if (_serialPort.IsOpen)
494 {
495 await _serialPort.FlushAsync(cancellationToken);
496 _serialPort.Close();
497 }
498 }
1 office 499 }
500 finally
501 {
26 office 502 _semaphoreSlim.Release();
1 office 503 }
504 }
505 }
506 }