--- /dev/null
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+\r
+namespace CarFire\r
+{\r
+ /// <summary>\r
+ /// A simple timer class. I'm not sure why .NET or at least\r
+ /// XNA doesn't already have one of these.\r
+ /// </summary>\r
+ public class Timer<T> : IComparable<Timer<T>> where T : IComparable<T>\r
+ {\r
+ #region Public Properties\r
+\r
+ /// <summary>\r
+ /// Get and set the expiration time. If the time is already set\r
+ /// and the timer is registered, you cannot push the expiration time\r
+ /// further back, but you can decrease it.\r
+ /// </summary>\r
+ public T Time\r
+ {\r
+ get\r
+ {\r
+ return mTime;\r
+ }\r
+ set\r
+ {\r
+ if (mTime.CompareTo(value) > 0)\r
+ {\r
+ mTime = value;\r
+ gTimers.Promote(this);\r
+ }\r
+ }\r
+ }\r
+\r
+ /// <summary>\r
+ /// Get the current absolute time, accurate up until\r
+ /// the last time Timer.FireAll was called.\r
+ /// </summary>\r
+ public static T Now { get { return gNow; } }\r
+\r
+ /// <summary>\r
+ /// Get and set the events that will be called when the\r
+ /// timer expires.\r
+ /// </summary>\r
+ public event ExpiredEventHandler Expired;\r
+\r
+ /// <summary>\r
+ /// Get and set a user contextual object.\r
+ /// </summary>\r
+ public object Context;\r
+\r
+ #endregion\r
+\r
+\r
+ #region Public Types\r
+\r
+ /// <summary>\r
+ /// The type for an event handler for timers that expire.\r
+ /// </summary>\r
+ /// <param name="timer">The timer that expired.</param>\r
+ public delegate void ExpiredEventHandler(Timer<T> timer);\r
+\r
+ #endregion\r
+\r
+\r
+ #region Public Methods\r
+\r
+ /// <summary>\r
+ /// Construct a timer with an absolute time (in seconds)\r
+ /// when the timer should expire.\r
+ /// </summary>\r
+ /// <param name="time">Absolute time, in seconds.</param>\r
+ public Timer(T time)\r
+ {\r
+ mTime = time;\r
+ gTimers.Add(this);\r
+ }\r
+\r
+ /// <summary>\r
+ /// Construct a timer with an absolute time (in seconds)\r
+ /// when the timer should expire, and an event handler.\r
+ /// </summary>\r
+ /// <param name="time">Absolute time, in seconds.</param>\r
+ /// <param name="expired">An event handler.</param>\r
+ public Timer(T time, ExpiredEventHandler expired)\r
+ {\r
+ mTime = time;\r
+ Expired += expired;\r
+ gTimers.Add(this);\r
+ }\r
+\r
+ /// <summary>\r
+ /// Construct a timer with an absolute time (in seconds)\r
+ /// when the timer should expire, and a contextual object.\r
+ /// </summary>\r
+ /// <param name="time">Absolute time, in seconds.</param>\r
+ /// <param name="context">A user contextual object.</param>\r
+ public Timer(T time, object context)\r
+ {\r
+ mTime = time;\r
+ Context = context;\r
+ gTimers.Add(this);\r
+ }\r
+\r
+ /// <summary>\r
+ /// Construct a timer with an absolute time (in seconds)\r
+ /// when the timer should expire, an event handler, and a\r
+ /// contextual object.\r
+ /// </summary>\r
+ /// <param name="time">Absolute time, in seconds.</param>\r
+ /// <param name="expired">An event handler.</param>\r
+ /// <param name="context">A user contextual object.</param>\r
+ public Timer(T time, ExpiredEventHandler expired, object context)\r
+ {\r
+ mTime = time;\r
+ Expired += expired;\r
+ Context = context;\r
+ gTimers.Add(this);\r
+ }\r
+\r
+\r
+ /// <summary>\r
+ /// Fire all outstanding timers which should be expired\r
+ /// before a certain time.\r
+ /// </summary>\r
+ /// <param name="time">Absolute time, in seconds.</param>\r
+ public static void FireExpired(T time)\r
+ {\r
+ gNow = time;\r
+\r
+ while (gTimers.Count > 0)\r
+ {\r
+ Timer<T> timer = gTimers.Peek();\r
+ if (timer.Time.CompareTo(Now) <= 0)\r
+ {\r
+ if (timer.Expired != null) timer.Expired(timer);\r
+ if (timer.Time.CompareTo(Now) <= 0) gTimers.GetNext();\r
+ }\r
+ else\r
+ {\r
+ break;\r
+ }\r
+ }\r
+ }\r
+\r
+\r
+ /// <summary>\r
+ /// Unregister all registered timers without firing any events.\r
+ /// </summary>\r
+ public static void Clear()\r
+ {\r
+ gTimers.Clear();\r
+ }\r
+\r
+\r
+ /// <summary>\r
+ /// Compare a timer with another, based on the expiration\r
+ /// times of both timers.\r
+ /// </summary>\r
+ /// <param name="other">The timer to compare against.</param>\r
+ /// <returns>A negative value if this timer is less than the\r
+ /// other, a positive value if this timer is greater than the\r
+ /// other, or zero if they are the same.</returns>\r
+ public int CompareTo(Timer<T> other)\r
+ {\r
+ return Time.CompareTo(other.Time);\r
+ }\r
+\r
+ #endregion\r
+\r
+\r
+ #region Private Variables\r
+\r
+ T mTime;\r
+\r
+ static IPriorityQueue<Timer<T>> gTimers = new BinaryHeap<Timer<T>>(10);\r
+ static T gNow;\r
+\r
+ #endregion\r
+ }\r
+}\r