Jypeli  5
The simple game programming library
Timer.cs
Siirry tämän tiedoston dokumentaatioon.
1 #region MIT License
2 /*
3  * Copyright (c) 2009 University of Jyväskylä, Department of Mathematical
4  * Information Technology.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #endregion
25 
26 /*
27  * Authors: Tero Jäntti, Tomi Karppinen, Janne Nikkanen.
28  */
29 
30 using System;
31 using System.Collections.Generic;
32 using System.ComponentModel;
33 
34 namespace Jypeli
35 {
39  public sealed class Timer
40  {
41  #region Events
42 
46  public event Action Timeout;
47 
48  public event Action Stopped;
49  protected void OnStopped()
50  {
51  if (Stopped != null)
52  {
53  Stopped();
54  }
55  }
56 
57  #endregion
58 
59  private static SynchronousList<Timer> timers = new SynchronousList<Timer>();
60  private static Dictionary<Action, Timer> limiters = new Dictionary<Action, Timer>();
61 
62  private bool _enabled = false;
63 
64  private TimeSpan timeToTrigger = TimeSpan.MaxValue;
65  private TimeSpan trigInterval = new TimeSpan( 0, 0, 1 );
66  private TimeSpan savedTrigger = TimeSpan.Zero;
67 
68  private TimeSpan timeToCount = TimeSpan.MaxValue;
69  private TimeSpan countInterval = TimeSpan.FromMilliseconds( 10 );
70  private TimeSpan savedCount = TimeSpan.Zero;
71 
72  #region Properties
73 
77  public bool Enabled
78  {
79  get { return _enabled; }
80  set
81  {
82  if ( value == _enabled ) return;
83  if ( value )
84  Start();
85  else
86  Stop();
87  }
88  }
89 
93  public bool IgnorePause { get; set; }
94 
98  public double Interval
99  {
100  get { return trigInterval.TotalSeconds; }
101  set
102  {
103  if ( value <= 0 ) throw new ArgumentException( "Interval cannot be zero or negative!" );
104  trigInterval = TimeSpan.FromSeconds( value );
105  if ( Enabled )
106  timeToTrigger = trigInterval;
107  }
108  }
109 
113  public double CurrentTime
114  {
115  get { return SecondCounter.Value; }
116  set { SecondCounter.Value = value; }
117  }
118 
122  //public TimeSpan StartTime { get; private set; }
123 
127  public DoubleMeter SecondCounter { get; private set; }
128 
133  public double SecondCounterStep { get; set; }
134 
143  public IntMeter Times { get; private set; }
144 
149  public bool TimesLimited
150  {
151  get { return Times.MinValue == 0; }
152  set
153  {
154  Times.MinValue = value ? 0 : 1;
155  }
156  }
157 
162  public object Tag { get; set; }
163 
164  #endregion
165 
166  #region Public methods
167 
171  public Timer()
172  {
173  SecondCounter = new DoubleMeter( 0 );
174  Times = new IntMeter( 1 );
175  Times.MinValue = 1;
176  Times.MaxValue = 1;
177  Enabled = false;
178  }
179 
186  public static void SingleShot( double seconds, Action onTimeout )
187  {
188  Timer t = new Timer();
189  t.Interval = seconds;
190  t.Timeout += onTimeout;
191  t.Start( 1 );
192  }
193 
200  public static void Limit( Action action, double seconds )
201  {
202  Timer limiter = limiters.ContainsKey( action ) ? limiters[action] : null;
203 
204  if ( limiter == null )
205  {
206  limiter = new Timer() { Interval = seconds };
207  limiters.Add( action, limiter );
208  }
209 
210  if ( !limiter.Enabled )
211  {
212  action();
213  limiter.Start( 1 );
214  }
215  }
216 
220  public void Start()
221  {
222  _enabled = true;
223  timeToTrigger = trigInterval;
224  timeToCount = countInterval;
225  timers.Add( this );
226  }
227 
232  public void Start( int times )
233  {
234  _enabled = true;
235  LimitTimes( times );
236  timeToTrigger = trigInterval - savedTrigger;
237  timeToCount = countInterval - savedCount;
238  timers.Add( this );
239  }
240 
244  public void Pause()
245  {
246  _enabled = false;
247  savedTrigger = trigInterval - timeToTrigger;
248  savedCount = countInterval - timeToCount;
249  timers.Remove( this );
250  }
251 
255  public void Stop()
256  {
257  _enabled = false;
258  savedTrigger = TimeSpan.Zero;
259  savedCount = TimeSpan.Zero;
260  timers.Remove( this );
261  OnStopped();
262  }
263 
268  public void Reset()
269  {
270  SecondCounter.Reset();
271  Times.Reset();
272  timeToTrigger = trigInterval;
273  }
274 
275  private void LimitTimes( int numTimes )
276  {
277  TimesLimited = true;
278  Times.DefaultValue = numTimes;
279  Times.MaxValue = numTimes;
280  Times.Value = numTimes;
281  }
282 
286  internal static void ClearAll()
287  {
288  timers.Clear();
289  }
290 
291  private static void UpdateTimer( Timer timer, TimeSpan dt )
292  {
293  if ( !timer.Enabled )
294  return;
295 
296  timer.timeToCount -= dt;
297 
298  while ( timer.timeToCount.TotalSeconds <= 0 )
299  {
300  // Count second counter
301  timer.timeToCount += timer.countInterval;
302  timer.SecondCounter.Value += timer.countInterval.TotalSeconds;
303  }
304 
305  if ( timer.Timeout != null || timer.TimesLimited )
306  {
307  timer.timeToTrigger -= dt;
308 
309  while ( timer.timeToTrigger.TotalSeconds <= 0 )
310  {
311  // Trigger timeouts
312  timer.timeToTrigger += timer.trigInterval;
313 
314  if ( timer.TimesLimited )
315  {
316  if ( --timer.Times.Value <= 0 )
317  {
318  // The timer has executed its maximum times, stop it
319  timer.Stop();
320  }
321  }
322 
323  if ( timer.Timeout != null )
324  timer.Timeout();
325  }
326  }
327  }
328 
329  internal static void UpdateAll( Time time )
330  {
331  timers.Update( time );
332  timers.ForEach( UpdateTimer, time.SinceLastUpdate );
333  }
334 
335  internal static void UpdateAll( Time time, Predicate<Timer> isUpdated )
336  {
337  timers.Update( time );
338 
339  foreach ( var timer in timers )
340  {
341  if ( isUpdated( timer ) )
342  UpdateTimer( timer, time.SinceLastUpdate );
343  }
344  }
345 
346  #endregion
347  }
348 }
double Interval
Aika sekunneissa, jonka välein TimeOut tapahtuu.
Definition: Timer.cs:99
void Start(int times)
Käynnistää ajastimen, rajoittaa suorituskerrat.
Definition: Timer.cs:232
IntMeter Times
Määrää, kuinka monta kertaa tapahtuma suoritetaan. Kun tapahtumaa on suoritettu tarpeeksi, Enabled saa automaattisesti arvon false, jolloin ajastin pysähtyy. Kun laskuri nollataan, myös Times palautuu oletusarvoonsa. Huomaa, että TimesLimited tulee olla true, että arvo otetaan huomioon.
Definition: Timer.cs:143
void Stop()
Pysäyttää ajastimen ja nollaa sen tilan.
Definition: Timer.cs:255
Action Timeout
Tapahtuu väliajoin.
Definition: Timer.cs:46
void Update(Time time)
Lisää ja poistaa jonossa olevat elementit sekä kutsuu niiden Update-metodia.
double CurrentTime
Menossa oleva hetki nollasta väliaikaan (Interval).
Definition: Timer.cs:114
DoubleMeter SecondCounter
Ajastimen käynnistysaika.
Definition: Timer.cs:127
void ForEach(Action< T > action)
Suorittaa annetun toimenpiteen kaikille (nykyisille) listan alkioille.
void Pause()
Pysäyttää ajastimen tallentaen sen tilan.
Definition: Timer.cs:244
void Reset()
Nollaa ajastimen tilan. Myös suorituskerrat nollataan.
Definition: Timer.cs:268
Timer()
Alustaa uuden ajastinluokan.
Definition: Timer.cs:171
bool Enabled
Ajastin päällä/pois päältä.
Definition: Timer.cs:78
TimeSpan SinceLastUpdate
Aika joka on kulunut viime päivityksestä.
Definition: Time.cs:24
Mittari, joka mittaa double-tyyppisiä arvoja. Sidottavissa näyttöihin, kuten ValueDisplay ja BarGauge...
Definition: Meter.cs:515
Sisältää tiedon ajasta, joka on kulunut pelin alusta ja viime päivityksestä.
Definition: Time.cs:13
static void SingleShot(double seconds, Action onTimeout)
Kutsuu aliohjelmaa onTimeout annetun ajan kuluttua. Ajastin luodaan automaattisesti.
Definition: Timer.cs:186
object Tag
Vapaasti asetettava muuttuja. Arvo ei muutu, jos sitä ei muuteta.
Definition: Timer.cs:162
void OnStopped()
Definition: Timer.cs:49
Mittari, joka mittaa int-tyyppisiä arvoja. Sidottavissa näyttöihin, kuten ValueDisplay ja BarGauge...
Definition: Meter.cs:387
Ajastin, joka voidaan asettaa laukaisemaan tapahtumia tietyin väliajoin.
Definition: Timer.cs:39
double SecondCounterStep
Kuinka monta sekuntia sekuntilaskuri laskee yhden sekunnin aikana. Oletus on 1. Arvolla 2 laskuri las...
Definition: Timer.cs:133
bool TimesLimited
Ajastimen suorituskertojen rajoitus päälle/pois.
Definition: Timer.cs:150
Synkroninen lista, eli lista joka päivittyy vasta kun sen Update-metodia kutsutaan. Jos listalle lisätään IUpdatable-rajapinnan toteuttavia olioita, kutsutaan myös niiden Update-metodeja samalla.
void Start()
Käynnistää ajastimen.
Definition: Timer.cs:220
bool IgnorePause
Ajastin ei pysähdy vaikka peli pysäytettäisiin.
Definition: Timer.cs:93
static void Limit(Action action, double seconds)
Rajoittaa toimintaa niin, että se voidaan suorittaa vain tietyin väliajoin. Huom. älä käytä delegaatt...
Definition: Timer.cs:200
Action Stopped
Definition: Timer.cs:48