suineg 发表于 2017-11-8 11:45:19

[Lua]分享一个能在短时间内多次触发只执行一次的方法库(附源码)V1.1

本帖最后由 suineg 于 2017-11-8 07:03 AM 编辑

起因是我昨天挂领悟时会卡住,
不停的弹"基本等级不够,无法练习"之类的提示,
然后就想到了写这个东西,
代码中Common.Test仅供测试用,可以删除;

API介绍:
Common.InstanceRun(执行的函数, 间隔的时间, 执行函数的参数);
会立刻执行对应的函数,并且在间隔的时间内都不会再次执行;
间隔的时间不填则默认2秒;
执行函数无参数则不填,
我的图片示例,
Common.InstanceRun(Common.Test);

使用场景:
1.比如同时N个人对你叫杀"\S+想杀死你",可以Common.InstanceRun(战斗准备);
2.比如N个人同时打你,血量到了要处理的警戒线,可以Common.InstanceRun(警告处理, 0.5);
3.比如我上面自己的案例;
4.换武器的pfm,可以用这来防止在CD时的换武器导致busy;
5.自己想吧

V1.1修改:
1.Common.InstanceRun能返回本次是否执行了,执行了return true,否则return false;
   应用:一次只能放一个pfm的情况下,可以根据这来判断是否换个pfm放;
2.添加形参vParam,可以调用带参数的pVoid,Common = Common or {};

Common.tInstanceVoid = {};

Common.InstanceRun = function(pVoid, nTime, vParam)
        local strKey = tostring(pVoid);
        if strKey == nil or strKey == "" then return false; end
        if Common.tInstanceVoid ~= nil then return false; end
        if nTime == nil then nTime = 2; end
        Common.tInstanceVoid = 1;
        pVoid(vParam);
        DoAfterSpecial(nTime, "Common.InstanceReset(\"" .. strKey .. "\")", 12);
        return true;
end
Common.InstanceReset = function(strKey)
        if strKey == nil or strKey == "" then return; end
        Common.tInstanceVoid = nil;
end

Common.Test = function()
        Note("CT 1");
end

北大侠客行MUD,中国最好的MUD

longzaitian 发表于 2017-11-8 14:53:36

感谢楼主,学习了。

我原来碰到这种情况是使用DoAfterSpecial()和DeleteTemporaryTimers() 这两个函数配合着处理的。

suineg 发表于 2017-11-8 14:56:39

回复 2# longzaitian

刚好准备改一下的,
就发现你的回复了,
我用这模块重写了我战斗模块和一部分任务模块,
然后有点优化

你那应该是延时执行,
我这是立刻执行并且一定时间内不再执行

longzaitian 发表于 2017-11-8 18:20:26

回复 3# suineg

对,用那两个函数可以保证不会重复执行,但是确实是延时的,只有最后一个命令起作用,还是没有你写的这个实用。

sunpepe 发表于 2017-11-8 19:19:13

你们都是机器人{:7_282:}

creat 发表于 2017-11-8 20:27:01

回复 4# longzaitian


    DoAfterSpecial在处理重复触发上可能没有AddTimer更灵活,而且DoAfter和DoAfterSpecial的第二个实参只支持string。
   有一个封装好了的AddTimer可能就想不起来DA和DAS两个函数了hz1

longzaitian 发表于 2017-11-9 07:34:59

回复 6# creat
哈,要不是教主你说,我都不知道还有这个函数,去查了一下,DA还有DAS原来是这个函数的简化版啊,又学到新东西了,谢谢。


suineg 发表于 2017-11-9 12:27:21

回复 7# longzaitian


    根据自己的需要来,我DoAfter,DoAfterSpecial,还有自己封装的两种AddTimer都会用,不同的情况用不同的方法

sans 发表于 2017-11-14 00:02:27

大佬们都不分享,搞得神神秘秘的,俺就先分享一个,供新人们参考:
--封装一个临时timer,使连续相同触发时只有第一个触发有效
function ExecFirstTri(cmd) --cmd:string格式指令
local s = GetTimer("abcdeTimer")
if s ~= 0 then
Execute(cmd)
else
ResetTimer("abcdeTimer")
end
AddTimer("abcdeTimer", 0, 0, 2, "", timer_flag.Enabled + timer_flag.OneShot, "")
end

默认是2秒,可以根据自己的需求修改

suineg 发表于 2017-11-14 16:22:26

回复 9# sans

这个的范用性有点问题,
1.因为AddTimer的名字固定成abcdeTimer(或者)了,所以如果要实现多个,要不是把名字提出当成一个形参,要不就是写多个;
2.只能执行一行execute命令,无法执行复杂的函数功能;
还有个问题,我没跑这个代码所以不确定,以我当看伪代码的方式来看的话,
ResetTimer会不会在本来已经过的1秒后又重置,这样无限卡到2秒.

我的本意还是用的DoAfterSpecial,
相当于匿名Timer,
只用关注要传的参数pVoid,也就是干什么的
然后有需要就传后面的两个参数,无需要就空着,
也算是简单好用

纯技术讨论
页: [1] 2
查看完整版本: [Lua]分享一个能在短时间内多次触发只执行一次的方法库(附源码)V1.1