using System; using System.Collections.Generic; using UnityEngine; namespace XUtliPoolLib { public sealed class XTimerMgr : XSingleton { public double Elapsed { get { return this._elapsed; } } public bool NeedFixedUpdate { get { return this._fixedUpdate; } } private uint _token = 0u; private double _elapsed = 0.0; private Queue _pool = new Queue(); private XHeap _timers = new XHeap(); private Dictionary _dict = new Dictionary(20); private float _intervalTime = 0f; private float _updateTime = 0.1f; private bool _fixedUpdate = false; public bool update = true; public float updateStartTime = 0f; public delegate void ElapsedEventHandler(object param); public delegate void AccurateElapsedEventHandler(object param, float delay); public delegate void ElapsedIDEventHandler(object param, int id); private sealed class XTimer : IComparable, IHere { public double TriggerTime { get { return this._triggerTime; } } public bool IsGlobaled { get { return this._global; } } public bool IsInPool { get; set; } public uint Token { get { return this._token; } } public int Here { get; set; } public int Id { get; set; } private double _triggerTime; private object _param; private object _handler; private bool _global = false; private uint _token = 0u; public XTimer(double trigger, object handler, object parma, uint token, bool global, int id) { this.Refine(trigger, handler, parma, token, global, id); } public void Refine(double trigger, object handler, object parma, uint token, bool global, int id) { this._triggerTime = trigger; this._handler = handler; this._param = parma; this._global = global; this._token = token; this.Here = -1; this.IsInPool = false; this.Id = id; } public void Refine(double trigger) { this._triggerTime = trigger; } public void Fire(float delta) { bool flag = this._handler is XTimerMgr.AccurateElapsedEventHandler; if (flag) { (this._handler as XTimerMgr.AccurateElapsedEventHandler)(this._param, delta); } else { bool flag2 = this._handler is XTimerMgr.ElapsedIDEventHandler; if (flag2) { (this._handler as XTimerMgr.ElapsedIDEventHandler)(this._param, this.Id); } else { (this._handler as XTimerMgr.ElapsedEventHandler)(this._param); } } } public int CompareTo(XTimerMgr.XTimer other) { return (int)((this._triggerTime == other._triggerTime) ? (this._token - other.Token) : ((this._triggerTime < other._triggerTime) ? uint.MaxValue : 1u)); } public double TimeLeft() { return this._triggerTime - XSingleton.singleton.Elapsed; } } public uint SetTimer(float interval, XTimerMgr.ElapsedEventHandler handler, object param) { this._token += 1u; bool flag = interval <= 0f; if (flag) { handler(param); this._token += 1u; } else { double trigger = this._elapsed + Math.Round((double)interval, 3); XTimerMgr.XTimer timer = this.GetTimer(trigger, handler, param, this._token, false, -1); this._timers.PushHeap(timer); this._dict.Add(this._token, timer); } return this._token; } public uint SetTimer(float interval, XTimerMgr.ElapsedIDEventHandler handler, object param, TEnum e) where TEnum : struct { this._token += 1u; int id = XFastEnumIntEqualityComparer.ToInt(e); bool flag = interval <= 0f; if (flag) { handler(param, id); this._token += 1u; } else { double trigger = this._elapsed + Math.Round((double)interval, 3); XTimerMgr.XTimer timer = this.GetTimer(trigger, handler, param, this._token, false, id); this._timers.PushHeap(timer); this._dict.Add(this._token, timer); } return this._token; } public uint SetGlobalTimer(float interval, XTimerMgr.ElapsedEventHandler handler, object param) { this._token += 1u; bool flag = interval <= 0f; if (flag) { handler(param); this._token += 1u; } else { double trigger = this._elapsed + Math.Round((double)interval, 3); XTimerMgr.XTimer timer = this.GetTimer(trigger, handler, param, this._token, true, -1); this._timers.PushHeap(timer); this._dict.Add(this._token, timer); } return this._token; } public uint SetTimerAccurate(float interval, XTimerMgr.AccurateElapsedEventHandler handler, object param) { this._token += 1u; bool flag = interval <= 0f; if (flag) { handler(param, 0f); this._token += 1u; } else { double trigger = this._elapsed + Math.Round((double)interval, 3); XTimerMgr.XTimer timer = this.GetTimer(trigger, handler, param, this._token, false, -1); this._timers.PushHeap(timer); this._dict.Add(this._token, timer); } return this._token; } public void AdjustTimer(float interval, uint token, bool closed = false) { XTimerMgr.XTimer xtimer = null; bool flag = this._dict.TryGetValue(token, out xtimer) && !xtimer.IsInPool; if (flag) { double trigger = closed ? (this._elapsed - (double)(Time.deltaTime * 0.5f) + Math.Round((double)interval, 3)) : (this._elapsed + Math.Round((double)interval, 3)); double triggerTime = xtimer.TriggerTime; xtimer.Refine(trigger); this._timers.Adjust(xtimer, triggerTime < xtimer.TriggerTime); } } public void KillTimerAll() { List list = new List(); foreach (XTimerMgr.XTimer xtimer in this._dict.Values) { bool isGlobaled = xtimer.IsGlobaled; if (!isGlobaled) { list.Add(xtimer); } } for (int i = 0; i < list.Count; i++) { this.KillTimer(list[i]); } list.Clear(); } private void KillTimer(XTimerMgr.XTimer timer) { bool flag = timer == null; if (!flag) { this._timers.PopHeapAt(timer.Here); this.Discard(timer); } } public void KillTimer(uint token) { bool flag = token == 0u; if (!flag) { XTimerMgr.XTimer timer = null; bool flag2 = this._dict.TryGetValue(token, out timer); if (flag2) { this.KillTimer(timer); } } } public double TimeLeft(uint token) { XTimerMgr.XTimer xtimer = null; bool flag = this._dict.TryGetValue(token, out xtimer); double result; if (flag) { result = xtimer.TimeLeft(); } else { result = 0.0; } return result; } public void Update(float fDeltaT) { this._elapsed += (double)fDeltaT; this._intervalTime += fDeltaT; bool flag = this._intervalTime > this._updateTime; if (flag) { this._intervalTime = 0f; this._fixedUpdate = true; } this.TriggerTimers(); } public void PostUpdate() { this._fixedUpdate = false; } private void TriggerTimers() { while (this._timers.HeapSize > 0) { XTimerMgr.XTimer xtimer = this._timers.Peek(); float num = (float)(this._elapsed - xtimer.TriggerTime); bool flag = num >= 0f; if (!flag) { break; } this.ExecuteTimer(this._timers.PopHeap(), num); } } private void ExecuteTimer(XTimerMgr.XTimer timer, float delta) { this.Discard(timer); timer.Fire(delta); } private void Discard(XTimerMgr.XTimer timer) { bool isInPool = timer.IsInPool; if (!isInPool) { bool flag = this._dict.Remove(timer.Token); if (flag) { timer.IsInPool = true; this._pool.Enqueue(timer); } } } private XTimerMgr.XTimer GetTimer(double trigger, object handler, object parma, uint token, bool global, int id = -1) { bool flag = this._pool.Count > 0; XTimerMgr.XTimer result; if (flag) { XTimerMgr.XTimer xtimer = this._pool.Dequeue(); xtimer.Refine(trigger, handler, parma, token, global, id); result = xtimer; } else { result = new XTimerMgr.XTimer(trigger, handler, parma, token, global, id); } return result; } public override bool Init() { return true; } public override void Uninit() { } } }