You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			275 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			C#
		
	
			
		
		
	
	
			275 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			C#
		
	
| 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();
 | |
|         }
 | |
|     }
 | |
| }
 |