任务定时器

任务定时器模块(后续会随着经验增加不断完善)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public delegate void TaskTimerCallBack(object param);
public class TaskTimer 
{
    
    
    private Dictionary<TaskTimerCallBack, TaskTimerParameter> _dicToAdd;
    private Dictionary<TaskTimerCallBack, TaskTimerParameter> _dicItems;
    private List<TaskTimerParameter> _listToRemove;
    private List<TaskTimerParameter> _listPool;
    private GameObject taskTimerGameObject;
    //后续可以开启携程之类的
    private TimerEngine timerEngine;
    private TaskTimer()
    {
    
    
        taskTimerGameObject = new GameObject("TaskTimer");
        taskTimerGameObject.SetActive(true);
        Object.DontDestroyOnLoad(taskTimerGameObject);
        timerEngine = taskTimerGameObject.AddComponent<TimerEngine>();
        _dicToAdd = new Dictionary<TaskTimerCallBack, TaskTimerParameter>();
        _dicItems = new Dictionary<TaskTimerCallBack, TaskTimerParameter>();
        _listToRemove = new List<TaskTimerParameter>();
        _listPool = new List<TaskTimerParameter>();
    }
    #region 单例
    private static TaskTimer _instance;
    public static TaskTimer Ins
    {
    
    
        get
        {
    
    
            if (_instance == null)
            {
    
    
                _instance = new TaskTimer();
            }
            return _instance;
        }
    }
    #endregion
    /// <summary>
    /// 增加一个间隔时间执行固定次数的定时任务(带有回调参数)
    /// </summary>
    /// <param name="interval">间隔时间</param>
    /// <param name="repeat">重复次数</param>
    /// <param name="taskTimerCallBack">任务回调</param>
    /// <param name="param">回调参数</param>
    public void Add(float interval,int repeat,TaskTimerCallBack taskTimerCallBack, object param)
    {
    
    
        if (taskTimerCallBack == null)
        {
    
    
            return;
        }
        TaskTimerParameter parameter;
        if (_dicToAdd.TryGetValue(taskTimerCallBack,out parameter))
        {
    
    
            Debug.LogError("不能重复添加TaskTimerCallBack");
            return;
        }
        parameter = GetFromPool();
        parameter.Set(interval, repeat, taskTimerCallBack, param);
        _dicToAdd.Add(taskTimerCallBack, parameter);
    }
    /// <summary>
    /// 增加一个间隔时间执行的定时任务(带有回调参数)
    /// </summary>
    /// <param name="interval">间隔时间</param>
    /// <param name="taskTimerCallBack">回调</param>
    /// <param name="param">回调参数</param>
    public void AddIntervalTaskTimer(float interval,TaskTimerCallBack taskTimerCallBack,object param)
    {
    
    
        Add(interval, 0, taskTimerCallBack, param);
    }
    /// <summary>
    /// 增加一个间隔时间执行的定时任务(没有回调参数)
    /// </summary>
    /// <param name="interval">间隔时间</param>
    /// <param name="taskTimerCallBack">回调</param>
    public void AddIntervalTaskTimer(float interval,TaskTimerCallBack taskTimerCallBack)
    {
    
    
        Add(interval, 0, taskTimerCallBack, null);
    }
    public void Remove(TaskTimerCallBack taskTimerCallBack)
    {
    
    
        TaskTimerParameter parameter;
        //如果还没有假如到Item中
        if (_dicToAdd.TryGetValue(taskTimerCallBack,out parameter))
        {
    
    
            _dicToAdd.Remove(taskTimerCallBack);
            ReturnToPool(parameter);
        }
        //如果任务定时器已经在执行
        if (_dicItems.TryGetValue(taskTimerCallBack, out parameter))
        {
    
    
            parameter.SetDeleted();
        }
    }
    private TaskTimerParameter GetFromPool()
    {
    
    
        TaskTimerParameter parameter;
        int cnt = _listPool.Count;
        if (cnt > 0)
        {
    
    
            parameter = _listPool[cnt - 1];
            _listPool.Remove(parameter);
        }
        else
        {
    
    
            parameter = new TaskTimerParameter();
        }
        return parameter;
    }
    private void ReturnToPool(TaskTimerParameter parameter)
    {
    
    
        parameter.Reset();
        _listPool.Add(parameter);
    }
    public void Update()
    {
    
    
        float dt = Time.deltaTime;
        Dictionary<TaskTimerCallBack, TaskTimerParameter>.Enumerator _iter;
        //首先判断当前拥有的
        if (_dicItems.Count > 0)
        {
    
    
            _iter = _dicItems.GetEnumerator();
            while (_iter.MoveNext())
            {
    
    
                TaskTimerParameter parameter = _iter.Current.Value;
                //如果在执行过程中客户端删除了任务定时器
                if (parameter.deleted)
                {
    
    
                    _listToRemove.Add(parameter);
                    continue;
                }
                parameter.timer += dt;
                if (parameter.timer < parameter.interval)
                {
    
    
                    continue;
                }
                parameter.ResetTimer();
                //清注意这里设计。如果有重复次数 才会去将当前定时器加入到删除列表
                //如果为0或者小于0,是不会去假如到删除列表的,也就意味着无限执行,也就意味着一直会执行
                if (parameter.repeat > 0)
                {
    
    
                    parameter.repeat--;
                    if (parameter.repeat == 0)
                    {
    
    
                        //任务完成 假如到移除列表
                        parameter.SetDeleted();
                        _listToRemove.Add(parameter);
                    }
                }
                //执行CallBack。
                if (parameter.taskTimerCallBack != null)
                {
    
    
                    try
                    {
    
    
                        parameter.taskTimerCallBack(parameter.param);
                    }
                    catch (System.Exception e)
                    {
    
    

                        Debug.LogError(e);
                    }
                }
            }
            _iter.Dispose();
        }
        //其次是需要删除的
        int len = _listToRemove.Count;
        if (len > 0)
        {
    
    
            for (int k = 0; k < len; k++)
            {
    
    
                TaskTimerParameter parameter = _listToRemove[k];
                if (parameter.taskTimerCallBack != null)
                {
    
    
                    _dicItems.Remove(parameter.taskTimerCallBack);
                    ReturnToPool(parameter);
                }
            }
            _listToRemove.Clear();
        }
        //最后是需要添加的
        int cnt = _dicToAdd.Count;
        if (cnt > 0)
        {
    
    
            _iter = _dicToAdd.GetEnumerator();
            while (_iter.MoveNext())
            {
    
    
                _dicItems.Add(_iter.Current.Key, _iter.Current.Value);
            }
            _iter.Dispose();
            _dicToAdd.Clear();
        }
    }
}
public class TimerEngine : MonoBehaviour
{
    
    
    private void Update()
    {
    
    
        TaskTimer.Ins.Update();
    }
}
public class TaskTimerParameter
{
    
    
    public float interval;
    public int repeat;
    public TaskTimerCallBack taskTimerCallBack;
    public object param;
    public float timer;
    public bool deleted {
    
     get; private set; }
    public void Set(float interval,int repeat,TaskTimerCallBack taskTimerCallBack,object param)
    {
    
    
        this.interval = interval;
        this.repeat = repeat;
        this.taskTimerCallBack = taskTimerCallBack;
        this.param = param;
        this.deleted = false;
    }
    public void Reset()
    {
    
    
        this.interval = 0f;
        this.repeat = 0;
        this.taskTimerCallBack = null;
        this.param = null;
        this.timer = 0f;
        this.deleted = false;
    }
    public void ResetTimer()
    {
    
    
        this.timer = 0f;
    }
    public void SetDeleted()
    {
    
    
        this.deleted = true;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_39691716/article/details/121414038