wasSharp – Diff between revs 2 and 5

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 2 Rev 5
1 /////////////////////////////////////////////////////////////////////////// 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 // 2 // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 //
3 // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // 3 // Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
4 // rights of fair usage, the disclaimer and warranty conditions. // 4 // rights of fair usage, the disclaimer and warranty conditions. //
5 /////////////////////////////////////////////////////////////////////////// 5 ///////////////////////////////////////////////////////////////////////////
6   6  
7 using System; 7 using System;
8 using System.Collections.Generic; 8 using System.Collections.Generic;
9 using System.Diagnostics; 9 using System.Diagnostics;
10 using System.Linq; 10 using System.Linq;
11 using System.Threading; 11 using System.Threading;
12 using System.Threading.Tasks; 12 using System.Threading.Tasks;
13 using System.Xml.Serialization; 13 using System.Xml.Serialization;
14   14  
15 namespace wasSharp 15 namespace wasSharp
16 { 16 {
17 public class Time 17 public class Time
18 { 18 {
19 public delegate void TimerCallback(object state); 19 public delegate void TimerCallback(object state);
20   20  
21 public sealed class Timer : IDisposable 21 public sealed class Timer : IDisposable
22 { 22 {
23 private static readonly Task CompletedTask = Task.FromResult(false); 23 private static readonly Task CompletedTask = Task.FromResult(false);
24 private readonly TimerCallback Callback; 24 private readonly TimerCallback Callback;
25 private readonly object State; 25 private readonly object State;
26 private Task Delay; 26 private Task Delay;
27 private bool Disposed; 27 private bool Disposed;
28 private int Period; 28 private int Period;
29 private CancellationTokenSource TokenSource; 29 private CancellationTokenSource TokenSource;
30   30  
31 public Timer(TimerCallback callback, object state, int dueTime, int period) 31 public Timer(TimerCallback callback, object state, int dueTime, int period)
32 { 32 {
33 Callback = callback; 33 Callback = callback;
34 State = state; 34 State = state;
35 Period = period; 35 Period = period;
36 Reset(dueTime); 36 Reset(dueTime);
37 } 37 }
38   38  
39 public Timer(TimerCallback callback, object state, TimeSpan dueTime, TimeSpan period) 39 public Timer(TimerCallback callback, object state, TimeSpan dueTime, TimeSpan period)
40 : this(callback, state, (int) dueTime.TotalMilliseconds, (int) period.TotalMilliseconds) 40 : this(callback, state, (int) dueTime.TotalMilliseconds, (int) period.TotalMilliseconds)
41 { 41 {
42 } 42 }
43   43  
44 public void Dispose() 44 public void Dispose()
45 { 45 {
46 Dispose(true); 46 Dispose(true);
47 GC.SuppressFinalize(this); 47 GC.SuppressFinalize(this);
48 } 48 }
49   49  
50 ~Timer() 50 ~Timer()
51 { 51 {
52 Dispose(false); 52 Dispose(false);
53 } 53 }
54   54  
55 private void Dispose(bool cleanUpManagedObjects) 55 private void Dispose(bool cleanUpManagedObjects)
56 { 56 {
57 if (cleanUpManagedObjects) 57 if (cleanUpManagedObjects)
58 Cancel(); 58 Cancel();
59 Disposed = true; 59 Disposed = true;
60 } 60 }
61   61  
62 public void Change(int dueTime, int period) 62 public void Change(int dueTime, int period)
63 { 63 {
64 Period = period; 64 Period = period;
65 Reset(dueTime); 65 Reset(dueTime);
66 } 66 }
67   67  
68 public void Change(TimeSpan dueTime, TimeSpan period) 68 public void Change(TimeSpan dueTime, TimeSpan period)
69 { 69 {
70 Change((int) dueTime.TotalMilliseconds, (int) period.TotalMilliseconds); 70 Change((int) dueTime.TotalMilliseconds, (int) period.TotalMilliseconds);
71 } 71 }
72   72  
73 private void Reset(int due) 73 private void Reset(int due)
74 { 74 {
75 Cancel(); 75 Cancel();
76 if (due >= 0) 76 if (due >= 0)
77 { 77 {
78 TokenSource = new CancellationTokenSource(); 78 TokenSource = new CancellationTokenSource();
79 Action tick = null; 79 Action tick = null;
80 tick = () => 80 tick = () =>
81 { 81 {
82 Task.Run(() => Callback(State)); 82 Task.Run(() => Callback(State));
83 if (Disposed || Period < 0) return; 83 if (Disposed || Period < 0) return;
84 Delay = Period > 0 ? Task.Delay(Period, TokenSource.Token) : CompletedTask; 84 Delay = Period > 0 ? Task.Delay(Period, TokenSource.Token) : CompletedTask;
85 Delay.ContinueWith(t => tick(), TokenSource.Token); 85 Delay.ContinueWith(t => tick(), TokenSource.Token);
86 }; 86 };
87 Delay = due > 0 ? Task.Delay(due, TokenSource.Token) : CompletedTask; 87 Delay = due > 0 ? Task.Delay(due, TokenSource.Token) : CompletedTask;
88 Delay.ContinueWith(t => tick(), TokenSource.Token); 88 Delay.ContinueWith(t => tick(), TokenSource.Token);
89 } 89 }
90 } 90 }
91   91  
92 private void Cancel() 92 private void Cancel()
93 { 93 {
94 if (TokenSource != null) 94 if (TokenSource != null)
95 { 95 {
96 TokenSource.Cancel(); 96 TokenSource.Cancel();
97 TokenSource.Dispose(); 97 TokenSource.Dispose();
98 TokenSource = null; 98 TokenSource = null;
99 } 99 }
100 } 100 }
101 } 101 }
102   102  
103 /////////////////////////////////////////////////////////////////////////// 103 ///////////////////////////////////////////////////////////////////////////
104 // Copyright (C) Wizardry and Steamworks 2015 - License: GNU GPLv3 // 104 // Copyright (C) Wizardry and Steamworks 2015 - License: GNU GPLv3 //
105 /////////////////////////////////////////////////////////////////////////// 105 ///////////////////////////////////////////////////////////////////////////
106 /// <summary> 106 /// <summary>
107 /// Given a number of allowed events per seconds, this class allows you 107 /// Given a number of allowed events per seconds, this class allows you
108 /// to determine via the IsSafe property whether it is safe to trigger 108 /// to determine via the IsSafe property whether it is safe to trigger
109 /// another lined-up event. This is mostly used to check that throttles 109 /// another lined-up event. This is mostly used to check that throttles
110 /// are being respected. 110 /// are being respected.
111 /// </summary> 111 /// </summary>
112 public class wasTimedThrottle : IDisposable 112 public class TimedThrottle : IDisposable
113 { 113 {
114 private readonly uint EventsAllowed; 114 private readonly uint EventsAllowed;
115 private readonly object LockObject = new object(); 115 private readonly object LockObject = new object();
116 private Timer timer; 116 private Timer timer;
117 private uint TriggeredEvents; 117 private uint TriggeredEvents;
118   118  
119 public wasTimedThrottle(uint events, uint seconds) 119 public TimedThrottle(uint events, uint seconds)
120 { 120 {
121 EventsAllowed = events; 121 EventsAllowed = events;
122 if (timer == null) 122 if (timer == null)
123 { 123 {
124 timer = new Timer(o => 124 timer = new Timer(o =>
125 { 125 {
126 lock (LockObject) 126 lock (LockObject)
127 { 127 {
128 TriggeredEvents = 0; 128 TriggeredEvents = 0;
129 } 129 }
130 }, null, (int) seconds, (int) seconds); 130 }, null, (int) seconds, (int) seconds);
131 } 131 }
132 } 132 }
133   133  
134 public bool IsSafe 134 public bool IsSafe
135 { 135 {
136 get 136 get
137 { 137 {
138 lock (LockObject) 138 lock (LockObject)
139 { 139 {
140 return ++TriggeredEvents <= EventsAllowed; 140 return ++TriggeredEvents <= EventsAllowed;
141 } 141 }
142 } 142 }
143 } 143 }
144   144  
145 public void Dispose() 145 public void Dispose()
146 { 146 {
147 Dispose(true); 147 Dispose(true);
148 GC.SuppressFinalize(this); 148 GC.SuppressFinalize(this);
149 } 149 }
150   150  
151 protected virtual void Dispose(bool dispose) 151 protected virtual void Dispose(bool dispose)
152 { 152 {
153 if (timer != null) 153 if (timer != null)
154 { 154 {
155 timer.Dispose(); 155 timer.Dispose();
156 timer = null; 156 timer = null;
157 } 157 }
158 } 158 }
159 } 159 }
160   160  
161 /////////////////////////////////////////////////////////////////////////// 161 ///////////////////////////////////////////////////////////////////////////
162 // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 // 162 // Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 //
163 /////////////////////////////////////////////////////////////////////////// 163 ///////////////////////////////////////////////////////////////////////////
164 /// <summary> 164 /// <summary>
165 /// An alarm class similar to the UNIX alarm with the added benefit 165 /// An alarm class similar to the UNIX alarm with the added benefit
166 /// of a decaying timer that tracks the time between rescheduling. 166 /// of a decaying timer that tracks the time between rescheduling.
167 /// </summary> 167 /// </summary>
168 /// <remarks> 168 /// <remarks>
169 /// (C) Wizardry and Steamworks 2013 - License: GNU GPLv3 169 /// (C) Wizardry and Steamworks 2013 - License: GNU GPLv3
170 /// </remarks> 170 /// </remarks>
171 public class wasAdaptiveAlarm : IDisposable 171 public class DecayingAlarm : IDisposable
172 { 172 {
173 [Flags] 173 [Flags]
174 public enum DECAY_TYPE 174 public enum DECAY_TYPE
175 { 175 {
176 [XmlEnum(Name = "none")] NONE = 0, 176 [XmlEnum(Name = "none")] NONE = 0,
177 [XmlEnum(Name = "arithmetic")] ARITHMETIC = 1, 177 [XmlEnum(Name = "arithmetic")] ARITHMETIC = 1,
178 [XmlEnum(Name = "geometric")] GEOMETRIC = 2, 178 [XmlEnum(Name = "geometric")] GEOMETRIC = 2,
179 [XmlEnum(Name = "harmonic")] HARMONIC = 4, 179 [XmlEnum(Name = "harmonic")] HARMONIC = 4,
180 [XmlEnum(Name = "weighted")] WEIGHTED = 5 180 [XmlEnum(Name = "weighted")] WEIGHTED = 5
181 } 181 }
182   182  
183 private readonly DECAY_TYPE decay = DECAY_TYPE.NONE; 183 private readonly DECAY_TYPE decay = DECAY_TYPE.NONE;
184 private readonly Stopwatch elapsed = new Stopwatch(); 184 private readonly Stopwatch elapsed = new Stopwatch();
185 private readonly object LockObject = new object(); 185 private readonly object LockObject = new object();
186 private readonly HashSet<double> times = new HashSet<double>(); 186 private readonly HashSet<double> times = new HashSet<double>();
187 private Timer alarm; 187 private Timer alarm;
188   188  
189 /// <summary> 189 /// <summary>
190 /// The default constructor using no decay. 190 /// The default constructor using no decay.
191 /// </summary> 191 /// </summary>
192 public wasAdaptiveAlarm() 192 public DecayingAlarm()
193 { 193 {
194 Signal = new ManualResetEvent(false); 194 Signal = new ManualResetEvent(false);
195 } 195 }
196   196  
197 /// <summary> 197 /// <summary>
198 /// The constructor for the wasAdaptiveAlarm class taking as parameter a decay type. 198 /// The constructor for the DecayingAlarm class taking as parameter a decay type.
199 /// </summary> 199 /// </summary>
200 /// <param name="decay">the type of decay: arithmetic, geometric, harmonic, heronian or quadratic</param> 200 /// <param name="decay">the type of decay: arithmetic, geometric, harmonic, heronian or quadratic</param>
201 public wasAdaptiveAlarm(DECAY_TYPE decay) 201 public DecayingAlarm(DECAY_TYPE decay)
202 { 202 {
203 Signal = new ManualResetEvent(false); 203 Signal = new ManualResetEvent(false);
204 this.decay = decay; 204 this.decay = decay;
205 } 205 }
206   206  
207 public ManualResetEvent Signal { get; set; } 207 public ManualResetEvent Signal { get; set; }
208   208  
209 public void Dispose() 209 public void Dispose()
210 { 210 {
211 Dispose(true); 211 Dispose(true);
212 GC.SuppressFinalize(this); 212 GC.SuppressFinalize(this);
213 } 213 }
214   214  
215 public void Alarm(double deadline) 215 public void Alarm(double deadline)
216 { 216 {
217 lock (LockObject) 217 lock (LockObject)
218 { 218 {
219 switch (alarm == null) 219 switch (alarm == null)
220 { 220 {
221 case true: 221 case true:
222 elapsed.Start(); 222 elapsed.Start();
223 alarm = new Timer(o => 223 alarm = new Timer(o =>
224 { 224 {
225 lock (LockObject) 225 lock (LockObject)
226 { 226 {
227 Signal.Set(); 227 Signal.Set();
228 elapsed.Stop(); 228 elapsed.Stop();
229 times.Clear(); 229 times.Clear();
230 alarm.Dispose(); 230 alarm.Dispose();
231 alarm = null; 231 alarm = null;
232 } 232 }
233 }, null, (int) deadline, 0); 233 }, null, (int) deadline, 0);
234 return; 234 return;
235 case false: 235 case false:
236 elapsed.Stop(); 236 elapsed.Stop();
237 times.Add(elapsed.ElapsedMilliseconds); 237 times.Add(elapsed.ElapsedMilliseconds);
238 switch (decay) 238 switch (decay)
239 { 239 {
240 case DECAY_TYPE.ARITHMETIC: 240 case DECAY_TYPE.ARITHMETIC:
241 alarm?.Change( 241 alarm?.Change(
242 (int) ((deadline + times.Aggregate((a, b) => b + a))/(1f + times.Count)), 0); 242 (int) ((deadline + times.Aggregate((a, b) => b + a))/(1f + times.Count)), 0);
243 break; 243 break;
244 case DECAY_TYPE.GEOMETRIC: 244 case DECAY_TYPE.GEOMETRIC:
245 alarm?.Change((int) (Math.Pow(deadline*times.Aggregate((a, b) => b*a), 245 alarm?.Change((int) (Math.Pow(deadline*times.Aggregate((a, b) => b*a),
246 1f/(1f + times.Count))), 0); 246 1f/(1f + times.Count))), 0);
247 break; 247 break;
248 case DECAY_TYPE.HARMONIC: 248 case DECAY_TYPE.HARMONIC:
249 alarm?.Change((int) ((1f + times.Count)/ 249 alarm?.Change((int) ((1f + times.Count)/
250 (1f/deadline + times.Aggregate((a, b) => 1f/b + 1f/a))), 0); 250 (1f/deadline + times.Aggregate((a, b) => 1f/b + 1f/a))), 0);
251 break; 251 break;
252 case DECAY_TYPE.WEIGHTED: 252 case DECAY_TYPE.WEIGHTED:
253 HashSet<double> d = new HashSet<double>(times) {deadline}; 253 HashSet<double> d = new HashSet<double>(times) {deadline};
254 double total = d.Aggregate((a, b) => b + a); 254 double total = d.Aggregate((a, b) => b + a);
255 alarm?.Change( 255 alarm?.Change(
256 (int) (d.Aggregate((a, b) => Math.Pow(a, 2)/total + Math.Pow(b, 2)/total)), 0); 256 (int) (d.Aggregate((a, b) => Math.Pow(a, 2)/total + Math.Pow(b, 2)/total)), 0);
257 break; 257 break;
258 default: 258 default:
259 alarm?.Change((int) deadline, 0); 259 alarm?.Change((int) deadline, 0);
260 break; 260 break;
261 } 261 }
262 elapsed.Reset(); 262 elapsed.Reset();
263 elapsed.Start(); 263 elapsed.Start();
264 break; 264 break;
265 } 265 }
266 } 266 }
267 } 267 }
268   268  
269 protected virtual void Dispose(bool dispose) 269 protected virtual void Dispose(bool dispose)
270 { 270 {
271 if (alarm != null) 271 if (alarm != null)
272 { 272 {
273 alarm.Dispose(); 273 alarm.Dispose();
274 alarm = null; 274 alarm = null;
275 } 275 }
276 } 276 }
277 } 277 }
278 } 278 }
279 } 279 }
280   280  
281
Generated by GNU Enscript 1.6.5.90.
281
Generated by GNU Enscript 1.6.5.90.
282   282  
283   283  
284   284