【CFramework】Unity定时器Timer封装C#

定时器Timer封装,避免各个模块需要使用定时器时重复写定时器逻辑。

【计时器提供功能】

  1. 自动创建,自动销毁,定义了定时器池子,重复利用
  2. 支持帧、秒计时,支持不受TimeScale影响计时
  3. 支持多次计时,支持循环计时
  4. 提供获取当前计时总时间

还可以扩展功能,可根据对应需求增加相应接口。


Timer定时器:

using NUnit.Framework;
using System;
using UnityEngine;

public class Timer
{
    
    
	// 外部传入参数
	private float _delayTime;
	private Action _onCall;
	private uint _loopCount; //小于0表示循环
	private bool _isUseRealTime;
	private bool _isFrame;
	// 内部定义参数
	private bool _destroyed;
	private bool _isLoop;
	private float _startTime;
	private float _nextTime;

	/// <summary>
	/// 外部创建Timer接口
	/// </summary>
	/// <param name="delayTime">延迟时间执行</param>
	/// <param name="onCall">执行函数</param>
	/// <param name="loopCount">循环次数,默认为1,0表示一直循环</param>
	/// <param name="isFrame">true:逐帧检测, false:逐秒检测</param>
	/// <param name="isUseRealTime">是否使用unScaleTime,默认false</param>
	/// <returns></returns>
	public static Timer CreateTimer(float delayTime, Action onCall, uint loopCount = 1, bool isFrame = false, bool isUseRealTime = false)
	{
    
    
		Timer timer = null;
		if (!TimerManager.Instance.TryGetTimer(timer))
		{
    
    
			timer = new Timer();
		}
		timer.InitParams(delayTime, onCall, loopCount, isFrame, isUseRealTime);
		return timer;
	}

	private Timer()
	{
    
    
		TimerManager.Instance.AddTimer(this);
	}

	private void InitParams(float delayTime, Action onCall, uint loopCount, bool isFrame, bool isUseRealTime)
	{
    
    
		Assert.IsTrue(delayTime > 0);
		Assert.IsNotNull(onCall);
		this._delayTime = delayTime;
		this._onCall = onCall;
		this._loopCount = loopCount;
		this._isFrame = isFrame;
		this._isUseRealTime = isUseRealTime;
		this._destroyed = false;
		this._isLoop = loopCount == 0;
		_startTime = this.GetCurTime();
		this._nextTime = _startTime + delayTime;
	}

	public void Update()
	{
    
    
		if (this._destroyed) return;
		if (this.GetCurTime() >= this._nextTime)
		{
    
    
			this.Execute();
		}
	}

	private void Execute()
	{
    
    
		try
		{
    
    
			this._onCall?.Invoke();
		}
		catch (Exception e)
		{
    
    
			LogModule.LogError("[Timer] call function error:{0}", e.ToString());
			Destroy();
			return;
		}
		this._loopCount--;
		if (!this._isLoop && this._loopCount <= 0)
		{
    
    
			Destroy();
			return;
		}
		this._nextTime = this.GetCurTime() + _delayTime;
	}

	private float GetCurTime()
	{
    
    
		return this._isFrame ? Time.frameCount : (this._isUseRealTime ? Time.unscaledTime : Time.time);
	}

	/// <summary>
	/// 获取定时器过去的时间(供外部有需要调用)
	/// </summary>
	public float GetPassTime()
	{
    
    
		return this.GetCurTime() - this._startTime;
	}

	public bool IsRecovery()
	{
    
    
		return this._destroyed;
	}

	public void Destroy()
	{
    
    
		this._destroyed = true;
		this._onCall = null;
	}
}

TimerManager定时器管理类:

using System.Collections.Generic;

public class TimerManager : MonoSingleton<TimerManager>
{
    
    
	private readonly List<Timer> _pool = new List<Timer>();
	private readonly List<Timer> _updateTimerList = new List<Timer>();

	protected override void Init()
	{
    
    
		_pool.Clear();
		_updateTimerList.Clear();
	}

	private void Update()
	{
    
    
		for (int i = _updateTimerList.Count - 1; i >= 0; i--)
		{
    
    
			var timer = _updateTimerList[i];
			timer.Update();
			if (timer.IsRecovery())
			{
    
    
				_updateTimerList.RemoveAt(i);
				_pool.Add(timer);
			}
		}
	}

	public void AddTimer(Timer timer)
	{
    
    
		_updateTimerList.Add(timer);
	}

	public bool TryGetTimer(Timer outTimer)
	{
    
    
		if (_pool.Count > 0)
		{
    
    
			outTimer = _pool[0];
			_pool.RemoveAt(0);
			return true;
		}
		return false;
	}

	protected override void Dispose()
	{
    
    
		_pool.Clear();
		_updateTimerList.Clear();
	}
}

使用范例:

Timer.CreateTimer(5, () =>
{
    
    
	LogModule.LogError("[Timer1] 5秒后执行");
});
Timer timer = null;
timer = Timer.CreateTimer(1, () =>
{
    
    
	LogModule.LogError("[Timer1] 循环,1秒执行一次,passTime = {0}", timer.GetPassTime().ToString());
}, 0);

在这里插入图片描述


(完)

Guess you like

Origin blog.csdn.net/qq_34937637/article/details/122490763