using System.Collections;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using UnityEngine;
using System;
namespace GuiltyVoid.Lua.LuaFrameWork.Wrap
{
/// <summary>
/// Lua计时器
/// </summary>
public class TickTimer
{
/// <summary>
/// 计时器下标
/// </summary>
public long Index = 0;
/// <summary>
/// 计时器停止回调
/// </summary>
private Action<TickTimer> Action_ShutDown;
/// <summary>
/// 延迟执行事件
/// </summary>
public event Action OnDelayAction;
/// <summary>
/// 每Tick执行事件
/// </summary>
public event Action OnTickActon;
/// <summary>
/// 当前已经响应过的Tick次数
/// </summary>
private int _TickActionCount = 0;
/// <summary>
/// 是否强制停止当前计时器
/// </summary>
private bool _IsFourceRemove = false;
/// <summary>
/// 持续时间
/// </summary>
private float _Duration = 0f;
/// <summary>
/// 剩余时间
/// </summary>
private float _RemainTime = 0f;
/// <summary>
/// 是否为永久持续
/// </summary>
private bool _IsPermanent = false;
/// <summary>
/// 当前总共持续时间
/// </summary>
private float _TimeCount = 0f;
/// <summary>
/// 延迟执行时间
/// </summary>
private float _Delay = 0f;
/// <summary>
/// 延迟执行后是否需要停止计时器
/// </summary>
private bool _IsNeedShutAfterDelay = true;
/// <summary>
/// Tick间隔时间
/// 默认为1s 1Tick
/// </summary>
private float _TickTime = 1f;
/// <summary>
/// 构造方法
/// </summary>
/// <param name="Action_ShutDown">关闭回调方法</param>
public TickTimer(Action<TickTimer> Action_ShutDown)
{
this.Action_ShutDown = Action_ShutDown;
}
/// <summary>
/// 开始执行Tick
/// </summary>
private async void StartRunTick()
{
while (true)
{
if (_IsFourceRemove)
{
ShutDownTick();
return;
}
OnTickRun();
await Task.Delay(100);
}
}
/// <summary>
/// 每1ms响应一次函数体
/// </summary>
/// <returns></returns>
private void OnTickRun()
{
if (_RemainTime <= 0 && !_IsPermanent)
{
//达到时间移除
_IsFourceRemove = true;
}
_TimeCount += 100;
if (!_IsPermanent)
{
_RemainTime -= 100;
}
//当前累积时间大于上一次进行Tick时间则执行一次TickAction(所以默认第一次Start后会立刻执行一次TickAction)
if (_TimeCount > (_TickTime * 1000 * _TickActionCount))
{
_TickActionCount++;
OnTickActon?.Invoke();
}
//当前累积时间到达了延迟时间响应一次延迟Action
if (OnDelayAction != null && _TimeCount > _Delay * 1000)
{
OnDelayAction?.Invoke();
OnDelayAction = null;
if (_IsNeedShutAfterDelay)
{
//停止计时器
ShutDownTick();
}
}
//await Task.Delay(100);
}
/// <summary>
/// 开启一个计时器
/// </summary>
/// <param name="pDuration">计时器总时间</param>
/// <param name="pTickTime">每Tick间隔时间</param>
/// <param name="pTickAction">每Tick回调方法</param>
/// <param name="pDelay">延迟执行时间</param>
/// <param name="pIsNeedShutAfterDelay">延迟执行后是否需要停止计时器</param>
/// <param name="pDelayAction">延迟执行事件</param>
public void StartTickTimer(float pDuration = 0f,
float pTickTime = 1f,
Action pTickAction = null,
float pDelay = 0f,
bool pIsNeedShutAfterDelay = true,
Action pDelayAction = null)
{
OnDelayAction = pDelayAction;
OnTickActon = pTickAction;
_TickActionCount = 0;
_IsFourceRemove = false;
_Duration = pDuration;
_RemainTime = _Duration;
_IsPermanent = _Duration <= 0;
_TimeCount = 0f;
_Delay = pDelay;
_IsNeedShutAfterDelay = pIsNeedShutAfterDelay;
_TickTime = pTickTime;
StartRunTick();
}
/// <summary>
/// 停止计时器
/// </summary>
public void ShutDownTick()
{
_IsPermanent = true;
Action_ShutDown?.Invoke(this);
}
}
/// <summary>
/// 计时器工具
/// </summary>
public class TimerUtilities
{
/// <summary>
/// 计时器实例下标计数器(用于保证每个计时器的Key唯一)
/// </summary>
private long _TickIndexr = 1;
/// <summary>
/// 计时器实例Map
/// </summary>
private ConcurrentDictionary<long, TickTimer> _MapTickTimer;
/// <summary>
/// 初始化
/// </summary>
public void Init()
{
//Debug.Log("[LuaFrameWork] ---------------INIT UTILITIES");
_MapTickTimer = new ConcurrentDictionary<long, TickTimer>();
_TickIndexr = 1;
}
/// <summary>
/// 延迟执行
/// </summary>
/// <param name="pDelay"></param>
/// <param name="pDelayAction"></param>
public void Delay(float pDelay, Action pDelayAction)
{
TickTimer timer = AddTickTimer();
if (timer != null)
{
//成功添加一个TickTimer到缓存Map中,执行对应延迟方法
timer.StartTickTimer(pDelay: pDelay, pDelayAction: pDelayAction);
}
}
/// <summary>
/// 开启一个帧回调计时器
/// </summary>
/// <param name="pDuration">计时器总时间</param>
/// <param name="pTickTime">每Tick间隔时间</param>
/// <param name="pTickAction">每Tick回调方法</param>
public TickTimer Tick(float pDuration = 0f, float pTickTime = 1f, Action pTickAction = null)
{
TickTimer timer = AddTickTimer();
if (timer != null)
{
//成功添加一个TickTimer到缓存Map中,执行对应延迟方法
timer.StartTickTimer(pDuration, pTickTime, pTickAction);
}
return timer;
}
/// <summary>
/// 开启一个帧回调计时器并且在指定延迟后响应一个事件
/// </summary>
/// <param name="pDuration">计时器总时间</param>
/// <param name="pTickTime">每Tick间隔时间</param>
/// <param name="pTickAction">每Tick回调方法</param>
/// <param name="pDelay">延迟执行时间</param>
/// <param name="pIsNeedShutAfterDelay">延迟执行后是否需要停止计时器</param>
/// <param name="pDelayAction">延迟执行事件</param>
public TickTimer TickDelay(float pDuration = 0f,
float pTickTime = 1f,
Action pTickAction = null,
float pDelay = 0f,
bool pIsNeedShutAfterDelay = true,
Action pDelayAction = null)
{
TickTimer timer = AddTickTimer();
if (timer != null)
{
//成功添加一个TickTimer到缓存Map中,执行对应延迟方法
timer.StartTickTimer(pDuration, pTickTime, pTickAction,pDelay,pIsNeedShutAfterDelay,pDelayAction);
}
return timer;
}
/// <summary>
/// 获取一个计时器
/// </summary>
/// <returns></returns>
private TickTimer AddTickTimer()
{
TickTimer timer = new TickTimer(RemoveTickTimer);
bool isSuccess = _MapTickTimer.TryAdd(_TickIndexr++, timer);
if (!isSuccess)
{
Debug.LogWarning($"[TimerUtilities] Error: Fail to Add a Timer to Map!");
timer = null; //字典添加失败,释放当前Timer实例
return null;
}
return timer;
}
/// <summary>
/// 移除一个计时器
/// </summary>
/// <param name="timer"></param>
private void RemoveTickTimer(TickTimer timer)
{
TickTimer outTimer;
if (_MapTickTimer != null && timer != null && _MapTickTimer.ContainsKey(timer.Index))
{
var Succeed = _MapTickTimer.TryRemove(timer.Index,out outTimer);
if (Succeed)
{
outTimer = null; //释放当前类
}
}
}
}
}
Elementor的code模板居然要pro会员看来是没得用了
整了个插件替代了