DirectOutputR1
DirectOutput framework R1 for virtual pinball cabinets.
Go to:
Overview 
 All Classes Namespaces Files Functions Variables Enumerations Enumerator Properties Events Macros Pages
AlarmHandler.cs
Go to the documentation of this file.
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using DirectOutput.General.Statistics;
5 
6 namespace DirectOutput.PinballSupport
7 {
14  public class AlarmHandler
15  {
16  private TimeSpanStatisticsItem AlarmStatistics;
17  private TimeSpanStatisticsItem IntervalAlarmStatistics;
18 
23  public DateTime GetNextAlarmTime()
24  {
25  DateTime IA = GetNextIntervalAlarm();
26  DateTime A = GetNextAlarm();
27 
28  if (IA < A)
29  {
30  return IA;
31  }
32  return A;
33  }
34 
40  public bool ExecuteAlarms(DateTime AlarmTime)
41  {
42  bool AlarmsExecuted = false;
43 
44  AlarmsExecuted |= Alarm(AlarmTime);
45  AlarmsExecuted |= IntervalAlarm(AlarmTime);
46 
47  return AlarmsExecuted;
48  }
49 
50 
51 
52 
53 
54  #region IntervalAlarm
55  private object IntervalAlarmLocker = new object();
56  private List<IntervalAlarmSettingBase> IntervalAlarmList = new List<IntervalAlarmSettingBase>();
57  private abstract class IntervalAlarmSettingBase
58  {
59  public int IntervalMs { get; set; }
60  public DateTime NextAlarm { get; set; }
61  public abstract void Execute();
62 
63 
64  }
65 
66  private class IntervalAlarmSettingPara : IntervalAlarmSettingBase
67  {
68 
69  public Action<object> IntervalAlarmHandler { get; set; }
70  public object Para { get; set; }
71 
72 
73  public override void Execute()
74  {
75  try
76  {
77  IntervalAlarmHandler(Para);
78  }
79  catch (Exception E)
80  {
81  throw new Exception("A exception occured in IntervalAlarm for AlarmHandler {0} with parameter {1}.".Build(IntervalAlarmHandler.ToString(), Para.ToString().Replace("\n", ",")), E);
82  }
83  }
84 
85  public IntervalAlarmSettingPara() { }
86  public IntervalAlarmSettingPara(int IntervalMs, Action<object> IntervalAlarmHandler, object Para)
87  {
88  this.IntervalAlarmHandler = IntervalAlarmHandler;
89  this.IntervalMs = IntervalMs;
90  this.NextAlarm = DateTime.Now.AddMilliseconds(IntervalMs);
91  this.Para = Para;
92  }
93  }
94 
95  private class IntervalAlarmSettingNoPara : IntervalAlarmSettingBase
96  {
97 
98  public Action IntervalAlarmHandler { get; set; }
99 
100 
101  public override void Execute()
102  {
103  try
104  {
105  IntervalAlarmHandler();
106  }
107  catch (Exception E)
108  {
109  throw new Exception("A exception occured in IntervalAlarm for AlarmHandler {0}.".Build(IntervalAlarmHandler.ToString()), E);
110  }
111  }
112 
113  public IntervalAlarmSettingNoPara() { }
114  public IntervalAlarmSettingNoPara(int IntervalMs, Action IntervalAlarmHandler)
115  {
116  this.IntervalAlarmHandler = IntervalAlarmHandler;
117  this.IntervalMs = IntervalMs;
118  this.NextAlarm = DateTime.Now.AddMilliseconds(IntervalMs);
119  }
120  }
121 
122  private DateTime GetNextIntervalAlarm()
123  {
124  if (IntervalAlarmList.Count > 0)
125  {
126  return IntervalAlarmList.Min(x => x.NextAlarm);
127  }
128  return DateTime.MaxValue;
129  }
130 
131  private bool IntervalAlarm(DateTime AlarmTime)
132  {
133  lock (IntervalAlarmLocker)
134  {
135  bool AlarmTriggered = false;
136  IntervalAlarmList.Where(x => x.NextAlarm <= AlarmTime).ToList().ForEach(delegate(IntervalAlarmSettingBase S)
137  {
138  IntervalAlarmStatistics.MeasurementStart();
139  try
140  {
141  S.Execute();
142  }
143  catch (Exception E)
144  {
145  Log.Exception("A exception occured when excuting the handler for a interval alarm. This interval alarm will be disabled.", E);
146  }
147  IntervalAlarmStatistics.MeasurementStop();
148  AlarmTriggered = true;
149 
150  if (S.NextAlarm.AddMilliseconds(S.IntervalMs) <= AlarmTime)
151  {
152  S.NextAlarm = AlarmTime.AddMilliseconds(1);
153  }
154  else
155  {
156  S.NextAlarm = S.NextAlarm.AddMilliseconds(S.IntervalMs);
157  }
158  });
159  return AlarmTriggered;
160  }
161  }
162 
169  public void RegisterIntervalAlarm(int IntervalMs, Action IntervalAlarmHandler)
170  {
171  lock (IntervalAlarmLocker)
172  {
173  UnregisterIntervalAlarm(IntervalAlarmHandler);
174  IntervalAlarmList.Add(new IntervalAlarmSettingNoPara(IntervalMs, IntervalAlarmHandler));
175  }
176  }
177 
178 
183  public void UnregisterIntervalAlarm(Action IntervalAlarmHandler)
184  {
185  lock (IntervalAlarmLocker)
186  {
187  IntervalAlarmList.RemoveAll(x => x is IntervalAlarmSettingNoPara && ((IntervalAlarmSettingNoPara)x).IntervalAlarmHandler == IntervalAlarmHandler);
188  }
189  }
190 
191 
199  public void RegisterIntervalAlarm(int IntervalMs, Action<object> IntervalAlarmHandler, object Parameter)
200  {
201  lock (IntervalAlarmLocker)
202  {
203  UnregisterIntervalAlarm(IntervalAlarmHandler);
204  IntervalAlarmList.Add(new IntervalAlarmSettingPara(IntervalMs, IntervalAlarmHandler, Parameter));
205  }
206  }
207 
208 
213  public void UnregisterIntervalAlarm(Action<object> IntervalAlarmHandler)
214  {
215  lock (IntervalAlarmLocker)
216  {
217  IntervalAlarmList.RemoveAll(x => x is IntervalAlarmSettingPara && ((IntervalAlarmSettingPara)x).IntervalAlarmHandler == IntervalAlarmHandler);
218  }
219  }
220 
221  #endregion
222 
223 
224 
225  #region Alarm
226  private object AlarmLocker = new object();
227  private List<AlarmSettingsBase> AlarmList = new List<AlarmSettingsBase>();
228 
229  private abstract class AlarmSettingsBase
230  {
231  public DateTime AlarmTime { get; set; }
232  public abstract void Execute();
233  }
234 
235  private class AlarmSettingNoPara : AlarmSettingsBase
236  {
237 
238  public Action AlarmHandler { get; set; }
239 
240 
241  public override void Execute()
242  {
243  try
244  {
245  AlarmHandler();
246  }
247  catch (Exception E)
248  {
249  Log.Exception("A exception occured for AlarmHandler {0}.".Build(AlarmHandler.ToString()), E);
250  }
251  }
252 
253  public AlarmSettingNoPara() { }
254  public AlarmSettingNoPara(DateTime AlarmTime, Action AlarmHandler)
255  {
256  this.AlarmTime = AlarmTime;
257  this.AlarmHandler = AlarmHandler;
258 
259  }
260  }
261 
262  private class AlarmSettingPara : AlarmSettingsBase
263  {
264 
265  public Action<object> AlarmHandler { get; set; }
266  public object Para { get; set; }
267 
268  public override void Execute()
269  {
270  try
271  {
272  AlarmHandler(Para);
273  }
274  catch (Exception E)
275  {
276  Log.Exception("A exception occured for AlarmHandler {0} with parameter {1}.".Build(AlarmHandler.ToString(), Para.ToString().Replace("\n", ",")), E);
277  }
278  }
279 
280  public AlarmSettingPara() { }
281  public AlarmSettingPara(DateTime AlarmTime, Action<object> AlarmHandler, object Para)
282  {
283  this.AlarmTime = AlarmTime;
284  this.AlarmHandler = AlarmHandler;
285  this.Para = Para;
286  }
287  }
288 
289  private DateTime GetNextAlarm()
290  {
291  if (AlarmList.Count > 0)
292  {
293  return AlarmList.Min(x => x.AlarmTime);
294  }
295  return DateTime.MaxValue;
296  }
297 
298  private bool Alarm(DateTime AlarmTime)
299  {
300 
301  lock (AlarmLocker)
302  {
303  List<AlarmSettingsBase> L = AlarmList.Where(x => x.AlarmTime <= AlarmTime).ToList();
304  AlarmList.RemoveAll(x => x.AlarmTime <= AlarmTime);
305  L.ForEach(delegate(AlarmSettingsBase S)
306  {
307  S.Execute();
308  });
309  return (L.Count > 0);
310  }
311  }
312 
313 
314 
315 
316 
323  public void RegisterAlarm(int DurationMs, Action AlarmHandler, bool DontUnregister = false)
324  {
325  RegisterAlarm(DateTime.Now.AddMilliseconds(DurationMs), AlarmHandler, DontUnregister);
326  }
327 
334  public void RegisterAlarm(DateTime AlarmTime, Action AlarmHandler, bool DontUnregister = false)
335  {
336  lock (AlarmLocker)
337  {
338  if (!DontUnregister) UnregisterAlarm(AlarmHandler);
339  AlarmList.Add(new AlarmSettingNoPara(AlarmTime, AlarmHandler));
340  }
341  }
342 
343 
348  public void UnregisterAlarm(Action AlarmHandler)
349  {
350  lock (AlarmLocker)
351  {
352  AlarmList.RemoveAll(x => x is AlarmSettingNoPara && ((AlarmSettingNoPara)x).AlarmHandler == AlarmHandler);
353  }
354  }
355 
356 
364  public void RegisterAlarm(int DurationMs, Action<object> AlarmHandler, object Parameter, bool DontUnregister = false)
365  {
366  RegisterAlarm(DateTime.Now.AddMilliseconds(DurationMs), AlarmHandler, Parameter, DontUnregister);
367  }
368 
376  public void RegisterAlarm(DateTime AlarmTime, Action<object> AlarmHandler, object Parameter, bool DontUnregister = false)
377  {
378  lock (AlarmLocker)
379  {
380  if(!DontUnregister) UnregisterAlarm(AlarmHandler);
381  AlarmList.Add(new AlarmSettingPara(AlarmTime, AlarmHandler, Parameter));
382  }
383  }
384 
385 
390  public void UnregisterAlarm(Action<object> AlarmHandler)
391  {
392  lock (AlarmLocker)
393  {
394  AlarmList.RemoveAll(x => x is AlarmSettingPara && ((AlarmSettingPara)x).AlarmHandler == AlarmHandler);
395  }
396  }
397 
398  #endregion
399 
400 
404  public void Init(Pinball Pinball)
405  {
406  AlarmStatistics = new TimeSpanStatisticsItem() { Name = "Alarm calls", GroupName = "Pinball - Alarm calls" };
407  Pinball.TimeSpanStatistics.Add(AlarmStatistics);
408  IntervalAlarmStatistics = new TimeSpanStatisticsItem() { Name = "Interval Alarm calls", GroupName = "Pinball - Alarm calls" };
409  Pinball.TimeSpanStatistics.Add(IntervalAlarmStatistics);
410  }
411 
415  public void Finish()
416  {
417 
418  AlarmList.Clear();
419  IntervalAlarmList.Clear();
420  }
421 
422 
423  #region Constructor
424 
425 
426 
427  public AlarmHandler()
428  {
429 
430 
431  }
432 
433 
434 
435 
436  #endregion
437 
438 
439 
440  }
441 }