119 lines
3.1 KiB
C#
119 lines
3.1 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using Logic.CrashSight;
|
||
using UnityEngine;
|
||
|
||
|
||
public class Timer
|
||
{
|
||
public static Timer Instance { get; private set; }
|
||
|
||
private List<TimerTask> tasks = new List<TimerTask>(); // 存储所有定时任务
|
||
|
||
private class TimerTask
|
||
{
|
||
public object target; // 目标对象 A
|
||
public Action method; // 方法 B
|
||
public float executeTime; // 任务执行时间(Time.time + C 毫秒)
|
||
public string errorMessage;
|
||
}
|
||
|
||
public Timer()
|
||
{
|
||
Instance = this;
|
||
}
|
||
|
||
// 注册定时任务
|
||
public void TimerRegister(object A, Action B, float C,string message)
|
||
{
|
||
if (B == null) return;
|
||
if (IsTargetDestroyed(A)) return;
|
||
tasks.Add(new TimerTask
|
||
{
|
||
target = A,
|
||
method = B,
|
||
executeTime = Time.time + C,
|
||
errorMessage = message
|
||
});
|
||
}
|
||
|
||
public void CancelByTarget(object target)
|
||
{
|
||
if (target == null) return;
|
||
for (int i = tasks.Count - 1; i >= 0; i--)
|
||
{
|
||
if (ReferenceEquals(tasks[i].target, target))
|
||
tasks.RemoveAt(i);
|
||
}
|
||
}
|
||
|
||
public void CancelByMessage(string message)
|
||
{
|
||
if (string.IsNullOrEmpty(message)) return;
|
||
for (int i = tasks.Count - 1; i >= 0; i--)
|
||
{
|
||
if (tasks[i].errorMessage == message)
|
||
tasks.RemoveAt(i);
|
||
}
|
||
}
|
||
|
||
public void Clear()
|
||
{
|
||
tasks.Clear();
|
||
}
|
||
|
||
public void Update()
|
||
{
|
||
if (tasks.Count == 0) return;
|
||
|
||
float currentTime = Time.time;
|
||
var i = tasks.Count - 1;
|
||
while (i >= 0)
|
||
{
|
||
if (i >= tasks.Count)
|
||
{
|
||
i = tasks.Count - 1;
|
||
continue;
|
||
}
|
||
|
||
var task = tasks[i];
|
||
if (IsTargetDestroyed(task.target))
|
||
{
|
||
tasks.RemoveAt(i);
|
||
i = Math.Min(i - 1, tasks.Count - 1);
|
||
continue;
|
||
}
|
||
|
||
if (currentTime >= task.executeTime)
|
||
{
|
||
try
|
||
{
|
||
task.method?.Invoke();
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
LogSystem.LogError($"Timer任务执行异常:\n" +
|
||
$"错误信息: {task.errorMessage}\n" +
|
||
$"异常类型: {e.GetType()}\n" +
|
||
$"异常信息: {e.Message}\n" +
|
||
$"调用堆栈: {e.StackTrace}\n" +
|
||
$"目标对象: {(task.target != null ? task.target.GetType().Name : "null")}"
|
||
);
|
||
}
|
||
|
||
var taskIndex = tasks.IndexOf(task);
|
||
if (taskIndex >= 0) tasks.RemoveAt(taskIndex); // 执行完毕后移除
|
||
}
|
||
|
||
i = Math.Min(i - 1, tasks.Count - 1);
|
||
}
|
||
}
|
||
|
||
private static bool IsTargetDestroyed(object target)
|
||
{
|
||
if (target is UnityEngine.Object unityObject)
|
||
return unityObject == null;
|
||
return false;
|
||
}
|
||
}
|