解析ET6框架定时器的原理和使用
Posted 萧寒大大
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解析ET6框架定时器的原理和使用相关的知识,希望对你有一定的参考价值。
1.介绍
在游戏逻辑编写中定时器是必不可少的,接下来我就来解析ET6框架的定时器的原理和使用。
2.原理(TimerComponent.cs)
1.awake
将所有TimerAttribute的类型的类存入timerActions数组
public void Awake()
this.timerActions = new ITimer[TimeTypeMax];
//获取所有TimerAttribute的类型
HashSet<Type> types = Game.EventSystem.GetTypes(typeof (TimerAttribute));
foreach (Type type in types)
ITimer iTimer = Activator.CreateInstance(type) as ITimer;
if (iTimer == null)
Log.Error($"Timer Action type.Name 需要继承 ITimer");
continue;
object[] attrs = type.GetCustomAttributes(typeof(TimerAttribute), false);
if (attrs.Length == 0)
continue;
//将TimerAttribute的类保存在timerActions数组
foreach (object attr in attrs)
TimerAttribute timerAttribute = attr as TimerAttribute;
this.timerActions[timerAttribute.Type] = iTimer;
2.WaitTillAsync/WaitFrameAsync/WaitAsync/NewOnceTimer/NewFrameTimer/NewRepeatedTimer(以WaitAsync为例子)
创建TimerAction到子节点,并添加timer到TimeId上
public async ETTask<bool> WaitAsync(long time, ETCancellationToken cancellationToken = null)
if (time == 0)
return true;
long tillTime = TimeHelper.ServerNow() + time;
ETTask<bool> tcs = ETTask<bool>.Create(true);
//在子节点创建TimerAction
TimerAction timer = this.AddChild<TimerAction, TimerClass, long, int, object>(TimerClass.OnceWaitTimer, time, 0, tcs, true);
//添加到TimeId上
this.AddTimer(tillTime, timer);
long timerId = timer.Id;
//移除timer并且返回false
void CancelAction()
if (this.Remove(timerId))
tcs.SetResult(false);
bool ret;
//cancellationToken不为null就添加CancelAction方法
try
cancellationToken?.Add(CancelAction);
ret = await tcs;
finally
cancellationToken?.Remove(CancelAction);
return ret;
3.Update
每帧刷新,将超时的timer执行run方法并从TimeId中移除
public void Update()
if (this.TimeId.Count == 0)
return;
long timeNow = TimeHelper.ServerNow();
if (timeNow < this.minTime)
return;
//到时间的timer压入timeOutTime队列
foreach (KeyValuePair<long, List<long>> kv in this.TimeId)
long k = kv.Key;
if (k > timeNow)
minTime = k;
break;
this.timeOutTime.Enqueue(k);
//将到时的的timerId压入timeOutTimerIds队列并从TimeId移除该timer
while (this.timeOutTime.Count > 0)
long time = this.timeOutTime.Dequeue();
foreach (long timerId in this.TimeId[time])
this.timeOutTimerIds.Enqueue(timerId);
this.TimeId.Remove(time);
//执行所有到时的计时器的timerAction
while (this.timeOutTimerIds.Count > 0)
long timerId = this.timeOutTimerIds.Dequeue();
TimerAction timerAction = this.GetChild<TimerAction>(timerId);
if (timerAction == null)
continue;
//执行timer标签类的run方法
Run(timerAction);
4.Run
执行timer的run方法
private void Run(TimerAction timerAction)
switch (timerAction.TimerClass)
case TimerClass.OnceTimer://回调等待,需要自己移除timer(单次)
int type = timerAction.Type;
ITimer timer = this.timerActions[type];
if (timer == null)
Log.Error($"not found timer action: type");
return;
timer.Handle(timerAction.Object);
break;
case TimerClass.OnceWaitTimer://携程等待,自动移除timer并返回true(单次)
ETTask<bool> tcs = timerAction.Object as ETTask<bool>;
this.Remove(timerAction.Id);
tcs.SetResult(true);
break;
case TimerClass.RepeatedTimer://回调等待,需要自己移除timer(多次)
int type = timerAction.Type;
long tillTime = TimeHelper.ServerNow() + timerAction.Time;
this.AddTimer(tillTime, timerAction);
ITimer timer = this.timerActions[type];
if (timer == null)
Log.Error($"not found timer action: type");
return;
timer.Handle(timerAction.Object);
break;
5.Remove
移除定时器
public bool Remove(ref long id)
long i = id;
id = 0;
return this.Remove(i);
private bool Remove(long id)
if (id == 0)
return false;
//从子节点移除TimerAction
TimerAction timerAction = this.GetChild<TimerAction>(id);
if (timerAction == null)
return false;
timerAction.Dispose();
return true;
3.使用
1.打上timer标签,继承ATimer,并重写Run方法
[Timer(TimerType.AITimer)]
public class AITimer: ATimer<AIComponent>
public override void Run(AIComponent self)
//方法
2.注册定时器
self.Timer = TimerComponent.Instance.NewRepeatedTimer(1000, TimerType.AITimer, self);
//中途可取消
bool timeRet = await TimerComponent.Instance.WaitAsync(1000, cancellationToken);
3.销毁定时器
TimerComponent.Instance.Remove(ref self.Timer);
self.CancellationToken?.Cancel();
self.CancellationToken = null;
以上是关于解析ET6框架定时器的原理和使用的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向使用 Python 解析 ELF 文件 ( Capstone 反汇编 ELF 文件中的机器码数据 | 创建反汇编解析器实例对象 | 设置汇编解析器显示细节 )(代码片段