Files
ZooMatch-GP/Assets/Scripts/ToolKit/GeneralKit/Timer/Timer.cs
T

175 lines
5.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace ZooMatch
{
public class TimerTask
{
private Timer timer;
public int repeatCount;
public float interval;
private Action<TimerTask> onCallBack;
public object[] args;
public float time;
public bool isActive = true;
public bool isFrameUpdate = false;
public TimerTask(Timer timer, float interval, Action<TimerTask> onCallBack, params object[] args)
{
this.timer = timer;
repeatCount = 1;
this.interval = interval;
this.onCallBack = onCallBack;
this.args = args;
time = timer.GetTriggerTime(interval);
}
public TimerTask(Timer timer, int repeatCount, float interval, Action<TimerTask> onCallBack,
params object[] args)
{
this.timer = timer;
this.repeatCount = repeatCount;
this.interval = interval;
this.onCallBack = onCallBack;
this.args = args;
time = timer.GetTriggerTime(interval);
}
public TimerTask(Timer timer, Action<TimerTask> onCallBack, params object[] args)
{
this.timer = timer;
this.onCallBack = onCallBack;
this.args = args;
}
public void CallFunc()
{
onCallBack?.Invoke(this);
}
public static implicit operator bool(TimerTask timerTask)
{
return null != timerTask;
}
}
public class Timer : MonoBehaviour
{
public const int INFINITE_LOOP = -1;
private List<TimerTask> timerTaskList = new();
private List<TimerTask> timerTaskTriggers = new();
[SerializeField] private string timerName;
private TimerTimeType type = TimerTimeType.Null;
public void SetTimer(string name, TimerTimeType type)
{
this.timerName = name + "_" + type;
this.type = type;
}
private float GetTime()
{
return type switch
{
TimerTimeType.Time => Time.time,
TimerTimeType.UnscaledTime => Time.unscaledTime,
TimerTimeType.RealtimeSinceStartup => Time.realtimeSinceStartup,
_ => 0
};
}
private void Update()
{
if (timerTaskList.Count > 0)
{
timerTaskTriggers.Clear();
foreach (var timerTask in timerTaskList.Where(timerTask => timerTask.isActive))
{
if (timerTask.isFrameUpdate)
{
timerTaskTriggers.Add(timerTask);
}
else
{
if (timerTask.time <= GetTime())
{
timerTaskTriggers.Add(timerTask);
}
}
}
foreach (var triggerTimerTask in timerTaskTriggers)
{
if (triggerTimerTask.repeatCount != INFINITE_LOOP)
{
triggerTimerTask.repeatCount--;
}
if (triggerTimerTask.repeatCount == 0)
{
timerTaskList.Remove(triggerTimerTask);
}
else
{
if (!triggerTimerTask.isFrameUpdate)
{
triggerTimerTask.time = GetTriggerTime(triggerTimerTask.interval);
}
}
triggerTimerTask.CallFunc();
}
}
}
public TimerTask AddLoopTimer(float interval, Action<TimerTask> onCallBack, params object[] args)
{
var timeTask = new TimerTask(this, INFINITE_LOOP, interval, onCallBack, args);
AddTimer(timeTask);
return timeTask;
}
public void AddTimer(TimerTask timerTask)
{
if (null != timerTask)
{
if (!timerTask.isFrameUpdate)
{
if (timerTask.interval <= 0)
{
timerTask.CallFunc();
return;
}
}
timerTaskList.Add(timerTask);
}
}
public void ClearAll()
{
timerTaskList.Clear();
timerTaskTriggers.Clear();
}
public float GetTriggerTime(float interval)
{
return GetTime() + interval;
}
private void OnDestroy()
{
ClearAll();
timerTaskList = null;
timerTaskTriggers = null;
}
}
}