using System; using System.Linq; using UnityEngine; using System.Collections.Generic; namespace BallKingdomCrush { public class NormalTimer : MonoBehaviour { private class TimerTask { private NormalTimer mNormalTimer; 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 timerArgsEvent; private object[] args = null; public float TimeLeft => Mathf.Max(0f, duration - (mNormalTimer.GetTime() - startTime) + breakDuration); public void Run() { if (isBreak) { return; } if (TimeLeft > 0f) { return; } if (mode == TimerMode.Normal) { mNormalTimer.RemoveTimer(name); } else { startTime = mNormalTimer.GetTime(); breakDuration = 0; } timerEvent?.Invoke(); timerArgsEvent?.Invoke(args); } public static implicit operator bool(TimerTask timerTask) { return null != timerTask; } } private enum TimerMode { Normal, Repeat, } private Dictionary addTimerList = new(); private Dictionary timerList = new(); private List 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 RemoveTimer(string key) { if (!timerList.ContainsKey(key)) { return false; } if (!destroyTimerList.Contains(key)) { destroyTimerList.Add(key); } return true; } public void ClearAll() { addTimerList.Clear(); timerList.Clear(); destroyTimerList.Clear(); } private void OnDestroy() { ClearAll(); addTimerList = null; timerList = null; destroyTimerList = null; } } }