任务定时器模块(后续会随着经验增加不断完善)
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
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);
}
public void AddIntervalTaskTimer(float interval,TaskTimerCallBack taskTimerCallBack,object param)
{
Add(interval, 0, taskTimerCallBack, param);
}
public void AddIntervalTaskTimer(float interval,TaskTimerCallBack taskTimerCallBack)
{
Add(interval, 0, taskTimerCallBack, null);
}
public void Remove(TaskTimerCallBack taskTimerCallBack)
{
TaskTimerParameter parameter;
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();
if (parameter.repeat > 0)
{
parameter.repeat--;
if (parameter.repeat == 0)
{
parameter.SetDeleted();
_listToRemove.Add(parameter);
}
}
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;
}
}