`

多timer管理实例-八音盒

 
阅读更多

from http://bbs.9ria.com/forum.php?mod=viewthread&tid=46386

 

多timer管理实例-八音盒

在一些游戏项目中我们经常会用到数量众多的timer或者setInterval和setTimeout。那么如果要实现一些比如暂停之类的功能就会牵涉到timer的管理问题上。
  之前也有一些朋友在论坛提出对这方面知识的询问,通过悬赏也引出了不少高手的多timer管理的实例。比如单timer实现多timer效果的,还有 多timer统一管理的等等。其中大家比较关心的也是比较被选用的可能就是单timer实现多timer效果的。其中有人提到了最小堆管理方法,也有直接 用时间比对的方法。在这里我向大家介绍一种本人设计的一种类类似八音盒原理的管理方法。

  相信大家都知道八音盒的运作原理,就是在一根滚动的柱子上根据击打的节奏和音符所在序位刻下凹槽或者制造突起。然后当这些凹槽或者凸起经过不同长度拨 片的时候发出对应的声音。其原理和计算机的0101 加指针很有相似之处。那么在一个制作完成的八音盒里就是N个音符按照自己的时间间隔来执行发声,这和timer管理中函数根据自身间隔执行程序是类似的。 那么我们也可以将程序做成八音盒的结构,一个索引指针表示现在滚柱正经过拨片的地方,一个数组序列表示滚柱上的凹曹和序号,然后用一个timer来做驱动 滚柱转动的动力。然后我们只要根据需要在数组了记录下函数触发的间隔和序号就可以象八音盒那样正常工作了。

  这个时候有人会问,模拟这个结构和其他的管理方法有什么区别?这么做有什么好处吗?
  我的思考是这样的:其他的多timer管理或者模拟都需要根据当前的timer心跳也就是时间去逐个比对哪个程序该触发了哪个程序不该触发了,方法有两种:
  第一种是逐个去把间隔时间减少,当间隔时间小于等于0的时候触发函数并且把时间间隔重置为函数间隔时间。
  第二种则是用当前的心跳时间去求余,也就是time %间隔时间,当余为0的时候执行函数。

  两种方式都必须根据timer的数量做数学运算,如果有10000个timer就要做10000次取值+减法+赋值+判断,或者做10000次取值+ 求余+判断。Timer的数量小还好,数量一大势必成为巨大的负担,特别是我们为了追求精确往往把心跳timer的时间间隔设置的尽量小。比如new Timer(1),让他能跑多快跑多快,那么这些数学运算和判断就会有多快就跑多多了。

  那么有什么办法可以避免每次心跳都去做如此多次的运算吗?如何把运算次数降到最小?这时我想到了,如果每 次心跳去驱动一个指针,而这个指针指向的一个数组的指针位置能读出我这次心跳应该执行的函数就好了。这样1000个timer也只是一次心条去取 10000次值而已,免计算免判断直接运行。那么这个数组该怎么生成呢?在新的timer被添加进来的时候我们可以得到他所请求的时间间隔,我们可以根据 现下所已经有的timer的间隔来建立这张表,而这张表的完整长度就是所有间隔时间的最小公倍数。

  比如我们有3个timer间隔分别为2、3、4毫秒,那么生成一张长度为2、3、4的最小公倍数长度12的数组,数组索引代表时间12毫秒为一个循 环,每次心跳只要计算出指针在这个数组中的位置即可,而每位中则保存该时间需要触发的函数在函数表里的索引号即可。那么每次得到指针后就可以以直接取值的 方式来获取和执行函数了。
如下图:



 

那么以这个例子来说一个12长度的数组就可以解决正确间隔判断问题而避免了多次的数学计算和判断。但是到这里并没有结束,请继续往下看。
  看到这,大家都认为可以以生成最小公倍数长度的列表来避免过多的运算了。但是实际并非如此,比如一个比较极端的例子,我只有2个timer,但是一个 间隔是 1 一个间隔是1000000000000毫秒。这会造成什么? 最小公倍数是1000000000000,我们按上面的方法生成的列表长度将是1000000000000。或者我有10000个timer间隔是1到 10000不等,可想而知生成的列表有多长花在生成列表上的时间有多多。那么这里生成一张完整的列表的想法就被否定掉了。于是我想到的则是生成一张局部 的,根据当前时间后的部分列表当列表被消耗完后清空数组继续生成。这样在大部分时间里我们仍然是以完整列表的方式在运行,只在列表消耗完的时候需要临时额 外消耗一些时间来生成一张列表。这就像开火车没路了临时铺一段铁轨然后再开没路了继续铺。而且这样做有另外一个好处,就是在有新的timer被加入进来的 时候生成列表也不会太消耗时间,只是舍弃当前在使用的一小段列表重新生成一小段而不是舍弃整张列重新表生成整张列表。这给多timer管理的灵活性加了保 证。

  有了目标我们就要考虑生成这一段列表的长度应该以什么为标准?固定长度?可以。但是这里我自己采用的是生成列表消耗时间来判断长度。程序中我用了 while(getTimer() – oldTime < 5){}来判断是否继续生成列表。意思就是在生成函数开始后5毫秒之内能生成多少就是多少,时间一到就宣告临时路段修建完成。好处是避免在timer数量 过多的时候导致消耗过多时间。比如只有10个timer可能5毫秒可以声称长达15秒的列表也就是15000长。而10000个timer的时候则只能生 成40到50毫秒的列表。保证不会因为生成列表而导致整个程序拖慢。特别是timer少的时候能保证最优效率,1X秒多执行个5毫秒的计算几乎可以忽略不 计。

  文章写到这里基本阐述了本多timer管理的实现原理和机制。最后放上源代码,方便暂时无法理解和自行编写的朋友们使用。Lii.fla里是一个10000个空timer的测试,有兴趣的朋友可以和官方的进行一下比较。

 

 

  • 大小: 106.6 KB
分享到:
评论

相关推荐

    C语言02-Timer0-Timer1-Timer2-Timer3-Timer4测试程序(STC32G-DEMO-CODE-22

    C语言02-Timer0-Timer1-Timer2-Timer3-Timer4测试程序(STC32G-DEMO-CODE-220311kw)C语言02-Timer0-Timer1-Timer2-Timer3-Timer4测试程序(STC32G-DEMO-CODE-220311kw)C语言02-Timer0-Timer1-Timer2-Timer3-Timer4...

    02-Timer0-Timer1-Timer2-Timer3-Timer4测试程序.rar

    测试程序中的每个文件应该对应一个定时器的实例,展示如何初始化、配置、启动和管理中断。通过分析和运行这些程序,开发者可以深入理解每个定时器的工作原理,以及如何根据项目需求进行优化。 在实际应用中,例如在...

    一个高层线程工具类(Timer)---马克-to-win java视频

    一个高层线程工具类(Timer)---马克-to-win java视频

    Remanent On-delayTimer for S7-300400.zip西门子PLC编程实例程序源码下载

    Remanent On-delayTimer for S7-300400.zip西门子PLC编程实例程序源码下载Remanent On-delayTimer for S7-300400.zip西门子PLC编程实例程序源码下载Remanent On-delayTimer for S7-300400.zip西门子PLC编程实例程序...

    timer的应用--yayu音乐心情

    总的来说,“timer的应用--yayu音乐心情”项目结合了C#的`Timer`控件、音频处理库`NAudio`以及可能的情感分析技术,创建了一个可以根据用户情绪定时播放音乐的桌面应用。这样的项目既涉及到了基础的编程技术,也涵盖...

    pb多timer事件实例.zip

    在这个"pb多timer事件实例"中,你可以期待看到如何设置和管理这些TIMER对象,以及如何在多个TIMER事件之间正确切换,以实现它们的并发运行而不会互相干扰。通过学习和理解这个实例,开发者将能够更有效地利用Power...

    PB9多Timer事件实例

    在"PB9多Timer事件实例"中,我们可能会遇到如何同时管理多个Timer的情况。这通常涉及到动态创建Timer对象、设置不同的Interval和处理各自的Timer事件。例如,我们可以创建一个数组来存储多个Timer对象,每个Timer...

    反时间限制anti-timer

    反时间限制,让许多试用版软件没有时间限制

    Python库 | new_timer-0.0.2-py3-none-any.whl

    python库。 资源全名:new_timer-0.0.2-py3-none-any.whl

    Java--Timer--TimerTask--.rar_java timer

    值得注意的是,`Timer`和`TimerTask`并不是线程安全的,因此不建议在多线程环境中直接共享一个`Timer`实例。另外,如果`TimerTask`的执行时间超过预定的调度间隔,可能会导致任务堆积,这被称为“定时器饥饿”。为...

    Agilely-Timer-for-Android

    Agilely-Timer-for-AndroidFor Agile and Scrum practitioners, this timer application allows to facilitate daily stand-up meetings and efficiently manage timeboxes. Time automatically allocated to ...

    10-MSP432-Timer-32-中断.rar

    10-MSP432-Timer-32-中断.rar

    Python库 | magic_timer-0.0.9-py3-none-any.whl

    例如,在编写代码时,我们可能需要知道某个函数执行需要多长时间,或者设置定时任务,`magic_timer`可能提供了这样的工具。 描述中提到该资源是"解压后可用",这意味着用户下载此wheel文件后,可以直接通过Python的...

    timer-integrator-ap.rar_V2

    在Linux操作系统中,驱动程序是连接硬件设备与操作...此外,对于系统程序员和嵌入式开发者来说,了解和分析这样的驱动代码有助于提高他们对Linux内核机制的理解,特别是关于中断处理、时间管理和设备驱动原理的部分。

    Python库 | timer_bot-0.4-py3-none-any.whl

    timer_bot可能是一个用于时间管理和定时任务的库。根据其名称,我们可以推测这个库可能专注于创建定时器功能,比如定时发送消息、执行周期性任务或进行时间相关的提醒。 在Python中,安装这样的库通常通过pip工具...

    Python库 | globus_timer_cli-0.1.7-py3-none-any.whl

    `globus_timer_cli-0.1.7-py3-none-any.whl` 是一个Python库的发行文件,它主要用于提供命令行工具,帮助用户管理和控制时间相关的任务。这个库是用Python 3编写的,因此它兼容Python 3.x版本。`whl` 文件是一种预...

Global site tag (gtag.js) - Google Analytics