Unity3D C# 定时触发器 定时任务 大型RPC游戏

支付宝捐赠

打赏红包

  1. 注释很详细,具体使用方法看代码注释
	// Test
	
	//定时器显示
	var timerid = TimerHeap.AddTimer(0, 500, () =>
	{
	});
	
	//定时器完成
	TimerHeap.AddTimer(1000, 0, () =>
	{
	  TimerHeap.DelTimer(timerid);
	});
	
    TimerHeap.AddTimer(2000, 0, () =>
    {
		Debug.LogError("Hello World");
    });
    void Awake()
    {
        InvokeRepeating("Tick", 1, 0.02f);
    }
    
	void Tick()
    {
        TimerHeap.Tick();
        FrameTimerHeap.Tick();
    }
  1. TimerData.cs
/// 
    /// 定时器抽象实体
    /// 
    internal abstract class AbsTimerData
    {
        private uint m_nTimerId;

        public uint NTimerId
        {
            get { return m_nTimerId; }
            set { m_nTimerId = value; }
        }
        private int m_nInterval;

        public int NInterval
        {
            get { return m_nInterval; }
            set { m_nInterval = value; }
        }
        private ulong m_unNextTick;

        public ulong UnNextTick
        {
            get { return m_unNextTick; }
            set { m_unNextTick = value; }
        }

        public abstract Delegate Action
        {
            get;
            set;
        }

        public abstract void DoAction();
    }

    /// 
    /// 无参数定时器实体
    /// 
    internal class TimerData : AbsTimerData
    {
        private Action m_action;

        public override Delegate Action
        {
            get { return m_action; }
            set { m_action = value as Action; }
        }

        public override void DoAction()
        {
            m_action();
        }
    }

    /// 
    /// 1个参数定时器实体
    /// 
    /// 参数1
    internal class TimerData<T> : AbsTimerData
    {
        private Action<T> m_action;

        public override Delegate Action
        {
            get { return m_action; }
            set { m_action = value as Action<T>; }
        }

        private T m_arg1;

        public T Arg1
        {
            get { return m_arg1; }
            set { m_arg1 = value; }
        }

        public override void DoAction()
        {
            m_action(m_arg1);
        }
    }

    /// 
    /// 2个参数定时器实体
    /// 
    /// 参数1
    /// 参数2
    internal class TimerData<T, U> : AbsTimerData
    {
        private Action<T, U> m_action;

        public override Delegate Action
        {
            get { return m_action; }
            set { m_action = value as Action<T, U>; }
        }

        private T m_arg1;

        public T Arg1
        {
            get { return m_arg1; }
            set { m_arg1 = value; }
        }

        private U m_arg2;

        public U Arg2
        {
            get { return m_arg2; }
            set { m_arg2 = value; }
        }

        public override void DoAction()
        {
            m_action(m_arg1, m_arg2);
        }
    }

    /// 
    /// 3个参数定时器实体
    /// 
    /// 参数1
    /// 参数2
    /// 参数3
    internal class TimerData<T, U, V> : AbsTimerData
    {
        private Action<T, U, V> m_action;

        public override Delegate Action
        {
            get { return m_action; }
            set { m_action = value as Action<T, U, V>; }
        }

        private T m_arg1;

        public T Arg1
        {
            get { return m_arg1; }
            set { m_arg1 = value; }
        }

        private U m_arg2;

        public U Arg2
        {
            get { return m_arg2; }
            set { m_arg2 = value; }
        }

        private V m_arg3;

        public V Arg3
        {
            get { return m_arg3; }
            set { m_arg3 = value; }
        }

        public override void DoAction()
        {
            m_action(m_arg1, m_arg2, m_arg3);
        }
    }
  1. TimerHeap.cs
/// 
    /// 定时触发器
    /// 
    public class TimerHeap
    {
        private static uint m_nNextTimerId;
        private static uint m_unTick;
        private static KeyedPriorityQueue<uint, AbsTimerData, ulong> m_queue;
        private static Stopwatch m_stopWatch;
        private static readonly object m_queueLock = new object();

        /// 
        /// 私有构造函数,封闭实例化。
        /// 
        private TimerHeap() { }

        /// 
        /// 默认构造函数
        /// 
        static TimerHeap()
        {
            m_queue = new KeyedPriorityQueue<uint, AbsTimerData, ulong>();
            m_stopWatch = new Stopwatch();
        }

        /// 
        /// 添加定时对象
        /// 
        /// 延迟启动时间。(毫秒)
        /// 重复间隔,为零不重复。(毫秒)
        /// 定时处理方法
        /// 定时对象Id
        public static uint AddTimer(uint start, int interval, Action handler)
        {
            //起始时间会有一个tick的误差,tick精度越高,误差越低
            var p = GetTimerData(new TimerData(), start, interval);
            p.Action = handler;
            return AddTimer(p);
        }

        /// 
        /// 添加定时对象
        /// 
        /// 参数类型1
        /// 延迟启动时间。(毫秒)
        /// 重复间隔,为零不重复。(毫秒)
        /// 定时处理方法
        /// 参数1
        /// 定时对象Id
        public static uint AddTimer<T>(uint start, int interval, Action<T> handler, T arg1)
        {
            var p = GetTimerData(new TimerData<T>(), start, interval);
            p.Action = handler;
            p.Arg1 = arg1;
            return AddTimer(p);
        }

        /// 
        /// 添加定时对象
        /// 
        /// 参数类型1
        /// 参数类型2
        /// 延迟启动时间。(毫秒)
        /// 重复间隔,为零不重复。(毫秒)
        /// 定时处理方法
        /// 参数1
        /// 参数2
        /// 定时对象Id
        public static uint AddTimer<T, U>(uint start, int interval, Action<T, U> handler, T arg1, U arg2)
        {
            var p = GetTimerData(new TimerData<T, U>(), start, interval);
            p.Action = handler;
            p.Arg1 = arg1;
            p.Arg2 = arg2;
            return AddTimer(p);
        }

        /// 
        /// 添加定时对象
        /// 
        /// 参数类型1
        /// 参数类型2
        /// 参数类型3
        /// 延迟启动时间。(毫秒)
        /// 重复间隔,为零不重复。(毫秒)
        /// 定时处理方法
        /// 参数1
        /// 参数2
        /// 参数3
        /// 定时对象Id
        public static uint AddTimer<T, U, V>(uint start, int interval, Action<T, U, V> handler, T arg1, U arg2, V arg3)
        {
            var p = GetTimerData(new TimerData<T, U, V>(), start, interval);
            p.Action = handler;
            p.Arg1 = arg1;
            p.Arg2 = arg2;
            p.Arg3 = arg3;
            return AddTimer(p);
        }

        /// 
        /// 删除定时对象
        /// 
        /// 定时对象Id
        public static void DelTimer(uint timerId)
        {
            lock (m_queueLock)
                m_queue.Remove(timerId);
        }

        /// 
        /// 周期调用触发任务
        /// 
        public static void Tick()
        {
            m_unTick += (uint)m_stopWatch.ElapsedMilliseconds;
            m_stopWatch.Reset();
            m_stopWatch.Start();

            while (m_queue.Count != 0)
            {
                AbsTimerData p;
                lock (m_queueLock)
                    p = m_queue.Peek();
                if (m_unTick < p.UnNextTick)
                {
                    break;
                }
                lock (m_queueLock)
                    m_queue.Dequeue();
                if (p.NInterval > 0)
                {
                    p.UnNextTick += (ulong)p.NInterval;
                    lock (m_queueLock)
                        m_queue.Enqueue(p.NTimerId, p, p.UnNextTick);
                    p.DoAction();
                }
                else
                {
                    p.DoAction();
                }
            }
        }

        /// 
        /// 重置定时触发器
        /// 
        public static void Reset()
        {
            m_unTick = 0;
            m_nNextTimerId = 0;
            lock (m_queueLock)
                while (m_queue.Count != 0)
                    m_queue.Dequeue();
        }

        private static uint AddTimer(AbsTimerData p)
        {
            lock (m_queueLock)
                m_queue.Enqueue(p.NTimerId, p, p.UnNextTick);
            return p.NTimerId;
        }

        private static T GetTimerData<T>(T p, uint start, int interval) where T : AbsTimerData
        {
            p.NInterval = interval;
            p.NTimerId = ++m_nNextTimerId;
            p.UnNextTick = m_unTick + 1 + start;
            return p;
        }
    }
  1. FrameTimerHeap.cs
public class FrameTimerHeap
    {
        private static uint m_nNextTimerId;
        private static uint m_unTick;
        private static KeyedPriorityQueue<uint, AbsTimerData, ulong> m_queue;
        private static readonly object m_queueLock = new object();

        /// 
        /// 私有构造函数,封闭实例化。
        /// 
        private FrameTimerHeap() { }

        /// 
        /// 默认构造函数
        /// 
        static FrameTimerHeap()
        {
            m_queue = new KeyedPriorityQueue<uint, AbsTimerData, ulong>();
        }

        /// 
        /// 添加定时对象
        /// 
        /// 延迟启动时间。(毫秒)
        /// 重复间隔,为零不重复。(毫秒)
        /// 定时处理方法
        /// 定时对象Id
        public static uint AddTimer(uint start, int interval, Action handler)
        {
            //起始时间会有一个tick的误差,tick精度越高,误差越低
            var p = GetTimerData(new TimerData(), start, interval);
            p.Action = handler;
            return AddTimer(p);
        }

        /// 
        /// 添加定时对象
        /// 
        /// 参数类型1
        /// 延迟启动时间。(毫秒)
        /// 重复间隔,为零不重复。(毫秒)
        /// 定时处理方法
        /// 参数1
        /// 定时对象Id
        public static uint AddTimer<T>(uint start, int interval, Action<T> handler, T arg1)
        {
            var p = GetTimerData(new TimerData<T>(), start, interval);
            p.Action = handler;
            p.Arg1 = arg1;
            return AddTimer(p);
        }

        /// 
        /// 添加定时对象
        /// 
        /// 参数类型1
        /// 参数类型2
        /// 延迟启动时间。(毫秒)
        /// 重复间隔,为零不重复。(毫秒)
        /// 定时处理方法
        /// 参数1
        /// 参数2
        /// 定时对象Id
        public static uint AddTimer<T, U>(uint start, int interval, Action<T, U> handler, T arg1, U arg2)
        {
            var p = GetTimerData(new TimerData<T, U>(), start, interval);
            p.Action = handler;
            p.Arg1 = arg1;
            p.Arg2 = arg2;
            return AddTimer(p);
        }

        /// 
        /// 添加定时对象
        /// 
        /// 参数类型1
        /// 参数类型2
        /// 参数类型3
        /// 延迟启动时间。(毫秒)
        /// 重复间隔,为零不重复。(毫秒)
        /// 定时处理方法
        /// 参数1
        /// 参数2
        /// 参数3
        /// 定时对象Id
        public static uint AddTimer<T, U, V>(uint start, int interval, Action<T, U, V> handler, T arg1, U arg2, V arg3)
        {
            var p = GetTimerData(new TimerData<T, U, V>(), start, interval);
            p.Action = handler;
            p.Arg1 = arg1;
            p.Arg2 = arg2;
            p.Arg3 = arg3;
            return AddTimer(p);
        }

        /// 
        /// 删除定时对象
        /// 
        /// 定时对象Id
        public static void DelTimer(uint timerId)
        {
            lock (m_queueLock)
                m_queue.Remove(timerId);
        }

        /// 
        /// 周期调用触发任务
        /// 
        public static void Tick()
        {
            m_unTick += (uint)(1000 * Time.deltaTime);
            //LoggerHelper.Error("m_unTick: " + (uint)(1000 * Time.deltaTime) + " Time.timeScale: " + Time.timeScale + " Time.deltaTime: " + Time.deltaTime);

            while (m_queue.Count != 0)
            {
                AbsTimerData p;
                lock (m_queueLock)
                    p = m_queue.Peek();
                if (m_unTick < p.UnNextTick)
                {
                    break;
                }
                lock (m_queueLock)
                    m_queue.Dequeue();
                if (p.NInterval > 0)
                {
                    p.UnNextTick += (ulong)p.NInterval;
                    lock (m_queueLock)
                        m_queue.Enqueue(p.NTimerId, p, p.UnNextTick);
                    p.DoAction();
                }
                else
                {
                    p.DoAction();
                }
            }
        }

        /// 
        /// 重置定时触发器
        /// 
        public static void Reset()
        {
            m_unTick = 0;
            m_nNextTimerId = 0;
            lock (m_queueLock)
                while (m_queue.Count != 0)
                    m_queue.Dequeue();
        }

        private static uint AddTimer(AbsTimerData p)
        {
            lock (m_queueLock)
                m_queue.Enqueue(p.NTimerId, p, p.UnNextTick);
            return p.NTimerId;
        }

        private static T GetTimerData<T>(T p, uint start, int interval) where T : AbsTimerData
        {
            p.NInterval = interval;
            p.NTimerId = ++m_nNextTimerId;
            p.UnNextTick = m_unTick + 1 + start;
            return p;
        }
    }

支付宝捐赠

打赏红包

你可能感兴趣的:(Unity3d,C#)