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

前言

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

Timer是定时器, 用途:

  • 延时执行事件
  • 周期性执行事件
参考官方文档Using Timers

Timer可以...

Timer能...

Timer...

...

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


TimerManager

246791a4b382264dcc836e8639a7a995.png

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

19387bc2caed85c4ee73126e73521f76.png

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

f7b9d6f2b599ca622d8e5c7d5f434875.png

1e68e6a7639fb5898a6e704b57baec80.png

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

de72bf13cc38319721f25ed3bcabb213.png

0cdfc1bc3b347e819d9ef0fd3c4e78a7.png

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

703f58f63af695daeea8e00207ca530b.png

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

4305a554d0c31216e35bd47d241e901d.png

d1c976320aac8bdcfb1c7b451d64cfe7.png

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

delete然后置nullptr, 简单粗暴.


Timer的执行

4797774f55b47ae6965d0b4cb8286044.png

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

fdf6a947b48bb8e328f1757328d71a6d.png

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

  • 先调用FTimerManager::HasBeenTickedThisFrame, 并维护LastTickedFrame避免一帧内被多次执行.

3e3e07dcfb6653aa56e18b297243fcb7.png

427463864597681e1f6ef1c8cdd3c47f.png
  • 然后InternalTime计时, 增加DeltaTime偏移量
  • 接着对ActiveTimerHeapPendingTimerSet进行一定逻辑处理

f53e7d43d2b7587ea0bc584ee17c6d2d.png

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

99eec07c27dad629c62ad9d7530d7076.png

while循环体主体逻辑:

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

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

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

fe36440e19a7890ceab44e10e6dd8e75.png

接着看, 如果定时器到时间了, 会将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次

54e9ce89ec18594bc333b83e1a2ef901.png

61a3d4833bc4bf97b4b840f088c00e46.png

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

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

117997da75cf6dfa4ec3462d86eca784.png

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

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

d1e5b36639d8d27d45cd393a3a3eecb4.png

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

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

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

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

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

ad1ed8484e6fe43e93e332e4215249d3.png

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

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


Timer的使用

de31862459ab3e40f487010371e4c80e.png

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

6dcc01a573b412b9763c1a49e05ac96c.png

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

47ecccc2b7ae1fc36a6d044787f4711c.png

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


c962b8d0bf894d0581225296330eabf2.png

98450e5f84f7a598b6fef59e7c7e2b10.png

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

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

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

  • DECLARE_DELEGATE(FTimerDelegate)
  • DECLARE_DYNAMIC_DELEGATE(FTimerDynamicDelegate)

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


结语

  • 骗赞, 骗评论了.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/346312.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

is array php,PHP 源码 — is_array 函数源码分析

php 中的 is_arrayphp 中的 is_array,它的签名是 is_array ( mixed $var ) : bool实现的源码在\ext\standard\type.c中可以找到PHP_FUNCTION(is_array)所处的位置,大概位于 273 行。在 PHP 中,这个系列的函数,是由很多个&#xff…

apache mahout_使用Apache Mahout创建在线推荐系统

apache mahout最近, 我们一直在为Yap.TV实施推荐系统:您可以在安装应用程序并转到“ Just for you”标签后才能看到它的运行情况。 我们以Apache Mahout为基础进行建议。 Mahout是一个“可扩展的机器学习库”,包含使用协作过滤算法的基于用户…

activitimq集群搭建_activitmq+keepalived+nfs 非zk的高可用集群构建

nfs192.168.10.32maast192.168.10.4savel192.168.10.31应对这个需求既要高可用又要消息延迟,只能使用变态方式实现nfs部署#yum install nfs-utils rpcbind#vim /etc/exports/data/activemq 192.168.10.31(rw,sync,no_root_squash,no_all_squash)/data/activemq 192.168.10.4(rw…

java50车架适合身高,【经验分享】身高与车架的选择

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼车架的长度:骑在车上,在正常握把时,眼睛、把立前端和前轮花鼓三点一线则说明车架长度正好,否则可通过更换不同长度的把立来调整长度。在Airborne网站上看到了度量身体个部位长度和计算…

Java应用程序的简单令牌认证

“我喜欢编写身份验证和授权代码。” 〜从来没有Web开发人员。 厌倦了一次又一次地建立相同的登录屏幕? 尝试使用Okta API进行托管身份验证,授权和多因素身份验证。 JSON Web令牌已Swift成为保护Web应用程序安全的标准,并取代了Cookie和会话…

element手机验证格式_基于Vue+elementUI实现动态表单的校验功能(根据条件动态切换校验格式)...

前言开发过程中遇到了一个需求,根据用户选择的联系方式,动态改变输入框的检验条件,并且整个表单是可以增加的在线访问:动态表单校验github(欢迎star): https://github.com/Mrblackant. ..思考几个问题1.整个表单是可新增的,所以要…

matlab中rb代表什么意思,你知道“川藏线上”女游客举着“求RB”的牌子是啥意思吗?暗语啊!...

现在穷游好像一种旅行圈的时髦,很多人都想着穷游能够锻炼人的意志,能够促进人与人的交流与合作,能够在路上遇到不一样的精彩,能够发现人性与真善美。现在穷游的人不在少数,尤其是在川藏线上,想要穷游入藏的…

vscode 智能打印_vscode智能提示

vscode智能提示官方版支持部分的语法高亮,现在官方C插件更新比较快, Visual Studio for C / C代码的扩展增加了C / C在Visual Studio语言支持。vscode智能提示功能介绍语言服务代码格式(铛格式)自动完成(实验)符号搜索转到定义/声明查看定义/声明类/方法…

重节点差商matlab,数值分析佳习题(含答案).doc

数值分析佳习题(含答案)2008信息与计算科学专业计算方法习题参考解答 江世宏编PAGEPAGE 25第一章 绪论姓名 学号 班级习题主要考察点:有效数字的计算、计算方法的比较选择、误差和误差限的计算。1 若误差限为,那么近似数0.003400有几位有效数字?(有效数字…

matlab 柴油机仿真,用MATLAB/SIMULINK实现柴油机及其控制系统的动态仿真

第 16卷(1998)第 3期 内 燃 机 学 报 Transaetions of CSICE VDl_16(1998)No.3 ④ f 用 MATLAB/SIMULINK 实现 柴油机 及其控制系统的动态仿真 980045 细描 述 了空气流量 率、燃 空 比、指 示热 效率、摩擦损 失、平均指 示 压力输 出、发 动 机 动力 学…

华为主题锁屏壁纸换不掉_华为手机总多出莫名的照片?那是因为这3个设置没关闭,赶紧自查...

随着华为在科技、5G以及数码领域的表现越来越好,使用华为手机的人也越来越多。不知道你在使用华为手机的过程中,有没有这样的感觉,华为手机总是多出莫名其妙的照片,即使删除了下次还会出现。如果有这样的情况,可能是手…

tomcat 正常关闭_Tomcat的带有守护程序和关闭钩子的正常关闭

tomcat 正常关闭我的最后两个博客讨论了长时间轮询和Spring的DeferredResult技术,并且为了展示这些概念,我将我的Producer Consumer项目中的代码添加到了Web应用程序中。 尽管该代码演示了博客所提出的观点,但其逻辑上确实包含大量漏洞。 除了…

php nginx 域名重定向,Nginx默认虚拟主机、用户认证、域名重定向

Nginx默认虚拟主机定义默认虚拟主机配置文件,在http下面加入include vhost/*.conf在/usr/local/nginx/conf/下创建目录#mkdir vhost/ //创建vhost目录#cd vhost/ //进入目录#vim aaa.com.conf //编辑文件server{listen 80 default_server; // 有这个标记的就是默认虚拟主机serv…

Java:使用SingletonStream获得性能

仅具有一个元素的Java流有时会在应用程序中造成不必要的开销。 了解如何使用SingletonStream对象并为其中某些此类流获得十倍的性能,并了解如何同时简化代码。 背景 Java 8中的Stream库是有史以来Java语言最强大的功能之一。 一旦您开始了解它的多功能性和所产生的…

多元线性回归分析spss结果解读_多元线性回归分析理论详解及SPSS结果分析

当影响因变量的因素是多个时候,这种一个变量同时与多个变量的回归问题就是多元回归,分为:多元线性回归和多元非线性回归。这里直说多元线性回归。对比一元线性回归:1.1多元回归模型:1.2多元回归方程1.3估计的多元回归方…

gilab无法解析php文件,gitlab重新设置域名后就无法访问了。

gitlab-ctl status ,查看是nignx启动不成功。查看gitlab-ctl tail日志&#xff0c;一直报这个错误 &#xff1a;> /var/log/gitlab/nginx/current <2020-01-06_09:12:15.16681 /opt/gitlab/embedded/sbin/nginx: error while loading shared libraries: libutility_mini_…

nginx请求转发被拒绝_nginx反向代理(请求转发-URL匹配规则)

反向代理适用于很多场合&#xff0c;负载均衡是最普遍的用法。nginx 作为目前最流行的web服务器之一&#xff0c;可以很方便地实现反向代理。当在一台主机上部署了多个不同的web服务器&#xff0c;并且需要能在80端口同时访问这些web服务器时&#xff0c;可以使用 nginx 的反向…

php调用pdf2html,php html2pdf

*安装composer运行html2pdf时&#xff0c;readme里面建议按照composer-setup.exe安装过程中出现openssl的问题&#xff0c;在php.ini中开启相应extension即可&#xff0c;路径写绝对路径&#xff0c;否则按默认路径找不到在html2pdf的文件路径下&#xff0c;cmd运行composer in…

electron 打开调试_Electron 应用调试指南

Electron 是一个基于 Node.js 和 Chromium 的开源框架&#xff0c;用于构建桌面应用&#xff0c;开发者可以使用 web 技术(HTML&#xff0c;JavaScript 和 CSS)完成整个应用的开发。许多知名桌面应用基于 Electron 实现&#xff0c;如 VSCode&#xff0c;Slack 和 GitHub Deskt…

java中方法的命名_Java方法中的参数太多,第5部分:方法命名

java中方法的命名在上一篇文章 &#xff08;有关处理Java方法中过多参数的系列文章的 第4部分 &#xff09;中&#xff0c;我将方法重载视为一种向客户提供需要较少参数的版本的方法或构造函数的方法。 我描述了该方法的一些缺点&#xff0c;并建议从方法重载中摆脱出来以使用不…