日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2023/12/2 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 setitimer 创建两个定时器_UE4 Timer(定时器)相关源码分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

  • 文章屬于舊有文章搬運, 之前在csdn上面
  • 2019.11.6修改

Timer是定時器, 用途:

  • 延時執行事件
  • 周期性執行事件
參考官方文檔Using Timers

Timer可以...

Timer能...

Timer...

...

編不下去了, 自己百度谷歌吧(手動狗頭)


TimerManager

Timer的管理類是FTimerManager, 是一個全局的Timer管理類.

通常通過UWorld::GetTimerManager()獲得
可以看到實際實現是先判斷GameInstance是否存在, 存在返回UGameInstance的TimerManger, 否則返回UWorld自己的TimerManger

接著, 如上圖, TimerManger在UWorld和UGameInstance的構造函數中創建, 調用構造函數, 不試圖賦值UGameInstance

在TimerManger的構造函數中, 主要還是給InternalTime設0, 該值是TimerManger內部的一個獨立時鐘, 在TimerManger的每次Tick調用時計時.

在UWorld::Tick中調用FTimerManager的Tick函數實際執行Timer里面的操作

TimerManger的銷毀是在UWorld::FinishDestroy和UGameInstance::FinishDestroy中

delete然后置nullptr, 簡單粗暴.


Timer的執行

從堆棧中也可以FTimerManger::Tick被UWorld::Tick調用

如圖, 這個函數體主要做了如下內容 :

  • 先調用FTimerManager::HasBeenTickedThisFrame, 并維護LastTickedFrame避免一幀內被多次執行.

  • 然后InternalTime計時, 增加DeltaTime偏移量
  • 接著對ActiveTimerHeap和PendingTimerSet進行一定邏輯處理

ActiveTimerHeap是一個當前活躍的, 待處理的FTimerHandle數組

看while循環體主體邏輯:

不斷取堆頂的FTimerHandle, 并得到對應的FTimerData.

如果該FTimerData的狀態是可被移除, 那么移除, 繼續
不斷執行, 直到InternalTimer(內部的獨立時鐘)大于FTimerData的ExpireTime, 即定時器到時間了, 那么執行一定邏輯, 否則, 沒有過時間, 就直接break跳出循環

因為ActiveTimerHeap是按照過期時間排序的

接著看, 如果定時器到時間了, 會將ActiveTimerHeap的堆頂元素移動置CurrentlyExecutingTimer(當前正在執行的Timer), 并更新FTimerData的Status為ETimerStatus::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(定时器)相关源码分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。