X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=CarFire%2FCarFire%2FCarFire%2FTimer.cs;fp=CarFire%2FCarFire%2FCarFire%2FTimer.cs;h=01dfd770bd59ca497a7e436dcf23d5c8d1c5100d;hb=8bd8893e7f7516c76558ad7262e9f9350f5192b9;hp=0000000000000000000000000000000000000000;hpb=1368c1af3d7a4a12b0b0577dbe3edbfd254e2d04;p=chaz%2Fcarfire diff --git a/CarFire/CarFire/CarFire/Timer.cs b/CarFire/CarFire/CarFire/Timer.cs new file mode 100644 index 0000000..01dfd77 --- /dev/null +++ b/CarFire/CarFire/CarFire/Timer.cs @@ -0,0 +1,183 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace CarFire +{ + /// + /// A simple timer class. I'm not sure why .NET or at least + /// XNA doesn't already have one of these. + /// + public class Timer : IComparable> where T : IComparable + { + #region Public Properties + + /// + /// Get and set the expiration time. If the time is already set + /// and the timer is registered, you cannot push the expiration time + /// further back, but you can decrease it. + /// + public T Time + { + get + { + return mTime; + } + set + { + if (mTime.CompareTo(value) > 0) + { + mTime = value; + gTimers.Promote(this); + } + } + } + + /// + /// Get the current absolute time, accurate up until + /// the last time Timer.FireAll was called. + /// + public static T Now { get { return gNow; } } + + /// + /// Get and set the events that will be called when the + /// timer expires. + /// + public event ExpiredEventHandler Expired; + + /// + /// Get and set a user contextual object. + /// + public object Context; + + #endregion + + + #region Public Types + + /// + /// The type for an event handler for timers that expire. + /// + /// The timer that expired. + public delegate void ExpiredEventHandler(Timer timer); + + #endregion + + + #region Public Methods + + /// + /// Construct a timer with an absolute time (in seconds) + /// when the timer should expire. + /// + /// Absolute time, in seconds. + public Timer(T time) + { + mTime = time; + gTimers.Add(this); + } + + /// + /// Construct a timer with an absolute time (in seconds) + /// when the timer should expire, and an event handler. + /// + /// Absolute time, in seconds. + /// An event handler. + public Timer(T time, ExpiredEventHandler expired) + { + mTime = time; + Expired += expired; + gTimers.Add(this); + } + + /// + /// Construct a timer with an absolute time (in seconds) + /// when the timer should expire, and a contextual object. + /// + /// Absolute time, in seconds. + /// A user contextual object. + public Timer(T time, object context) + { + mTime = time; + Context = context; + gTimers.Add(this); + } + + /// + /// Construct a timer with an absolute time (in seconds) + /// when the timer should expire, an event handler, and a + /// contextual object. + /// + /// Absolute time, in seconds. + /// An event handler. + /// A user contextual object. + public Timer(T time, ExpiredEventHandler expired, object context) + { + mTime = time; + Expired += expired; + Context = context; + gTimers.Add(this); + } + + + /// + /// Fire all outstanding timers which should be expired + /// before a certain time. + /// + /// Absolute time, in seconds. + public static void FireExpired(T time) + { + gNow = time; + + while (gTimers.Count > 0) + { + Timer timer = gTimers.Peek(); + if (timer.Time.CompareTo(Now) <= 0) + { + if (timer.Expired != null) timer.Expired(timer); + if (timer.Time.CompareTo(Now) <= 0) gTimers.GetNext(); + } + else + { + break; + } + } + } + + + /// + /// Unregister all registered timers without firing any events. + /// + public static void Clear() + { + gTimers.Clear(); + } + + + /// + /// Compare a timer with another, based on the expiration + /// times of both timers. + /// + /// The timer to compare against. + /// A negative value if this timer is less than the + /// other, a positive value if this timer is greater than the + /// other, or zero if they are the same. + public int CompareTo(Timer other) + { + return Time.CompareTo(other.Time); + } + + #endregion + + + #region Private Variables + + T mTime; + + static IPriorityQueue> gTimers = new BinaryHeap>(10); + static T gNow; + + #endregion + } +}