在luat脚本程序中,往往需要用到延时和等待等逻辑功能。例如,你想得到每隔30秒查询当前内存,这里就需要用到延时和定时器。在每次打印后加上一个30秒的定时器或者30秒的延迟,既可以实现这个功能。本篇文章将介绍2个延时函数和4个定时器函数以及一个判定定时器激活状态的函数,讲解这些函数如何使用以及在什么环境下使用。
详细的API介绍见
sys API章节
和
rtos API章节
sys.wait():
-
sys.wait(ms):既属于延时也属于定时器,但只能适用于任务函数中(task)。它功能就是被调用时挂起当前协程,等延时时间结束结束后再继续执行剩下的协程功能。原理是先去启动一个定时器,将当前的协程挂起。如需在定时器计时结束前退出,可使用coroutine.resume接口重新激活协程。
创建也很简单,例子:sys.wait(1000) 会停止当前的协程任务,等1000ms后延时函数正常消亡,继续回来执行剩下脚本。
rtos.sleep():
-
rtos.sleep(ms):属于底层延时函数,可用于任何环境。函数执行原理:执行该函数会将操作系统中的Lua虚拟机任务挂起,在计时结束前无 法退出。
创建示例:rtos.sleep(1000) 执行后,Lua虚拟机任务就会被挂起,1000ms后函数正常消亡,继续执行Lua虚拟机任务。
接下来是介绍定时器,共有四种定时器,他们各有各的特点。所以我们在使用时一定要记清楚这些定时器的特点,挑选适合当前程序需求的定时器使用。在luat脚本程序中,同时运行的定时器是有数量限制的。8910平台的Luat最多支持50个定时器,如何理解50个定时器?在下面的知识扩展里详细讲解了。sys.timerStart()和function sys.timerLoopStart()的返回值是定时器ID,这个可以用来判断是否为同一个
定时器。或者也可以通过定时器的回调函数和回调参数是否相同来判断。
sys.timerStart():
-
sys.timerStart(fnc,ms,…):属于定时器,单词定时器,适用场景不限定。第一个参数是回调函数,第二个是超时时间(ms),第三个是回调函数的参数,返回值是定时器ID。在创建前会查找当前开启的定时器,有相同定时器ID或者回调函数和回调参数相同时,就会关闭签一个定时器,再创建新的定时器,重新计时。
function sys.timerLoopStart():
-
function sys.timerLoopStart(fnc,ms, …):属定时器,循环定时器,适用场景不限定。用法特点同单此定时器几乎相同。唯一区别就是单此和多次循环。
sys.wait()(仅适用于task):
-
function sys.wait(ms):延时介绍过,属于延时也属于定时器。单次定时器,适用场景仅限定task内。
sys.waitUntil()(仅适用于task):
-
sys.waitUntil(id,ms):属于定时器,单次定时器,适用场景不限定。第一个参数是消息ID,第二个是超时间。sys.waitUntil()的特性与sys.timerStart()的完全一样,区别是sys.waitUntil()仅限于task内部使用。特性与详细介绍看下图。
-
sys.timerStart:收到定时器事件,执行回调函数后,lib中自动消亡
-
sys.timerLoopStart:收到定时器事件,每次执行回调函数后,lib中重新创建
-
sys.wait:挂起的task收到定时器事件后,lib中自动消亡
-
sys.waitUntil:挂起的task收到消息事件或者定时器事件后,lib中自动消亡
手动消亡有两种方式:sys.timerstop()和sys.timerstopAll()
1.sys.timerstop(val,…)
参数是定时器ID或者定时器的回调函数和回调参数。使用这个函数可以关闭指定的一个定时器。
返回值为nil
2.sys.timerstopAll(fnc)
功能:关闭sys.timerStart和sys.timerLoopStart创建的某一个回调函数的所有定时器
参数:需要关闭的定时器回调函数。
返回值:nil
已经消亡的定时器,再去执行stop不会产生异常
sys.timerlsActive()
功能:判断“通过timerStart或者timerStart创建的定时器”是否处于激活状态
参数:通过timerStart或者timerStart创建的定时器返回的定时器id或者回调函数与回调参数。
参数:
参数为回调函数与回调参数时,如果处于激活状态,则返回bool类型的true,否则返回nil。
返回值:
参数为定时器ID时,如果处于激活状态,则返回function类型的定时器回调函数,否则返回nil
例子:
local function timerCbFnc2(tag)
log.info("timerCbFnc2",tag)
sys.timerStart(timerCbFnc2,5000,"test")
sys.taskInit(function()
sys.wait(3000)
log.info("after 3 senonds, timerCbFnc2 test isActive?",sys.timerIsActive(timerCbFnc2,"test"))
sys.wait(3000)
log.info("after 6 senonds, timerCbFnc2 test isActive?",sys.timerIsActive(timerCbFnc2,"test"))
end)
1.8910平台的Luat最多支持50个定时器,如何理解50个定时器?
看下列两端代码,猜测,最后分别还有几个定时器在运行。
sys.taskInit(function()
for i=1,50 do
sys.timerStart(function() end,1000)
log.info("不考虑其它代码中定时器的使用")
log.info("运行到这里,同时存在多少个定时器?")
end)
sys.taskInit(function()
for i=1,50 do
sys.wait(1000)
log.info("不考虑其它代码中定时器的使用")
log.info("运行到这里,同时存在多少个定时器?")
end)
第一段代码是创建50个回调函数相同,延时时间相同的单此定时器。通过前面的介绍可知, 如果回调函数和回调参数都相同的两个sys.timerStart()定时器,可视为同一定时器。当第一个sys.timerStart(function() end,1000)创建好后,再创建第二个sys.timerStart(function() end,1000)时,就会查找当前存在的定时器里,是否有相同的定时器,如果就就会将第一个关闭,创建第二个相同的定时器,并重新开始计时。所以第一个代码段最后吃剩一个定时器在运行。
第二段代码是创建50个sys.wait(1000)。当创建第一个sys.wait(1000)后,这个协程就会被挂起。1000ms后,继续执行剩下的程序,创建下一个sys.wait(1000)。所以,最后也只剩一个定时器。
下面这段代码,通过改变回调参数来同时创建50个sys.timerLoopStart(log.info,1000,“nCounter1”,i)。但看打印结果会发现,没到50个。因为打印出来的数量只是sys.timerLoopStart(log.info,1000,“nCounter1”,i)的数量,还有sys.wait(5000)等一些定时器没算在内。
local function wait1()
sys.wait(5000)
for i=1,50 do
sys.timerLoopStart(log.info,1000,"nCounter1",i)
sys.taskInit(wait1)
详细的API demo见The Timer demo章节
1.waitUntil()、wait()
- waitUntil()和wait()sys.wait和sys.waitUntil只能用在task中,或者被task的主函数直接或者间接调用。
local function IndirectCall()
sys.waitUntil("MSG_ID",5000)
sys.taskInit(function()
sys.wait(5000)
IndirectCall()
log.info("sys.wait和sys.waitUntil只能用在task中")
log.info("只能被task的主函数直接或者间接调用")
end)
2.timerStart()
local function publicTimerCbFnc(tag)
log.info("publicTimerCbFnc",tag)
sys.timerStart(publicTimerCbFnc,8000,"first")
local timerId2 = sys.timerStart(publicTimerCbFnc,8000,"second")
sys.timerStart(publicTimerCbFnc,8000,"third")
3.timerLoopStart()
local nCounter = 0
sys.taskInit(function ()
while true do
nCounter = nCounter+1
sys.wait(1000)
end)
sys.timerLoopStart(log.info,1000,"nCounter1",nCounter)
sys.timerLoopStart(function() log.info("nCounter2",nCounter) end,1000)0,"first")
1,定时器精度问题
Luat开发最小仅支持5毫秒的定时器,超时时间最小1ms(实际支持的最小时间是5ms,小于5ms的时间都被转化为5ms) 超时间最大0x7FFFFFFF(24.85天)。
另外毫秒级的定时器的误差较大,原因可参考Luat应用脚本运行框架
延时和定时器 相关资料
sys API章节和rtos API章节
延时和定时器demo说明
相关开发板购买链接
Air724UG开发板
Air724 开发板使用说明
作者:王海洋更新时间:2021年4月2日关键词:延时,定时器,timer目录延时和定时器简介API说明实现流程创建消亡自动消亡手动消亡判断定时器状态知识拓展示例常见问题相关资料以及购买链接延时和定时器简介在luat脚本程序中,往往需要用到延时和等待等逻辑功能。例如,你想得到每隔30秒查询当前内存,这里就需要用到延时和定时器。在每次打印后加上一个30秒的定时器或者30秒的延迟,既可以实现这个功能。本篇文章将介绍2个延时函数和4个定时器函数以及一个判定定时器激活状态的函数,讲解这些函数如何使用以.
文件放入现有项目并为其所必需。
tick = require " tick "
在每一帧开始时,应该调用tick.update()并给tick.update()上次调用以来的增量时间作为其参数。
tick. update (dt)
滴答。延迟(fn,延迟)
在给定的delay时间过后调用函数fn 。 返回关联的事件。
-- Prints "Hello world!" after 2 seconds
tick. delay ( function () print ( " Hello world! " ) end , 2 )
滴答.recur(fn,延迟)
以delay时间间隔调用函数fn 。 返回关联的事件。
-- Prints "tick!" every half-second
tick. r
想在lua中写一个Unity协程效果的函数,延时N秒触发。无奈lua中没有提供封装好的函数调用。
最开始的思路是利用lua的协程,在thread中调用sleep之类的方法,之前做安卓开发的时候就用类似的思路实现的。
结果百度了一圈,网上有四种方法实现sleep的效果。
4种方法转载自 https://blog.csdn.net/charlie_2010/article/details/671...
LUA延时控制与C++交互实现其它可参考方式Lua封装延时执行函数LUA的延时调用功能Sleep Function
与C++交互实现
通过C++提供Sleep函数给LUA调用即可,可以任意实现。比如超过5秒再提示相应倒计时功能。
if(funName == L"Sleep") {
if(lua->CheckParamCount(params, 1)) {
int sleepMs = l...
使用方法很简单
local scheduler = require("framework.scheduler")
local handler = scheduler.scheduleGlobal(function()
-- 想做的事情
0.2) -- 调用间隔
scheduler.unscheduleGlobal(handler) -- 取消定时器