378 lines
9.9 KiB
C#
378 lines
9.9 KiB
C#
using System;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using System.Collections.Generic;
|
|
|
|
namespace BingoBrain.Core
|
|
{
|
|
public class UFdsa : MonoBehaviour
|
|
{
|
|
private class TimerTask
|
|
{
|
|
private UFdsa _mUFdsa;
|
|
|
|
private string name;
|
|
private TimerMode mode;
|
|
private float startTime;
|
|
private float duration;
|
|
|
|
private bool isBreak = false;
|
|
private float breakStart;
|
|
private float breakDuration = 0;
|
|
|
|
private Action timerEvent;
|
|
private Action<object[]> timerArgsEvent;
|
|
private object[] args = null;
|
|
|
|
public float TimeLeft => Mathf.Max(0f, duration - (_mUFdsa.GetTime() - startTime) + breakDuration);
|
|
|
|
public TimerTask(UFdsa uFdsa, string name, TimerMode mode, float startTime, float duration,
|
|
Action handler)
|
|
{
|
|
this._mUFdsa = uFdsa;
|
|
|
|
this.name = name;
|
|
this.mode = mode;
|
|
this.startTime = startTime;
|
|
this.duration = duration;
|
|
timerEvent = handler;
|
|
}
|
|
|
|
public TimerTask(UFdsa uFdsa, string name, TimerMode mode, float startTime, float duration,
|
|
Action<object[]> handler, params object[] args)
|
|
{
|
|
this._mUFdsa = uFdsa;
|
|
|
|
this.name = name;
|
|
this.mode = mode;
|
|
this.startTime = startTime;
|
|
this.duration = duration;
|
|
timerArgsEvent = handler;
|
|
this.args = args;
|
|
}
|
|
|
|
public void Run()
|
|
{
|
|
if (isBreak)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (TimeLeft > 0f)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (mode == TimerMode.Normal)
|
|
{
|
|
_mUFdsa.RemoveTimer(name);
|
|
}
|
|
else
|
|
{
|
|
startTime = _mUFdsa.GetTime();
|
|
breakDuration = 0;
|
|
}
|
|
|
|
timerEvent?.Invoke();
|
|
timerArgsEvent?.Invoke(args);
|
|
}
|
|
|
|
public void Break()
|
|
{
|
|
if (isBreak)
|
|
{
|
|
return;
|
|
}
|
|
|
|
isBreak = true;
|
|
breakStart = _mUFdsa.GetTime();
|
|
}
|
|
|
|
public void Resume()
|
|
{
|
|
if (!isBreak)
|
|
{
|
|
return;
|
|
}
|
|
|
|
breakDuration += (_mUFdsa.GetTime() - breakStart);
|
|
isBreak = false;
|
|
}
|
|
|
|
public static implicit operator bool(TimerTask timerTask)
|
|
{
|
|
return null != timerTask;
|
|
}
|
|
}
|
|
|
|
private enum TimerMode
|
|
{
|
|
Normal,
|
|
Repeat,
|
|
}
|
|
|
|
private Dictionary<string, TimerTask> addTimerList = new();
|
|
private Dictionary<string, TimerTask> timerList = new();
|
|
private List<string> destroyTimerList = new();
|
|
|
|
[SerializeField] private string timerName;
|
|
private TimerTimeType type = TimerTimeType.Null;
|
|
|
|
public void SetTimer(string name, TimerTimeType type)
|
|
{
|
|
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 (destroyTimerList.Count > 0)
|
|
{
|
|
foreach (var i in destroyTimerList)
|
|
{
|
|
timerList.Remove(i);
|
|
}
|
|
|
|
destroyTimerList.Clear();
|
|
}
|
|
|
|
if (addTimerList.Count > 0)
|
|
{
|
|
foreach (var i in addTimerList.Where(i => i.Value != null))
|
|
{
|
|
timerList[i.Key] = i.Value;
|
|
}
|
|
|
|
addTimerList.Clear();
|
|
}
|
|
|
|
if (timerList.Count > 0)
|
|
{
|
|
foreach (var timer in timerList.Values)
|
|
{
|
|
if (timer == null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
timer.Run();
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool AddTimer(string key, float duration, Action handler)
|
|
{
|
|
return InternalAddTimer(key, TimerMode.Normal, duration, handler);
|
|
}
|
|
|
|
public bool AddTimer(string key, float duration, Action<object[]> handler, params object[] args)
|
|
{
|
|
return InternalAddTimer(key, TimerMode.Normal, duration, handler, args);
|
|
}
|
|
|
|
public bool AddRepeatTimer(string key, float duration, Action handler)
|
|
{
|
|
return InternalAddTimer(key, TimerMode.Repeat, duration, handler);
|
|
}
|
|
|
|
public bool AddRepeatTimer(string key, float duration, Action<object[]> handler, params object[] args)
|
|
{
|
|
return InternalAddTimer(key, TimerMode.Repeat, duration, handler, args);
|
|
}
|
|
|
|
private bool InternalAddTimer(string key, TimerMode mode, float duration, Action handler)
|
|
{
|
|
if (string.IsNullOrEmpty(key))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (duration <= 0.0f)
|
|
{
|
|
if (mode == TimerMode.Normal)
|
|
{
|
|
handler();
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("[HeavyTimer]Add Repeat Timer Error: Time is Not Greater Than Zero");
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
var timer = new TimerTask(this, key, mode, GetTime(), duration, handler);
|
|
addTimerList[key] = timer;
|
|
return true;
|
|
}
|
|
|
|
private bool InternalAddTimer(string key, TimerMode mode, float duration, Action<object[]> handler,
|
|
params object[] args)
|
|
{
|
|
if (string.IsNullOrEmpty(key))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (duration <= 0.0f)
|
|
{
|
|
if (mode == TimerMode.Normal)
|
|
{
|
|
handler(args);
|
|
}
|
|
else
|
|
{
|
|
Debug.LogError("[HeavyTimer]Add Repeat Timer Error: Time is Not Greater Than Zero");
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
var timer = new TimerTask(this, key, mode, GetTime(), duration, handler, args);
|
|
addTimerList[key] = timer;
|
|
return true;
|
|
}
|
|
|
|
public void BreakTimerWithPrefix(string prefix)
|
|
{
|
|
if (timerList is { Count: > 0 })
|
|
{
|
|
var arr = new string[timerList.Count];
|
|
timerList.Keys.CopyTo(arr, 0);
|
|
|
|
foreach (var t in arr)
|
|
{
|
|
if (t.StartsWith(prefix))
|
|
{
|
|
BreakTimer(t);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void BreakTimer(string key)
|
|
{
|
|
if (!timerList.ContainsKey(key))
|
|
{
|
|
return;
|
|
}
|
|
|
|
var timer = timerList[key];
|
|
timer.Break();
|
|
}
|
|
|
|
public void ResumeTimerWithPrefix(string prefix)
|
|
{
|
|
if (timerList is { Count: > 0 })
|
|
{
|
|
var arr = new string[timerList.Count];
|
|
timerList.Keys.CopyTo(arr, 0);
|
|
|
|
foreach (var t in arr)
|
|
{
|
|
if (t.StartsWith(prefix))
|
|
{
|
|
ResumeTimer(t);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void ResumeTimer(string key)
|
|
{
|
|
if (!timerList.ContainsKey(key))
|
|
{
|
|
return;
|
|
}
|
|
|
|
var timer = timerList[key];
|
|
timer.Resume();
|
|
}
|
|
|
|
public void ClearTimerWithPrefix(string prefix)
|
|
{
|
|
if (timerList is { Count: > 0 })
|
|
{
|
|
foreach (var timerKey in timerList.Keys.Where(timerKey => timerKey.StartsWith(prefix)))
|
|
{
|
|
RemoveTimer(timerKey);
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool RemoveTimer(string key)
|
|
{
|
|
if (!timerList.ContainsKey(key))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!destroyTimerList.Contains(key))
|
|
{
|
|
destroyTimerList.Add(key);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public bool IsRunning(string key)
|
|
{
|
|
return timerList.ContainsKey(key);
|
|
}
|
|
|
|
public float GetTimerLeft(string key)
|
|
{
|
|
if (!timerList.ContainsKey(key))
|
|
{
|
|
return 0.0f;
|
|
}
|
|
|
|
var timer = timerList[key];
|
|
return timer.TimeLeft;
|
|
}
|
|
|
|
public float GetTimerLeftWithPrefix(string prefix)
|
|
{
|
|
if (timerList is { Count: > 0 })
|
|
{
|
|
var arr = new string[timerList.Count];
|
|
timerList.Keys.CopyTo(arr, 0);
|
|
|
|
return (from t in arr where t.StartsWith(prefix) select GetTimerLeft(t)).FirstOrDefault();
|
|
}
|
|
|
|
return 0.0f;
|
|
}
|
|
|
|
public void ClearAll()
|
|
{
|
|
addTimerList.Clear();
|
|
timerList.Clear();
|
|
destroyTimerList.Clear();
|
|
}
|
|
|
|
public void Destroy()
|
|
{
|
|
Destroy(this);
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
ClearAll();
|
|
addTimerList = null;
|
|
timerList = null;
|
|
destroyTimerList = null;
|
|
}
|
|
}
|
|
} |