HamBook – Blame information for rev 54

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