Jypeli  9
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 
32 namespace Jypeli
33 {
37  public sealed class Timer
38  {
39  #region Events
40 
44  public event Action Timeout;
45 
46  #endregion
47 
49 
50  private bool _enabled = false;
51 
52  private TimeSpan timeToTrigger = TimeSpan.MaxValue;
53  private TimeSpan trigInterval = new TimeSpan( 0, 0, 1 );
54  private TimeSpan savedTrigger = TimeSpan.Zero;
55 
56  private TimeSpan timeToCount = TimeSpan.MaxValue;
57  private TimeSpan countInterval = TimeSpan.FromMilliseconds( 10 );
58  private TimeSpan savedCount = TimeSpan.Zero;
59 
60  #region Properties
61 
65  public bool Enabled
66  {
67  get { return _enabled; }
68  set
69  {
70  if ( value == _enabled ) return;
71  if ( value )
72  Start();
73  else
74  Stop();
75  }
76  }
77 
81  public bool IgnorePause { get; set; }
82 
86  public double Interval
87  {
88  get { return trigInterval.TotalSeconds; }
89  set
90  {
91  if ( value <= 0 ) throw new ArgumentException( "Interval cannot be zero or negative!" );
92 
93  try
94  {
95  trigInterval = TimeSpan.FromSeconds(value);
96  }
97  catch (OverflowException)
98  {
99  // Workaround for overflow when converting TimeSpan.MaxValue to seconds and back again
100  trigInterval = TimeSpan.MaxValue;
101  }
102 
103  if ( Enabled )
105  }
106  }
107 
111  public double CurrentTime
112  {
113  get { return SecondCounter.Value; }
114  set { SecondCounter.Value = value; }
115  }
116 
117  // /// <summary>
118  // /// Ajastimen käynnistysaika.
119  // /// </summary>
120  //public TimeSpan StartTime { get; private set; }
121 
125  public DoubleMeter SecondCounter { get; private set; }
126 
131  public double SecondCounterStep { get; set; }
132 
141  public IntMeter Times { get; private set; }
142 
147  public bool TimesLimited
148  {
149  get { return Times.MinValue == 0; }
150  set
151  {
152  Times.MinValue = value ? 0 : 1;
153  }
154  }
155 
160  public object Tag { get; set; }
161 
162  #endregion
163 
164  #region Public methods
165 
169  public Timer()
170  {
171  SecondCounter = new DoubleMeter( 0 );
172  Times = new IntMeter( 1 );
173  Times.MinValue = 1;
174  Times.MaxValue = 1;
175  Enabled = false;
176  }
177 
183  public Timer(double interval) : this()
184  {
185  Interval = interval;
186  }
187 
194  public Timer(double interval, Action onTimeout) : this(interval)
195  {
196  Timeout += onTimeout;
197  }
198 
207  public static Timer CreateAndStart(double interval, Action onTimeout)
208  {
209  Timer t = new Timer(interval, onTimeout);
210  t.Start();
211  return t;
212  }
213 
220  public static void SingleShot( double seconds, Action onTimeout )
221  {
222  Timer t = new Timer();
223  t.Interval = seconds;
224  t.Timeout += onTimeout;
225  t.Start( 1 );
226  }
227 
234  public static Action Limit( Action action, double seconds )
235  {
236  Timer limiter = new Timer();
237  bool allowInvoke = true;
238 
239  limiter.Interval = seconds;
240  limiter.LimitTimes( 1 );
241  limiter.Timeout += () => allowInvoke = true;
242 
243  return delegate
244  {
245  if ( allowInvoke )
246  {
247  allowInvoke = false;
248  action();
249  limiter.Start();
250  }
251  };
252  }
253 
257  public void Start()
258  {
259  _enabled = true;
262  timers.Add( this );
263  }
264 
269  public void Start( int times )
270  {
271  _enabled = true;
272  LimitTimes( times );
275  timers.Add( this );
276  }
277 
281  public void Pause()
282  {
283  _enabled = false;
286  timers.Remove( this );
287  }
288 
292  public void Stop()
293  {
294  _enabled = false;
295  savedTrigger = TimeSpan.Zero;
296  savedCount = TimeSpan.Zero;
297  timers.Remove( this );
298  }
299 
304  public void Reset()
305  {
306  SecondCounter.Reset();
307  Times.Reset();
309  }
310 
311  private void LimitTimes( int numTimes )
312  {
313  TimesLimited = true;
314  Times.DefaultValue = numTimes;
315  Times.MaxValue = numTimes;
316  Times.Value = numTimes;
317  }
318 
322  internal static void ClearAll()
323  {
324  timers.ForEach(t => { t.Enabled = false; });
325  timers.Clear();
326  }
327 
328  private static void UpdateTimer( Timer timer, TimeSpan dt )
329  {
330  if ( !timer.Enabled )
331  return;
332 
333  timer.timeToCount -= dt;
334 
335  while ( timer.timeToCount.TotalSeconds <= 0 )
336  {
337  // Count second counter
338  timer.timeToCount += timer.countInterval;
339  timer.SecondCounter.Value += timer.countInterval.TotalSeconds;
340  }
341 
342  if ( timer.Timeout != null || timer.TimesLimited )
343  {
344  timer.timeToTrigger -= dt;
345 
346  while ( timer.timeToTrigger.TotalSeconds <= 0 )
347  {
348  // Trigger timeouts
349  timer.timeToTrigger += timer.trigInterval; // TODO: MessageDisplay.MessageTime = TimeSpan.MaxValue; Aiheuttaa tässä kohdassa overflown
350 
351  if ( timer.TimesLimited )
352  {
353  if ( --timer.Times.Value <= 0 )
354  {
355  // The timer has executed its maximum times, stop it
356  timer.Stop();
357  }
358  }
359 
360  if ( timer.Timeout != null )
361  timer.Timeout();
362  }
363  }
364  }
365 
366  internal static void UpdateAll( Time time )
367  {
368  timers.Update( time );
369  timers.ForEach( UpdateTimer, time.SinceLastUpdate );
370  }
371 
372  internal static void UpdateAll( Time time, Predicate<Timer> isUpdated )
373  {
374  timers.Update( time );
375 
376  foreach ( var timer in timers )
377  {
378  if ( isUpdated( timer ) )
379  UpdateTimer( timer, time.SinceLastUpdate );
380  }
381  }
382 
383  #endregion
384  }
385 }
Jypeli.Timer.Enabled
bool Enabled
Ajastin päällä/pois päältä.
Definition: Timer.cs:66
Jypeli.Timer.savedCount
TimeSpan savedCount
Definition: Timer.cs:58
Jypeli.DoubleMeter
Mittari, joka mittaa double-tyyppisiä arvoja. Sidottavissa näyttöihin, kuten ValueDisplay ja BarGa...
Definition: DoubleMeter.cs:11
Jypeli.Timer.ClearAll
static void ClearAll()
Poistaa kaikki ajastimet.
Definition: Timer.cs:322
Jypeli.Timer.SingleShot
static void SingleShot(double seconds, Action onTimeout)
Kutsuu aliohjelmaa onTimeout annetun ajan kuluttua. Ajastin luodaan automaattisesti.
Definition: Timer.cs:220
Jypeli.Timer.IgnorePause
bool IgnorePause
Ajastin ei pysähdy vaikka peli pysäytettäisiin.
Definition: Timer.cs:81
Jypeli.Timer.timeToTrigger
TimeSpan timeToTrigger
Definition: Timer.cs:52
Jypeli.Timer.UpdateTimer
static void UpdateTimer(Timer timer, TimeSpan dt)
Definition: Timer.cs:328
Jypeli.Timer.TimesLimited
bool? TimesLimited
Ajastimen suorituskertojen rajoitus päälle/pois.
Definition: Timer.cs:148
Jypeli.Timer.Timeout
Action Timeout
Tapahtuu väliajoin.
Definition: Timer.cs:44
Jypeli
Definition: Automobile.cs:5
Jypeli.Timer.UpdateAll
static void UpdateAll(Time time, Predicate< Timer > isUpdated)
Definition: Timer.cs:372
Jypeli.Timer.Tag
object Tag
Vapaasti asetettava muuttuja. Arvo ei muutu, jos sitä ei muuteta.
Definition: Timer.cs:160
Jypeli.Timer.trigInterval
TimeSpan trigInterval
Definition: Timer.cs:53
Jypeli.Timer.CurrentTime
double CurrentTime
Menossa oleva hetki nollasta väliaikaan (Interval).
Definition: Timer.cs:112
Jypeli.Timer.Timer
Timer(double interval, Action onTimeout)
Alustaa uuden ajastimen ja asettaa sille tapahtuma-aikavälin sekä aliohjelman, jota kutsutaan TimeOut...
Definition: Timer.cs:194
Jypeli.Timer.timeToCount
TimeSpan timeToCount
Definition: Timer.cs:56
Jypeli.Timer.UpdateAll
static void UpdateAll(Time time)
Definition: Timer.cs:366
Jypeli.Timer.Reset
void Reset()
Nollaa ajastimen tilan. Myös suorituskerrat nollataan.
Definition: Timer.cs:304
Jypeli.Time
Sisältää tiedon ajasta, joka on kulunut pelin alusta ja viime päivityksestä.
Definition: Time.cs:14
Jypeli.Timer.Start
void Start(int times)
Käynnistää ajastimen, rajoittaa suorituskerrat.
Definition: Timer.cs:269
Jypeli.Timer.Timer
Timer()
Alustaa uuden ajastinluokan.
Definition: Timer.cs:169
Jypeli.Timer.Interval
double Interval
Aika sekunneissa, jonka välein TimeOut tapahtuu.
Definition: Timer.cs:87
Jypeli.Timer.LimitTimes
void LimitTimes(int numTimes)
Definition: Timer.cs:311
Jypeli.Timer.Pause
void Pause()
Pysäyttää ajastimen tallentaen sen tilan.
Definition: Timer.cs:281
Jypeli.Timer.SecondCounter
DoubleMeter SecondCounter
Sekuntilaskuri. Voidaan sitoa näyttöihin.
Definition: Timer.cs:125
Jypeli.Time.SinceLastUpdate
TimeSpan SinceLastUpdate
Aika joka on kulunut viime päivityksestä.
Definition: Time.cs:24
Jypeli.Timer.countInterval
TimeSpan countInterval
Definition: Timer.cs:57
Jypeli.Timer.timers
static SynchronousList< Timer > timers
Definition: Timer.cs:48
Jypeli.Timer.Timer
Timer(double interval)
Alustaa uuden ajastimen ja asettaa sille ajan sekunneissa, jonka välein TimeOut tapahtuu.
Definition: Timer.cs:183
Jypeli.Timer.Stop
void Stop()
Pysäyttää ajastimen ja nollaa sen tilan.
Definition: Timer.cs:292
Jypeli.Timer.SecondCounterStep
double SecondCounterStep
Kuinka monta sekuntia sekuntilaskuri laskee yhden sekunnin aikana. Oletus on 1. Arvolla 2 laskuri las...
Definition: Timer.cs:131
System
Definition: CFFauxAttributes.cs:29
Jypeli.Timer
Ajastin, joka voidaan asettaa laukaisemaan tapahtumia tietyin väliajoin.
Definition: Timer.cs:38
Jypeli.IntMeter
Mittari, joka mittaa int-tyyppisiä arvoja. Sidottavissa näyttöihin, kuten ValueDisplay ja BarGauge...
Definition: IntMeter.cs:11
Jypeli.Timer.savedTrigger
TimeSpan savedTrigger
Definition: Timer.cs:54
Jypeli.Timer.Times
IntMeter Times
Määrää, kuinka monta kertaa tapahtuma suoritetaan. Kun tapahtumaa on suoritettu tarpeeksi,...
Definition: Timer.cs:141
Jypeli.SynchronousList
Synkroninen lista, eli lista joka päivittyy vasta kun sen Update-metodia kutsutaan....
Definition: SynchronousList.cs:15
Jypeli.Timer.Start
void Start()
Käynnistää ajastimen.
Definition: Timer.cs:257
Jypeli.Timer.CreateAndStart
static Timer CreateAndStart(double interval, Action onTimeout)
Luo ja käynnistää uuden ajastimen tietyllä tapahtuma-aikavälillä sekä aliohjelmalla,...
Definition: Timer.cs:207
Jypeli.Timer.Limit
static Action Limit(Action action, double seconds)
Rajoittaa aliohjelman toimintaa niin, että se voidaan suorittaa vain tietyin väliajoin.
Definition: Timer.cs:234
Jypeli.Timer._enabled
bool _enabled
Definition: Timer.cs:50