我小小调整了下,自己能用using System;using System.Collections;using System.Collections.Generic;using System.Time...
我小小调整了下,自己能用
using System;
using System.Collections;
using System.Collections.Generic;
using System.Timers;
using UnityEngine;
//定时单位
public enum PETimeUnit
{
Millisecond,
Second,
Minute,
Hour,
Day
}
public class TimerUtil : MonoBehaviour
{
//时间定时任务
class PETimeTask
{
public int tid;
public Action callback;
public double destTime;
public double value;
public int count;
public PETimeTask(int tid, Action callback, double destTime, double value, int count)
{
this.tid = tid;
this.callback = callback;
this.destTime = destTime;
this.value = value;
this.count = count;
}
}
//帧定时任务
class PEFrameTask
{
public int tid;
public Action callback;
public int destFrame;
public int delay;
public int count;
public PEFrameTask(int tid, Action callback, int destFrame, int delay, int count)
{
this.tid = tid;
this.callback = callback;
this.destFrame = destFrame;
this.delay = delay;
this.count = count;
}
}
#region Data Area
private Action taskLog;
private Action, int> taskHandle;
private int tid;
private static readonly string obj = "lock";
private DateTime startDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0);
private double nowTime;
private List tidLst = new List();
private List tmpTimerLst = new List();
private List taskTimerLst = new List();
private int frameCounter = 0;
private List tmpFramerLst = new List();
private List taskFramerLst = new List();
#endregion
private static TimerUtil Instance = null;
public static TimerUtil InitSys(TimerUtil timerUtil = null)
{
if (Instance == null && timerUtil != null)
{
Instance = timerUtil;
Instance.tidLst.Clear();
Instance.tmpTimerLst.Clear();
Instance.taskTimerLst.Clear();
Instance.tmpFramerLst.Clear();
Instance.taskFramerLst.Clear();
print("TimerSys Init Done");
}
return Instance;
}
private void Awake()
{
if (Instance == null)
{
InitSys(this);
}
}
// Update is called once per frame
void Update()
{
//秒倒计时
CheckTimeTask();
//帧定时器
CheckFrameTask();
}
#region timerTask
public int AddTimeTask(Action callback, double delay, PETimeUnit timeUnit = PETimeUnit.Millisecond, int count = 1)
{
if (timeUnit != PETimeUnit.Millisecond)
{
switch (timeUnit)
{
case PETimeUnit.Second:
delay = delay * 1000;
break;
case PETimeUnit.Minute:
delay = delay * 1000 * 60;
break;
case PETimeUnit.Hour:
delay = delay * 1000 * 60 * 60;
break;
case PETimeUnit.Day:
delay = delay * 1000 * 60 * 60 * 24;
break;
default:
print("add task timeunit type error...");
break;
}
}
nowTime = GetUTCMilliseconds();
int code = callback.GetHashCode();
int tid = GetTid();
tmpTimerLst.Add(new PETimeTask(tid, callback, nowTime + delay, delay, count));
tidLst.Add(tid);
Debug.Log("add timeTask success:delay" + delay + " count" + count + " tid" + tid);
return tid;
}
public bool ReplaceTimeTask(int tid, Action callback, double delay, PETimeUnit timeUnit = PETimeUnit.Millisecond, int count = 1)
{
bool isRep = false;
if (tidLst.Contains(tid))
{
if (timeUnit != PETimeUnit.Millisecond)
{
switch (timeUnit)
{
case PETimeUnit.Second:
delay = delay * 1000;
break;
case PETimeUnit.Minute:
delay = delay * 1000 * 60;
break;
case PETimeUnit.Hour:
delay = delay * 1000 * 60 * 60;
break;
case PETimeUnit.Day:
delay = delay * 1000 * 60 * 60 * 24;
break;
default:
Debug.Log("replace task timeunit type error...");
break;
}
}
nowTime = GetUTCMilliseconds();
PETimeTask newTask = new PETimeTask(tid, callback, nowTime + delay, delay, count);
for (int i = 0; i < taskTimerLst.Count; i++)
{
if (taskTimerLst[i].tid == tid)
{
taskTimerLst[i] = newTask;
isRep = true;
break;
}
}
if (!isRep)
{
for (int i = 0; i < tmpTimerLst.Count; i++)
{
if (tmpTimerLst[i].tid == tid)
{
tmpTimerLst[i] = newTask;
isRep = true;
break;
}
}
}
}
Debug.Log("ReplaceTimeTask:" + isRep + " tid" + tid);
return isRep;
}
public bool DeleteTimeTask(int tid)
{
bool exist = false;
if (tidLst.Contains(tid))
{
for (int i = 0; i < taskTimerLst.Count; i++)
{
PETimeTask task = taskTimerLst[i];
if (task.tid == tid)
{
taskTimerLst.RemoveAt(i);
break;
}
}
for (int i = 0; i < tmpTimerLst.Count; i++)
{
PETimeTask task = tmpTimerLst[i];
if (task.tid == tid)
{
tmpTimerLst.RemoveAt(i);
break;
}
}
tidLst.Remove(tid);
exist = true;
}
Debug.Log("DeleteTimeTask tid" + tid + " "+ exist);
return exist;
}
public int AddFrameTask(Action callback, int frame, int count = 1)
{
int tid = GetTid();
tmpFramerLst.Add(new PEFrameTask(tid, callback, frameCounter + frame, frame, count));
tidLst.Add(tid);
Debug.Log("add frameTask success:frame" + frame + " count" + count + " tid" + tid);
return tid;
}
public bool ReplaceFrameTask(int tid, Action callback, int frame, int count = 1)
{
PEFrameTask newTask = new PEFrameTask(tid, callback, frameCounter + frame, frame, count);
bool isRep = false;
if (tidLst.Contains(tid))
{
for (int i = 0; i < taskFramerLst.Count; i++)
{
if (taskFramerLst[i].tid == tid)
{
taskFramerLst[i] = newTask;
isRep = true;
break;
}
}
if (!isRep)
{
for (int i = 0; i < tmpFramerLst.Count; i++)
{
if (tmpFramerLst[i].tid == tid)
{
tmpFramerLst[i] = newTask;
isRep = true;
break;
}
}
}
}
Debug.Log("ReplaceFrameTask tid" + tid + " " + isRep);
return isRep;
}
public bool DeleteFrameTask(int tid)
{
bool exist = false;
if (tidLst.Contains(tid))
{
for (int i = 0; i < taskFramerLst.Count; i++)
{
PEFrameTask task = taskFramerLst[i];
if (task.tid == tid)
{
taskFramerLst.RemoveAt(i);
break;
}
}
for (int i = 0; i < tmpFramerLst.Count; i++)
{
PEFrameTask task = tmpFramerLst[i];
if (task.tid == tid)
{
tmpFramerLst.RemoveAt(i);
break;
}
}
tidLst.Remove(tid);
exist = true;
}
Debug.Log("DeleteFrameTask tid" + tid + " " + exist);
return exist;
}
public void Reset()
{
tidLst.Clear();
tmpTimerLst.Clear();
taskTimerLst.Clear();
tmpFramerLst.Clear();
taskFramerLst.Clear();
tid = 0;
frameCounter = 0;
taskLog = null;
taskHandle = null;
Debug.Log("PETimer Reset");
}
#endregion
private int GetTid()
{
lock (obj)
{
AddTid();
for (int i = 0; i <= 99; i++)
{
if (tidLst.Contains(tid))
{
AddTid();
}
else
{
break;
}
if (i == 99)
{
Debug.Log("PETimer Error: Tid Busy being used");
}
}
}
return tid;
}
private int AddTid()
{
tid += 1;
//安全代码,以防万一
if (tid == int.MaxValue)
{
tid = 0;
}
return tid;
}
//时间定时器检测
private void CheckTimeTask()
{
for (int tmpIndex = 0; tmpIndex < tmpTimerLst.Count; tmpIndex++)
{
taskTimerLst.Add(tmpTimerLst[tmpIndex]);
}
tmpTimerLst.Clear();
nowTime = GetUTCMilliseconds();
for (int index = 0; index < taskTimerLst.Count; index++)
{
PETimeTask task = taskTimerLst[index];
if (nowTime.CompareTo(task.destTime) < 0)
{
continue;
}
else
{
Action cb = task.callback;
try
{
if (taskHandle != null)
{
taskHandle(cb, task.tid);
}
else
{
if (cb != null)
{
cb(task.tid);
}
}
}
catch (Exception e)
{
Debug.Log(e.ToString());
}
if (task.count == 1 && taskTimerLst.Count > 0)
{
try
{
taskTimerLst.RemoveAt(index);
tidLst.Remove(task.tid);
index--;
}
catch (Exception e)
{
Debug.Log(e.ToString());
}
}
else
{
if (task.count != 0)
{
task.count -= 1;
}
task.destTime = task.destTime + task.value;
}
}
}
}
//帧定时器检测
private void CheckFrameTask()
{
for (int tmpIndex = 0; tmpIndex < tmpFramerLst.Count; tmpIndex++)
{
taskFramerLst.Add(tmpFramerLst[tmpIndex]);
}
tmpFramerLst.Clear();
frameCounter += 1;
for (int index = 0; index < taskFramerLst.Count; index++)
{
PEFrameTask task = taskFramerLst[index];
if (frameCounter.CompareTo(task.destFrame) < 0)
continue;
else
{
Action cb = task.callback;
try
{
if (taskHandle != null)
{
taskHandle(cb, task.tid);
}
else
{
if (cb != null)
{
cb(task.tid);
}
}
}
catch (Exception e)
{
Debug.Log(e.ToString());
}
if (task.count == 1 && taskFramerLst.Count > 0)
{
try
{
taskFramerLst.RemoveAt(index);
tidLst.Remove(task.tid);
index--;
}
catch (Exception e)
{
Debug.Log(e.ToString());
}
}
else
{
if (task.count != 0)
{
task.count -= 1;
}
task.destFrame = task.destFrame + task.delay;
}
}
}
}
private double GetUTCMilliseconds()
{
TimeSpan ts = DateTime.UtcNow - startDateTime;
return ts.TotalMilliseconds;
}
}