using System; using System.Collections; using System.Collections.Generic; using UnityEngine; public delegate void EnterFrameUpdate(float timeElapsed); public class EnterFrameManager : MonoBehaviour { private Dictionary<object, EnterFrameUpdate> enterFrameCallbacks = new Dictionary<object, EnterFrameUpdate>(); private Dictionary<object, EnterFrameUpdate> addQueue = new Dictionary<object, EnterFrameUpdate>(); private List<object> removeQueue = new List<object>(); public Action<Exception> OnException = null; public void Add(object obj, EnterFrameUpdate func) { // If the item is marked for removal, cancel the removal. if (removeQueue.Contains(obj)) { removeQueue.Remove(obj); // don't add to the queue if this item is already active if (enterFrameCallbacks.ContainsKey(obj)) return; } // Queue (if we aren't already adding this object...) if (!addQueue.ContainsKey(obj)) { addQueue.Add(obj, func); } } public void Remove(object obj) { // If we haven't added this object yet, just remove it from the add queue if (addQueue.ContainsKey(obj)) { addQueue.Remove(obj); return; } // Queue for removal if (!removeQueue.Contains(obj)) { removeQueue.Add(obj); } } public int LastItemsUpdated = 0; public float LastTimeUpdated = 0; void Update() { float timeElapsed = Time.deltaTime; foreach (object obj in removeQueue) { if (enterFrameCallbacks.ContainsKey(obj)) { enterFrameCallbacks.Remove(obj); } } removeQueue.Clear(); foreach (KeyValuePair<object, EnterFrameUpdate> add in addQueue) { if (!enterFrameCallbacks.ContainsKey(add.Key)) { enterFrameCallbacks.Add(add.Key, add.Value); } } addQueue.Clear(); LastItemsUpdated = 0; foreach (KeyValuePair<object, EnterFrameUpdate> entry in enterFrameCallbacks) { if (OnException == null) { entry.Value(timeElapsed); LastItemsUpdated++; } else { try { entry.Value(timeElapsed); LastItemsUpdated++; } catch (Exception e) { OnException(e); } } } LastTimeUpdated = timeElapsed; } }