All pastes #977946 Raw Edit

tobz

public text v1 · immutable
·published 2008-04-09 05:31 UTC
rendered paste body
/*************************************************************************
 *
 *   file		: RepeatingTimer.cs
 *   copyright		: (C) The WCell Team
 *   email		: info@wcell.org
 *   last changed	: $LastChangedDate: 2008-03-09 19:28:05 -0400 (Sun, 09 Mar 2008) $
 *   last author	: $LastChangedBy: tobz $
 *   revision		: $Rev: 183 $
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *************************************************************************/

using System;

namespace WCell.Core.Timers
{
    /// <summary>
    /// A repeating timer that will continue to fire after its first
    /// tick until stopped manually.
    /// </summary>
    public class RepeatingTimer : ITimer
    {
        private volatile bool m_running;
		private long m_delay, m_interval, m_started, m_lastTick;
		private TimerCallback m_callback;

        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="callback">the timer callback</param>
        public RepeatingTimer(TimerCallback callback)
        {
			m_callback = callback;
        }

        /// <summary>
        /// Whether or not the timer is running.
        /// </summary>
        public bool IsRunning
        {
            get
            {
                return m_running;
            }
        }

        /// <summary>
        /// Starts the timer, given the initial firing delay.
        /// </summary>
        /// <param name="delay">the time before the timer fires in milliseconds</param>
        /// <param name="interval">the time between ticks after the initial tick in millisecond</param>
        public void Start(int delay, int interval)
        {
			Start((long)delay, (long)interval);
        }

        /// <summary>
        /// Starts the timer, given the initial firing delay.
        /// </summary>
        /// <param name="delay">the time before the timer fires in milliseconds</param>
		/// <param name="interval">the time between ticks after the initial tick in millisecond</param>
        public void Start(uint delay, uint interval)
        {
			Start((long)delay, (long)interval);
        }

        /// <summary>
        /// Starts the timer, given the initial firing delay.
        /// </summary>
        /// <param name="delay">the time before the timer fires in milliseconds</param>
		/// <param name="interval">the time between ticks after the initial tick in millisecond</param>
        public void Start(long delay, long interval)
        {
			m_delay = delay;
			m_interval = interval;
			m_started = m_lastTick = Utility.GetSystemTimeLong();

            m_running = true;
        }

        /// <summary>
        /// Starts the timer, given the initial firing delay.
        /// </summary>
        /// <param name="delay">the time before the timer fires in TimeSpan format</param>
		/// <param name="interval">the time between ticks after the initial tick in TimeSpan format</param>
        public void Start(TimeSpan delay, TimeSpan interval)
        {
			Start((long)delay.TotalMilliseconds, (long)interval.TotalMilliseconds);
        }

        /// <summary>
        /// Stops the timer.
        /// </summary>
        public void Stop()
        {
            m_running = false;
        }

		/// <summary>
		/// Updates the timer, firing the callback if enough time has elapsed.
		/// </summary>
		/// <param name="systemTime">the time this timer was called</param>
		public void Update(long systemTime)
		{
			if (!m_running)
				return;

			long timeDiff = systemTime - m_lastTick;

			if (m_started == m_lastTick)
			{
				// we haven't run yet, check delay.
				if (timeDiff >= m_delay)
				{
					// tick.
					m_callback(this);

					m_lastTick = systemTime;
				}
			}
			else
			{
				if (timeDiff > 0 && timeDiff >= m_interval)
				{
					m_callback(this);

					m_lastTick = systemTime;
				}
			}
		}

		/// <summary>
		/// Disposes the timer.
		/// </summary>
		public void Dispose()
		{
			Stop();
			m_callback = null;
		}
    }
}