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;
}
}