/*
- 刷新管理器
- @处理定时任务
- @统一刷新回调机制
- @处理倒计时(防后台)
*/
using UnityEngine;
using System.Collections.Generic;
using System.Collections;
using System;
using LogPrint;
public class TimeManager : MonoBehaviour
{
///
/// 全局实例
///
private static TimeManager _Instance = null;
/// <summary>
/// 定时器字典
/// </summary>
private Dictionary<string, Timer> m_TimerList = new Dictionary<string, Timer>();
/// <summary>
/// 增加队列
/// </summary>
private Dictionary<string, Timer> m_AddTimerList = new Dictionary<string, Timer>();
/// <summary>
/// 销毁队列
/// </summary>5069726163792e
private List<string> m_DestroyTimerList = new List<string>();
public delegate void TimerManagerHandler();
public delegate void TimerManagerHandlerArgs(params object[] args);
/// <summary>e5adabe38aa3e58189
/// 倒计时回调
/// </summary>
/// <param name="count">倒计时剩余时间</param>
/// <param name="args">倒计时参数</param>
public delegate void TimerManagerCountHandlerArgs(int count, params object[] args);
/// -----------------------------------------------------------------------------
/// <summary>
/// 全局实例
/// </summary>
/// -----------------------------------------------------------------------------
public static TimeManager Instance
{
get
{
if (_Instance == null)
{
_Instance = FindObjectOfType(typeof(TimeManager)) as TimeManager;
}
return _Instance;
}
}
// Use this for initialization
void Awake()
{
if (TimeManager.Instance != null && TimeManager.Instance != this)
{
UnityEngine.Object.Destroy(this);
return;
}
_Instance = this;
}
#region 刷新器管理
Dictionary<string, Timer>.Enumerator it;
Dictionary<string, Timer>.Enumerator itAdd;
// Update is called once per frame
void Update()
{
if (m_DestroyTimerList.Count > 0)
{
///>从销毁队列中销毁指定内容
//foreach (string i in m_DestroyTimerList)
//{
// m_TimerList.Remove(i);
//}
for (int i = 0; i < m_DestroyTimerList.Count; i++)
{
m_TimerList.Remove(m_DestroyTimerList[i]);
}
//清空
m_DestroyTimerList.Clear();
}
if (m_AddTimerList.Count > 0)
{
///>从增加队列中增加定时器
itAdd = m_AddTimerList.GetEnumerator();
while (itAdd.MoveNext())
{
if (itAdd.Current.Value == null)
continue;
if (m_TimerList.ContainsKey(itAdd.Current.Key))
{
m_TimerList[itAdd.Current.Key] = itAdd.Current.Value;
}
else
{
m_TimerList.Add(itAdd.Current.Key, itAdd.Current.Value);
}
}
//清空
m_AddTimerList.Clear();
}
//响应定时器
if (m_TimerList.Count > 0)
{
it = m_TimerList.GetEnumerator();
while (it.MoveNext())
{
if (it.Current.Value == null)
return;
it.Current.Value.Run();
}
}
}
/// -----------------------------------------------------------------------------
/// <summary>
/// 增加刷新器
/// </summary>
/// <param name=""></param>
/// <returns></returns>
/// -----------------------------------------------------------------------------
public bool AddTimer(string key, float duration, TimerManagerHandler handler)
{
return Internal_AddTimer(key, TIMER_MODE.NORMAL, duration, handler);
}
public bool AddTimer(string key, float duration, TimerManagerHandlerArgs handler, params object[] args)
{
return Internal_AddTimer(key, TIMER_MODE.NORMAL, duration, handler, args);
}
/// -----------------------------------------------------------------------------
/// <summary>
/// 增加持续刷新器
/// </summary>
/// <param name=""></param>
/// <returns></returns>
/// -----------------------------------------------------------------------------
public bool AddTimerRepeat(string key, float duration, TimerManagerHandler handler)
{
return Internal_AddTimer(key, TIMER_MODE.REPEAT, duration, handler);
}
public bool AddTimerRepeat(string key, float duration, TimerManagerHandlerArgs handler, params object[] args)
{
return Internal_AddTimer(key, TIMER_MODE.REPEAT, duration, handler, args);
}
/// <summary>
/// 刷新倒计时
/// </summary>
/// <param name="key">标记字符</param>
/// <param name="duration">倒计时时间</param>
/// <param name="handler">计时回调</param>
/// <param name="args">计时参数</param>
/// <returns></returns>
public bool AddTimerCount(string key, float duration, TimerManagerCountHandlerArgs handler, params object[] args)
{
return Internal_AddTimer(key, TIMER_MODE.COUNTTIME, duration, 1, (int)duration, handler, args);
}
/// <summary>
/// 刷新倒计时
/// </summary>
/// <param name="key">标记字符</param>
/// <param name="duration">倒计时时间</param>
/// <param name="totalTime">总次数</param>
/// <param name="handler">计时回调</param>
/// <param name="args">计时参数</param>
public bool AddTimerCount(string key, float eachTime, int totalTime, TimerManagerCountHandlerArgs handler, params object[] args)
{
float totalTimed = eachTime * totalTime;
return Internal_AddTimer(key, TIMER_MODE.COUNTTIME, totalTimed, eachTime, totalTime, handler, args);
}
/// <summary>
/// 销毁带有前缀的所有刷新器
/// </summary>
/// <param name="prefix"></param>
public void ClearTimerWithPrefix(string prefix)
{
if (m_TimerList != null && m_TimerList.Count > 0)
{
foreach (string timerKey in m_TimerList.Keys)
{
if (timerKey.StartsWith(prefix))
{
Destroy(timerKey);
}
}
}
}
/// -----------------------------------------------------------------------------
/// <summary>
/// 销毁指定定时器
/// </summary>
/// <param name="key">标识符</param>
/// <returns></returns>
/// -----------------------------------------------------------------------------
public bool Destroy(string key)
{
if (m_AddTimerList.ContainsKey(key))
{
m_AddTimerList.Remove(key);
}
if (!m_TimerList.ContainsKey(key))
{
return false;
}
if (!m_DestroyTimerList.Contains(key))
{
m_DestroyTimerList.Add(key);
}
return true;
}
/// <summary>
/// 是否含用定时器
/// </summary>
/// <returns><c>true</c> if this instance is have timer the specified key; otherwise, <c>false</c>.</returns>
/// <param name="key">Key.</param>
public bool IsHaveTimer(string key)
{
// 待添加队里中有
if (m_AddTimerList.ContainsKey(key))
{
return true;
}
// 正在运行阶段
if (!m_DestroyTimerList.Contains(key) && m_TimerList.ContainsKey(key))
{
return true;
}
return false;
}
/// -----------------------------------------------------------------------------
/// <summary>
/// 增加定时器
/// </summary>
/// <param name=""></param>
/// <returns></returns>
/// -----------------------------------------------------------------------------
private bool Internal_AddTimer(string key, TIMER_MODE mode, float duration, TimerManagerHandler handler)
{
if (string.IsNullOrEmpty(key))
return false;
if (duration < 0.0f)
return false;
Timer timer = new Timer(key, mode, Time.realtimeSinceStartup, duration, handler, this);
if (m_AddTimerList.ContainsKey(key))
{
m_AddTimerList[key] = timer;
}
else
{
m_AddTimerList.Add(key, timer);
}
if (GameDefault.Instance.Debug)
{
SetTimeScale(key);
}
return true;
}
private bool Internal_AddTimer(string key, TIMER_MODE mode, float duration, TimerManagerHandlerArgs handler, params object[] args)
{
if (string.IsNullOrEmpty(key))
return false;
if (duration < 0.0f)
return false;
Timer timer = new Timer(key, mode, Time.realtimeSinceStartup, duration, handler, this, args);
if (m_AddTimerList.ContainsKey(key))
{
m_AddTimerList[key] = timer;
}
else
{
m_AddTimerList.Add(key, timer);
}
return true;
}
private bool Internal_AddTimer(string key, TIMER_MODE mode, float duration, float eachTime, int count, TimerManagerCountHandlerArgs handler, params object[] args)
{
if (string.IsNullOrEmpty(key))
return false;
if (duration < 0.0f)
return false;
Timer timer = new Timer(key, mode, Time.time, duration, eachTime, count, handler, this, args);
if (m_AddTimerList.ContainsKey(key))
{
m_AddTimerList[key] = timer;
}
else
{
m_AddTimerList.Add(key, timer);
}
return true;
}
public bool IsRunning(string key)
{
return m_TimerList.ContainsKey(key);
}
public int getTimeCount(string key)
{
if (m_TimerList.ContainsKey(key))
{
return m_TimerList[key].Count;
}
return 0;
}
/// -----------------------------------------------------------------------------
/// <summary>
/// 定时器模式
/// </summary>
/// -----------------------------------------------------------------------------
public enum TIMER_MODE
{
NORMAL,
REPEAT,
COUNTTIME,
}
public class Timer
{
/// <summary>
/// 名称
/// </summary>
private string m_Name;
/// <summary>
/// 模式
/// </summary>
private TIMER_MODE m_Mode;
/// <summary>
/// 开始时间
/// </summary>
public float m_StartTime;
/// <summary>
/// 时长
/// </summary>
public float m_duration;
/// <summary>
/// 单次时长
/// </summary>
private float m_eachTime;
/// <summary>
/// 总次数
/// </summary>
private int m_Count;
/// <summary>
/// 中断
/// </summary>
private bool m_Break = false;
/// <summary>
/// 中断开始时间
/// </summary>
private float m_BreakStart;
/// <summary>
/// 中断开始时间
/// </summary>
private float m_BreakDuration = 0;
/// <summary>
/// 时间点
/// </summary>
public float m_time = 0;
private bool timeScale = false;
/// <summary>
/// 是否缩放时间
/// </summary>
public bool TimeScale
{
get { return timeScale; }
set { timeScale = value; }
}
/// <summary>
/// 定时器委托
/// </summary>
private TimerManagerHandler m_TimerEvent;
private TimerManagerHandlerArgs m_TimerArgsEvent;
private TimerManagerCountHandlerArgs m_TimerCountArgsEvent;
private TimeManager m_Manger;
private object[] m_Args = null;
/// -----------------------------------------------------------------------------
/// <summary>
/// 开始时间
/// </summary>
/// <param name=""></param>
/// <returns></returns>
/// -----------------------------------------------------------------------------
public float StartTime
{
get
{
return m_StartTime;
}
set
{
m_StartTime = value;
}
}
/// -----------------------------------------------------------------------------
/// <summary>
/// 剩余时间
/// </summary>
/// <param name=""></param>
/// <returns></returns>
/// -----------------------------------------------------------------------------
public float TimeLeft
{
get
{
return Mathf.Max(0.0f, m_duration - (timeScale ? Time.time - m_StartTime : Time.realtimeSinceStartup - m_StartTime));
}
}
/// -----------------------------------------------------------------------------
/// <summary>
///
/// </summary>
/// <param name=""></param>
/// <returns></returns>
/// -----------------------------------------------------------------------------
public Timer(string name, TIMER_MODE mode, float startTime, float duration, TimerManagerHandler handler, TimeManager manager)
{
m_Name = name;
m_Mode = mode;
m_StartTime = startTime;
m_duration = duration;
m_TimerEvent = handler;
m_Manger = manager;
}
public Timer(string name, TIMER_MODE mode, float startTime, float duration, TimerManagerHandlerArgs handler, TimeManager manager, params object[] args)
{
m_Name = name;
m_Mode = mode;
m_StartTime = startTime;
m_duration = duration;
m_TimerArgsEvent = handler;
m_Manger = manager;
m_Args = args;
}
public Timer(string name, TIMER_MODE mode, float startTime, float duration, float eachTime, int count, TimerManagerCountHandlerArgs handler, TimeManager manager, params object[] args)
{
m_time = Time.realtimeSinceStartup;
m_Name = name;
m_Mode = mode;
m_StartTime = startTime;
m_duration = duration;
m_eachTime = eachTime;
m_Count = count;
m_TimerCountArgsEvent = handler;
m_Manger = manager;
m_Args = args;
}
public Timer(string name, TIMER_MODE mode, float startTime, float duration, TimerManagerCountHandlerArgs handler, TimeManager manager, params object[] args)
{
m_time = Time.realtimeSinceStartup;
m_Name = name;
m_Mode = mode;
m_StartTime = startTime;
m_duration = duration;
m_TimerCountArgsEvent = handler;
m_Manger = manager;
m_Args = args;
}
/// -----------------------------------------------------------------------------
/// <summary>
/// 运行事件
/// </summary>
/// <param name=""></param>
/// <returns></returns>
/// -----------------------------------------------------------------------------
public void Run()
{
if (m_Break) return;
if (m_Mode == TIMER_MODE.COUNTTIME)
{
float lastTime = timeScale ? Time.time - m_time : Time.realtimeSinceStartup - m_time;
if (lastTime - m_eachTime >= 0.03f)
{
m_time = timeScale ? Time.time : Time.realtimeSinceStartup;
if (this.m_TimerCountArgsEvent != null)
{
m_Count--;
this.m_TimerCountArgsEvent(m_Count, m_Args);
}
//if (this.TimeLeft < m_eachTime)
//{
// m_Manger.Destroy(this.m_Name);
//}
if (m_Count <= 0)
{
m_Manger.Destroy(this.m_Name);
}
}
return;
}
if (this.TimeLeft > 0.0f)
return;
if (m_Mode == TIMER_MODE.NORMAL)
{
m_Manger.Destroy(this.m_Name);
}
else
{
m_StartTime = timeScale ? Time.time : Time.realtimeSinceStartup;
}
if (this.m_TimerEvent != null)
{
this.m_TimerEvent();
}
if (this.m_TimerArgsEvent != null)
{
this.m_TimerArgsEvent(m_Args);
}
}
public void Break()
{
if (m_Break)
{
return;
}
m_Break = true;
m_BreakStart = Time.realtimeSinceStartup;
}
public void Resume()
{
if (!m_Break)
{
return;
}
m_BreakDuration += (Time.realtimeSinceStartup - m_BreakStart);
m_Break = false;
}
public float RealTime()
{
return Time.realtimeSinceStartup - m_BreakDuration;
}
public int Count
{
get { return m_Count; }
}
}
internal void AddTimer(string v, object moveredtwo)
{
throw new NotImplementedException();
}
public Timer GetTimer(string key)
{
if (m_TimerList.ContainsKey(key))
return m_TimerList[key];
return null;
}
/// <summary>
/// 暂停带有前缀的所有定时器
/// </summary>
/// <param name="prefix"></param>
public void BreakTimerWithPrefix(string prefix)
{
if (m_TimerList != null && m_TimerList.Count > 0)
{
string[] arr = new string[m_TimerList.Count];
m_TimerList.Keys.CopyTo(arr, 0);
for (int i = 0; i < arr.Length; i++)
{
if (arr[i].StartsWith(prefix))
{
BreakTimer(arr[i]);
}
}
}
}
/// <summary>
/// 暂停计时器
/// </summary>
public void BreakTimer(string key)
{
if (m_TimerList.ContainsKey(key))
{
Timer timer = m_TimerList[key];
timer.Break();
}
else
{
if (m_AddTimerList.ContainsKey(key))
{
Timer timer = m_AddTimerList[key];
timer.Break();
}
}
}
/// <summary>
/// 重启带有前缀的所有定时器
/// </summary>
/// <param name="prefix"></param>
public void ResumeTimerWithPrefix(string prefix)
{
if (m_TimerList != null && m_TimerList.Count > 0)
{
string[] arr = new string[m_TimerList.Count];
m_TimerList.Keys.CopyTo(arr, 0);
for (int i = 0; i < arr.Length; i++)
{
if (arr[i].StartsWith(prefix))
{
ResumeTimer(arr[i]);
}
}
}
}
/// <summary>
/// 重启计时器
/// </summary>
public void ResumeTimer(string key)
{
if (m_TimerList.ContainsKey(key))
{
Timer timer = m_TimerList[key];
timer.Resume();
}
else
{
if (m_AddTimerList.ContainsKey(key))
{
Timer timer = m_AddTimerList[key];
timer.Resume();
}
}
}
/// <summary>
/// 获取实际游戏时间
/// </summary>
public float RealGameTime(string key)
{
if (!m_TimerList.ContainsKey(key))
{
return 0f;
}
Timer timer = m_TimerList[key];
return timer.RealTime();
}
/// <summary>
/// 设置计时器受定帧影响
/// </summary>
public void SetTimeScale(string key)
{
if (!m_AddTimerList.ContainsKey(key))
{
LogSystem.LogError("not contains key: " + key);
return;
}
Timer timer = m_AddTimerList[key];
timer.TimeScale = true;
timer.m_time = Time.time;
timer.m_StartTime = Time.time;
}
#endregion
#region 全局定帧
/// <summary>
/// 全局定帧
/// </summary>
/// <param name="slowRate">速度比率</param>
/// <param name="slowTime">定帧时间</param>
public void SlowGamePlay(int slowRate, float slowTime = 0f)
{
Destroy("SlowGamePlay");
if (slowRate == 0)
{
Time.timeScale = 0;
return;
}
if (slowRate == 100)
{
Time.timeScale = 1;
return;
}
Time.timeScale = slowRate * 0.01f;
AddTimer("SlowGamePlay", slowTime, () =>
{
Time.timeScale = 1;
});
}
/// <summary>
/// 继续游戏
/// </summary>
public void PlayGame()
{
Time.timeScale = 1;
}
/// <summary>
/// 暂停游戏
/// </summary>
public void PauseGame()
{
Time.timeScale = 0;
}
#endregion
public static IEnumerator DelayToInvokeDo(Action action, float delaySeconds)
{
yield return new WaitForSeconds(delaySeconds);
action();
}
}