| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274 | using System.Collections.Generic;using System.Collections;using UnityEngine;namespace FairyGUI{    public delegate void TimerCallback(object param);    /// <summary>    ///     /// </summary>    public class Timers    {        public static int repeat;        public static float time;        public static bool catchCallbackExceptions = false;        Dictionary<TimerCallback, Anymous_T> _items;        Dictionary<TimerCallback, Anymous_T> _toAdd;        List<Anymous_T> _toRemove;        List<Anymous_T> _pool;        TimersEngine _engine;        GameObject gameObject;        private static Timers _inst;        public static Timers inst        {            get            {                if (_inst == null)                    _inst = new Timers();                return _inst;            }        }        public Timers()        {            _inst = this;            gameObject = new GameObject("[FairyGUI.Timers]");            gameObject.hideFlags = HideFlags.HideInHierarchy;            gameObject.SetActive(true);            Object.DontDestroyOnLoad(gameObject);            _engine = gameObject.AddComponent<TimersEngine>();            _items = new Dictionary<TimerCallback, Anymous_T>();            _toAdd = new Dictionary<TimerCallback, Anymous_T>();            _toRemove = new List<Anymous_T>();            _pool = new List<Anymous_T>(100);        }        public void Add(float interval, int repeat, TimerCallback callback)        {            Add(interval, repeat, callback, null);        }        /**         * @interval in seconds         * @repeat 0 indicate loop infinitely, otherwise the run count         **/        public void Add(float interval, int repeat, TimerCallback callback, object callbackParam)        {            if (callback == null)            {                Debug.LogWarning("timer callback is null, " + interval + "," + repeat);                return;            }            Anymous_T t;            if (_items.TryGetValue(callback, out t))            {                t.set(interval, repeat, callback, callbackParam);                t.elapsed = 0;                t.deleted = false;                return;            }            if (_toAdd.TryGetValue(callback, out t))            {                t.set(interval, repeat, callback, callbackParam);                return;            }            t = GetFromPool();            t.interval = interval;            t.repeat = repeat;            t.callback = callback;            t.param = callbackParam;            _toAdd[callback] = t;        }        public void CallLater(TimerCallback callback)        {            Add(0.001f, 1, callback);        }        public void CallLater(TimerCallback callback, object callbackParam)        {            Add(0.001f, 1, callback, callbackParam);        }        public void AddUpdate(TimerCallback callback)        {            Add(0.001f, 0, callback);        }        public void AddUpdate(TimerCallback callback, object callbackParam)        {            Add(0.001f, 0, callback, callbackParam);        }        public void StartCoroutine(IEnumerator routine)        {            _engine.StartCoroutine(routine);        }        public bool Exists(TimerCallback callback)        {            if (_toAdd.ContainsKey(callback))                return true;            Anymous_T at;            if (_items.TryGetValue(callback, out at))                return !at.deleted;            return false;        }        public void Remove(TimerCallback callback)        {            Anymous_T t;            if (_toAdd.TryGetValue(callback, out t))            {                _toAdd.Remove(callback);                ReturnToPool(t);            }            if (_items.TryGetValue(callback, out t))                t.deleted = true;        }        private Anymous_T GetFromPool()        {            Anymous_T t;            int cnt = _pool.Count;            if (cnt > 0)            {                t = _pool[cnt - 1];                _pool.RemoveAt(cnt - 1);                t.deleted = false;                t.elapsed = 0;            }            else                t = new Anymous_T();            return t;        }        private void ReturnToPool(Anymous_T t)        {            t.callback = null;            _pool.Add(t);        }        public void Update()        {            float dt = Time.unscaledDeltaTime;            Dictionary<TimerCallback, Anymous_T>.Enumerator iter;            if (_items.Count > 0)            {                iter = _items.GetEnumerator();                while (iter.MoveNext())                {                    Anymous_T i = iter.Current.Value;                    if (i.deleted)                    {                        _toRemove.Add(i);                        continue;                    }                    i.elapsed += dt;                    if (i.elapsed < i.interval)                        continue;                    i.elapsed -= i.interval;                    if (i.elapsed < 0 || i.elapsed > 0.03f)                        i.elapsed = 0;                    if (i.repeat > 0)                    {                        i.repeat--;                        if (i.repeat == 0)                        {                            i.deleted = true;                            _toRemove.Add(i);                        }                    }                    repeat = i.repeat;                    if (i.callback != null)                    {                        if (catchCallbackExceptions)                        {                            try                            {                                i.callback(i.param);                            }                            catch (System.Exception e)                            {                                i.deleted = true;                                Debug.LogWarning("FairyGUI: timer(internal=" + i.interval + ", repeat=" + i.repeat + ") callback error > " + e.Message);                            }                        }                        else                            i.callback(i.param);                    }                }                iter.Dispose();            }            int len = _toRemove.Count;            if (len > 0)            {                for (int k = 0; k < len; k++)                {                    Anymous_T i = _toRemove[k];                    if (i.deleted && i.callback != null)                    {                        _items.Remove(i.callback);                        ReturnToPool(i);                    }                }                _toRemove.Clear();            }            if (_toAdd.Count > 0)            {                iter = _toAdd.GetEnumerator();                while (iter.MoveNext())                    _items.Add(iter.Current.Key, iter.Current.Value);                iter.Dispose();                _toAdd.Clear();            }        }    }    class Anymous_T    {        public float interval;        public int repeat;        public TimerCallback callback;        public object param;        public float elapsed;        public bool deleted;        public void set(float interval, int repeat, TimerCallback callback, object param)        {            this.interval = interval;            this.repeat = repeat;            this.callback = callback;            this.param = param;        }    }    class TimersEngine : MonoBehaviour    {        void Update()        {            Timers.inst.Update();        }    }}
 |