using System; using System.Collections.Generic; using System.Linq; using UnityEngine; namespace BingoBrain.Core { public class Psvsagh { private Psvsa _psvsa; public int repeatCount; public float interval; private Action onCallBack; public object[] args; public float time; public bool isActive = true; public bool isFrameUpdate = false; public Psvsagh(Psvsa psvsa, float interval, Action onCallBack, params object[] args) { this._psvsa = psvsa; repeatCount = 1; this.interval = interval; this.onCallBack = onCallBack; this.args = args; time = psvsa.GetTriggerTime(interval); } public Psvsagh(Psvsa psvsa, int repeatCount, float interval, Action onCallBack, params object[] args) { this._psvsa = psvsa; this.repeatCount = repeatCount; this.interval = interval; this.onCallBack = onCallBack; this.args = args; time = psvsa.GetTriggerTime(interval); } public Psvsagh(Psvsa psvsa, Action onCallBack, params object[] args) { this._psvsa = psvsa; this.onCallBack = onCallBack; this.args = args; } public void SetActive(bool isActive) { if (this.isActive == isActive) return; this.isActive = isActive; if (!isFrameUpdate) { if (this.isActive) { time = _psvsa.GetTriggerTime(interval); } } } public void CallFunc() { onCallBack?.Invoke(this); } public void Kill(bool needComplete = false) { if (needComplete) { CallFunc(); } Dispose(); } public void Dispose() { _psvsa.RemoveTimer(this); } public static implicit operator bool(Psvsagh psvsagh) { return null != psvsagh; } } public class Psvsa : MonoBehaviour { public const int INFINITE_LOOP = -1; private List timerTaskList = new(); private List 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 Psvsagh AddTimer(float interval, Action onCallBack, params object[] args) { var timeTask = new Psvsagh(this, interval, onCallBack, args); AddTimer(timeTask); return timeTask; } public Psvsagh AddRepeatTimer(int repeatCount, float interval, Action onCallBack, params object[] args) { var timeTask = new Psvsagh(this, repeatCount, interval, onCallBack, args); AddTimer(timeTask); return timeTask; } public Psvsagh AddLoopTimer(float interval, Action onCallBack, params object[] args) { var timeTask = new Psvsagh(this, INFINITE_LOOP, interval, onCallBack, args); AddTimer(timeTask); return timeTask; } public Psvsagh AddFrameUpdateTimer(Action onCallBack, params object[] args) { var timeTask = new Psvsagh(this, onCallBack, args) { repeatCount = INFINITE_LOOP, isFrameUpdate = true }; AddTimer(timeTask); return timeTask; } public void AddTimer(Psvsagh psvsagh) { if (null != psvsagh) { if (!psvsagh.isFrameUpdate) { if (psvsagh.interval <= 0) { psvsagh.CallFunc(); return; } } timerTaskList.Add(psvsagh); } } public void RemoveTimer(Psvsagh psvsagh) { if (psvsagh == null) return; if (timerTaskList == null) return; if (timerTaskList.Count == 0) return; if (timerTaskList.Contains(psvsagh)) { timerTaskList.Remove(psvsagh); } } public void ClearAll() { timerTaskList.Clear(); timerTaskTriggers.Clear(); } public void Destroy() { Destroy(this); } public float GetTriggerTime(float interval) { return GetTime() + interval; } private void OnDestroy() { ClearAll(); timerTaskList = null; timerTaskTriggers = null; } } }