using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
public class TimerManager : MonoBehaviour
{
private static TimerManager m_Instance = null;
public static TimerManager Instance
{
get
{
if (m_Instance == null)
{
m_Instance = FindObjectOfType<TimerManager>();
if (m_Instance == null)
{
m_Instance = new GameObject("TimerManager").AddComponent<TimerManager>();
}
}
return m_Instance;
}
}
private class TimeItem
{
private float duration;
private float timer;
public bool isDone { get; private set; }
private UnityAction OnComplete;
public TimeItem(float duration, UnityAction oncomplete)
{
Reset(duration, oncomplete);
}
public void Update(float time)
{
if (isDone)
{
return;
}
timer += time;
if (timer >= duration)
{
isDone = true;
if (OnComplete != null)
{
OnComplete();
OnComplete = null;
}
}
}
public void Reset(float duration, UnityAction oncomplete)
{
timer = 0;
isDone = false;
this.duration = duration;
OnComplete = oncomplete;
}
}
private void Awake()
{
if (m_Instance == null)
{
m_Instance = this;
}
}
private List<TimeItem> tasks = new List<TimeItem>();
private List<TimeItem> add_tasks = new List<TimeItem>();
private List<TimeItem> recycle_tasks = new List<TimeItem>();
public void NewTimer(float duration, UnityAction oncomplete)
{
TimeItem timeItem = GetOneTimeItem(duration, oncomplete);
add_tasks.Add(timeItem);
}
private TimeItem GetOneTimeItem(float duration, UnityAction oncomplete)
{
TimeItem timeItem;
if (recycle_tasks.Count > 0)
{
timeItem = recycle_tasks[0];
timeItem.Reset(duration, oncomplete);
recycle_tasks.RemoveAt(0);
}
else
{
timeItem = new TimeItem(duration, oncomplete);
}
return timeItem;
}
private void Update()
{
if (add_tasks.Count > 0)
{
tasks.AddRange(add_tasks);
add_tasks.Clear();
}
if (tasks.Count > 0)
{
for (int i = 0; i < tasks.Count; i++)
{
tasks[i].Update(Time.deltaTime);
if (tasks[i].isDone)
{
recycle_tasks.Add(tasks[i]);
tasks.Remove(tasks[i]);
i--;
}
}
}
}
}