HamBook – Blame information for rev 27

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  
1 office 366 public T CatRead<T>(string command, object[] param)
367 {
26 office 368 _semaphoreSlim.Wait();
3 office 369  
1 office 370 try
371 {
26 office 372 if (!_serialPort.IsOpen)
1 office 373 {
26 office 374 _serialPort.Open();
375 }
376  
377 try
378 {
379 if (_catCommands.TryGetValue(command, out var catCommand))
1 office 380 {
26 office 381 var methodInfo = catCommand.GetType().GetMethod("Read");
382 if (methodInfo != null)
383 {
384 return (T)methodInfo.Invoke(catCommand, param);
385 }
386  
387 throw new CatCommandException(Resources.CAT_command_method_not_found, command, "Read");
1 office 388 }
11 office 389  
26 office 390 throw new CatCommandException(Resources.CAT_command_not_found, command);
1 office 391 }
26 office 392 finally
393 {
394 if (_serialPort.IsOpen)
395 {
396 _serialPort.Flush();
397 _serialPort.Close();
398 }
399 }
1 office 400 }
401 finally
402 {
26 office 403 _semaphoreSlim.Release();
1 office 404 }
405 }
406  
9 office 407 public async Task<T> CatReadAsync<T>(string command, object[] param, CancellationToken cancellationToken)
1 office 408 {
26 office 409 await _semaphoreSlim.WaitAsync(cancellationToken);
3 office 410  
1 office 411 try
412 {
26 office 413 if (!_serialPort.IsOpen)
1 office 414 {
26 office 415 _serialPort.Open();
416 }
417  
418 try
419 {
420 if (_catCommands.TryGetValue(command, out var catCommand))
1 office 421 {
26 office 422 var methodInfo = catCommand.GetType().GetMethod("ReadAsync");
423 if (methodInfo != null)
1 office 424 {
26 office 425 if (methodInfo.GetCustomAttribute<AsyncStateMachineAttribute>() != null)
426 {
427 var parameters = new List<object>();
428 parameters.AddRange(param);
429 parameters.Add(cancellationToken);
9 office 430  
27 office 431 var result = await (Task<T>)methodInfo.Invoke(catCommand, parameters.ToArray());
432  
433 return result;
26 office 434 }
1 office 435 }
26 office 436  
437 throw new CatCommandException(Resources.CAT_command_method_not_found, command, "ReadAsync");
1 office 438 }
11 office 439  
26 office 440 throw new CatCommandException(Resources.CAT_command_not_found, command);
1 office 441 }
26 office 442 finally
443 {
444 if (_serialPort.IsOpen)
445 {
446 await _serialPort.FlushAsync(cancellationToken);
447 _serialPort.Close();
448 }
449 }
1 office 450 }
451 finally
452 {
26 office 453 _semaphoreSlim.Release();
1 office 454 }
455 }
456 }
457 }