wasSharp – Rev 10

Subversion Repositories:
Rev:
///////////////////////////////////////////////////////////////////////////
//  Copyright (C) Wizardry and Steamworks 2013 - License: GNU GPLv3      //
//  Please see: http://www.gnu.org/licenses/gpl.html for legal details,  //
//  rights of fair usage, the disclaimer and warranty conditions.        //
///////////////////////////////////////////////////////////////////////////

using System;
using System.Threading;
using System.Threading.Tasks;

namespace wasSharp.Timers
{
    public delegate void TimerCallback(object state);

    public class Timer : IDisposable
    {
        private static readonly Task CompletedTask = Task.FromResult(false);
        private readonly TimerCallback Callback;
        private readonly object State;
        private Task Delay;
        private bool Disposed;
        private int Period;
        private CancellationTokenSource TokenSource;

        public Timer(TimerCallback callback, object state, int dueTime, int period)
        {
            Callback = callback;
            State = state;
            Period = period;
            Reset(dueTime);
        }

        public Timer(TimerCallback callback, object state, TimeSpan dueTime, TimeSpan period)
            : this(callback, state, (int) dueTime.TotalMilliseconds, (int) period.TotalMilliseconds)
        {
        }

        public Timer(TimerCallback callback) : this(callback, null, TimeSpan.Zero, TimeSpan.Zero)
        {
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        ~Timer()
        {
            Dispose(false);
        }

        private void Dispose(bool cleanUpManagedObjects)
        {
            if (cleanUpManagedObjects)
                Cancel();
            Disposed = true;
        }

        public void Change(int dueTime, int period)
        {
            Period = period;
            Reset(dueTime);
        }

        public void Change(uint dueTime, int period)
        {
            Period = period;
            Change((int) dueTime, period);
        }

        public void Change(TimeSpan dueTime, TimeSpan period)
        {
            Change((int) dueTime.TotalMilliseconds, (int) period.TotalMilliseconds);
        }

        private void Reset(int due)
        {
            Cancel();
            if (due <= 0)
                return;
            TokenSource = new CancellationTokenSource();
            Action tick = null;
            tick = () =>
            {
                Task.Run(() => Callback(State));
                if (Disposed)
                    return;
                Delay = Period > 0 ? Task.Delay(Period, TokenSource.Token) : CompletedTask;
                if (Delay.IsCompleted)
                    return;
                Delay.ContinueWith(t => tick(), TokenSource.Token);
            };
            Delay = due > 0 ? Task.Delay(due, TokenSource.Token) : CompletedTask;
            if (Delay.IsCompleted)
                return;
            Delay.ContinueWith(t => tick(), TokenSource.Token);
        }

        public void Stop()
        {
            Change(0, 0);
        }

        private void Cancel()
        {
            if (TokenSource == null)
                return;
            TokenSource.Cancel();
            TokenSource.Dispose();
            TokenSource = null;
        }
    }
}

Generated by GNU Enscript 1.6.5.90.