前言

  • 文章属于旧有文章搬运, 之前在csdn上面
  • 2019.11.6修改

Timer是定时器, 用途:

  • 延时执行事件
  • 周期性执行事件

参考官方文档Using Timers

Timer可以...

Timer能...

Timer...

...

编不下去了, 自己百度谷歌吧(手动狗头)


TimerManager

Timer的管理类是FTimerManager, 是一个全局的Timer管理类.

通常通过UWorld::GetTimerManager()获得
可以看到实际实现是先判断GameInstance是否存在, 存在返回UGameInstanceTimerManger, 否则返回UWorld自己的TimerManger

接着, 如上图, TimerMangerUWorldUGameInstance的构造函数中创建, 调用构造函数, 不试图赋值UGameInstance

TimerManger的构造函数中, 主要还是给InternalTime设0, 该值是TimerManger内部的一个独立时钟, 在TimerManger的每次Tick调用时计时.

UWorld::Tick中调用FTimerManagerTick函数实际执行Timer里面的操作

TimerManger的销毁是在UWorld::FinishDestroy和UGameInstance::FinishDestroy中

delete然后置nullptr, 简单粗暴.


Timer的执行

从堆栈中也可以FTimerManger::TickUWorld::Tick调用

如图, 这个函数体主要做了如下内容 :

  • 先调用FTimerManager::HasBeenTickedThisFrame, 并维护LastTickedFrame避免一帧内被多次执行.
  • 然后InternalTime计时, 增加DeltaTime偏移量
  • 接着对ActiveTimerHeapPendingTimerSet进行一定逻辑处理

ActiveTimerHeap是一个当前活跃的, 待处理的FTimerHandle数组

while循环体主体逻辑:

不断取堆顶的FTimerHandle, 并得到对应的FTimerData.

如果该FTimerData的状态是可被移除, 那么移除, 继续
不断执行, 直到InternalTimer(内部的独立时钟)大于FTimerDataExpireTime, 即定时器到时间了, 那么执行一定逻辑, 否则, 没有过时间, 就直接break跳出循环

因为ActiveTimerHeap是按照过期时间排序的

接着看, 如果定时器到时间了, 会将ActiveTimerHeap的堆顶元素移动置CurrentlyExecutingTimer(当前正在执行的Timer), 并更新FTimerDataStatusETimerStatus::Executing

注意, 这里的CurrentlyExecutingTimer上文中的TopHandler是同一个值, 所以改Top(FTImerData)修改的是同一Timer的信息

然后, 重点来了

划重点了!

划重点了!

划重点了!

上图圈起来的代码, CallCount(执行次数), 为了避免在两帧之间时间过长而导致丢掉一些定时器的间隔执行, 计算, 两帧之间实际需要执行多少次.

设一个Timer, 每0.1秒执行一次, Tick总共过了5秒, 有

  • 定时器必定执行50次, 执行次数恒定
  • 如果比较卡顿, 每0.5秒执行1帧, 即定时器可能也可以在同一帧执行多次
  • 定时器是假定时, 即期望0.1s, 0.2s, 0.3s, 0.4s, 0.5s执行, 实际可能是0.5s, 0.5s, 0.5s, 0.5s, 0.5s执行5次

而Timer的执行, 实际上也就是绑定的代理执行. 此处略

// 可以参考代理相关的文章自己啃, 难度不大

在执行后有个更新指针的操作, 为了防止执行后无效, 这是为什么呢?

考验你C++功底的时候到了, 自行理解, 此处忽略(手动狗头)

Timer执行完毕之后, 做清理.

如果Timer不循环, 执行一次, 那么完成使命了, 清理掉吧!

如果Timer代理无效了, 那么无法完成使命, 也清理掉吧!

否则, 嗯, 设置下次时间, 打回去, 接着干活(手动狗头)

// 所以循环Timer啊, Timer对应的代理实际对象啊, 多数是不需要人工维护移除的
// 即多数Timer绑定好, 不清除, 也没啥影响, 他会自动移除无效的Timer

最后再看PendingTimerSet的处理, 这是在当前Tick帧添加的定时器集合, 将里面的定时器添加到ActiveTimerHeap里面

即很明显, Timer最少也会延迟一帧调用


Timer的使用

参照上面若干函数, 最后都通过FTimerManger::InternalSetTimer函数SetTimerForNextTick相关基本同, 略

FTimerManger::InternalSetTimer中在设置Timer时, 会查找一下TimerHandle是否有效, 有效会清除.

接着就是创建一个FTimerData信息, 并维护, 具体略了


最后贴一张使用图, 一些基础知识就懒得提了.

// 基础知识 : TimerHandler清除, 获得剩余时间, 暂停和取消暂停, 是否存在等函数
// 看看头文件, 配合使用即可.

以及提一下这两个Timer的代理:

  • DECLARE_DELEGATE(FTimerDelegate)
  • DECLARE_DYNAMIC_DELEGATE(FTimerDynamicDelegate)

自行参考代理相关文章, 配合使用, 能玩出花(笑)


结语

  • 骗赞, 骗评论了.

setitimer 创建两个定时器_UE4 Timer(定时器)相关源码分析相关推荐

  1. arraylist扩容是创建新数组吗 java_Java集合干货——ArrayList源码分析

    前言 在之前的文章中我们提到过ArrayList,ArrayList可以说是每一个学java的人使用最多最熟练的集合了,但是知其然不知其所以然.关于ArrayList的具体实现,一些基本的都也知道,譬 ...

  2. netty 5 alph1源码分析(服务端创建过程)

    研究了netty的服务端创建过程.至于netty的优势,可以参照网络其他文章.<Netty系列之Netty 服务端创建>是 李林锋撰写的netty源码分析的一篇好文,绝对是技术干货.但抛开 ...

  3. Spring AOP 源码分析 - 创建代理对象

    1.简介 在上一篇文章中,我分析了 Spring 是如何为目标 bean 筛选合适的通知器的.现在通知器选好了,接下来就要通过代理的方式将通知器(Advisor)所持有的通知(Advice)织入到 b ...

  4. Spring IOC 容器源码分析 - 创建原始 bean 对象

    1. 简介 本篇文章是上一篇文章(创建单例 bean 的过程)的延续.在上一篇文章中,我们从战略层面上领略了doCreateBean方法的全过程.本篇文章,我们就从战术的层面上,详细分析doCreat ...

  5. Spring IOC 容器源码分析 - 创建单例 bean 的过程

    1. 简介 在上一篇文章中,我比较详细的分析了获取 bean 的方法,也就是getBean(String)的实现逻辑.对于已实例化好的单例 bean,getBean(String) 方法并不会再一次去 ...

  6. v45.05 鸿蒙内核源码分析(Fork) | 一次调用 两次返回 | 百篇博客分析HarmonyOS源码

    孔子于乡党,恂恂如也,似不能言者.其在宗庙朝廷,便便言,唯谨尔. <论语>:乡党篇 百篇博客系列篇.本篇为: v45.xx 鸿蒙内核源码分析(Fork篇) | 一次调用 两次返回 进程管理 ...

  7. 【Android 异步操作】Timer 定时器 ( Timer 与 TimerTask 基本使用 | Timer 定时器常用用法 | Timer 源码分析 )

    文章目录 一.Timer 定时器基本使用 二.Timer 定时器常用用法 三.Timer 源码分析 四.Timer 部分源码注释 五.源码及资源下载 参考文档 : Timer 定时器 API 文档 T ...

  8. skynet源码分析之定时器skynet_timer.c

    skynet自带定时器功能skynet-src/skynet_timer.c,在skynet启动时会创建一个线程专门跑定时器.每帧(0.0025秒/帧)调用skynet_updatetime() 1 ...

  9. Java定时任务(一) Timer及TimerTask的案例解析及源码分析

    Java定时任务(一)  Timer及TimerTask的案例解析及源码分析 一.概述: 定时任务这个概念在Java的学习以及项目的开发中并不陌生,应用场景也是多种多样.比如我们会注意到12306网站 ...

最新文章

  1. Weex Flexbox弹性布局使用
  2. SSM整合(基础框架)代码
  3. mysql proxy ro-pooling.lua_MySQL读写分离
  4. 在Win10 LTSC 2019上安装和卸载linux子系统
  5. c++ 网络编程课设入门超详细教程 ---目录
  6. StanfordDB class自学笔记 (8) Querying XML
  7. FPGA 入门 (一)
  8. 对数坐标归一化_数据归一化处理方法 数据处理之标准化/归一化方法
  9. 【计算机网络学习笔记16】网络新技术
  10. pigxCloud微服务项目04——服务端——腾讯云即时通信IM,拉取群历史消息(全量消息、所有群消息)
  11. uni-app - 实现手机扫描二维码并跳转全过程
  12. 轩小陌的Python笔记-Pandas 高级数据处理
  13. 你有哪些“相见恨晚”的UE4学习资料?
  14. oracle 12c创建归档,oracle 12c 数据归档 即Using In-Database Archiving feature
  15. django笔记10 cookie整理
  16. 计算机颜色管理器,系统颜色管理完全攻略
  17. 阅读笔记 - 20220401
  18. python使用 docx 库操作 docx 格式文件
  19. jsp层级选择器_jQuery 选择器
  20. scipy笔记—scipy.misc.imresize用法(方便训练图像数据)

热门文章

  1. JavaEE概念简介
  2. Java:放心(或非常容易)
  3. 寻找随机的错误-一个真实的故事
  4. 带有Jersey和Spring的RESTful Web应用程序
  5. Linux 命令之 xargs -- 给其他命令传递参数的一个过滤器
  6. MySQL 批量生成 SQL 脚本语句解决实际的业务需求/如何拼接字符串/拼接字符串的 SQL 语句
  7. RestTemplate入门案例
  8. linux安装meld rpm,Linux meld安装
  9. OS X下使用OpenGL做离屏渲染
  10. 电脑所有程序里有不一样颜色_12个好玩的电脑屏保,让你成为别人眼中最靓的仔。...