LayaAir 定时器 Timer

 

目录

Timer 

编码示例

callLater 延迟调用

延迟执行

间隔循环

时钟暂停与恢复

结束定时器

优化策略


Timer 

Packagelaya.utils
public class Timer
InheritanceTimer Inheritance Object

Timer 是时钟管理类,它是一个单例,不要手动实例化此类,应该通过 Laya.timer 访问。 

Property(属性)
currFrame : int = 0 ,当前的帧数。
currTimer : Number ,当前帧开始的时间。
delta : int ,[read-only] 两帧之间的时间间隔,单位毫秒。
scale : Number = 1 ,时针缩放。
Method(方法)

callLater(caller:*, method:Function, args:Array = null):void ,延迟执行。

clear(caller:*, method:Function):void ,清理定时器。

clearAll(caller:*):void ,清理对象身上的所有定时器。

frameLoop(delay:int, caller:*, method:Function, args:Array = null, coverBefore:Boolean = true):void ,定时重复执行(基于帧率)。

frameOnce(delay:int, caller:*, method:Function, args:Array = null, coverBefore:Boolean = true):void ,定时执行一次(基于帧率)。

loop(delay:int, caller:*, method:Function, args:Array = null, coverBefore:Boolean = true, jumpFrame:Boolean = false):void

定时重复执行。

once(delay:int, caller:*, method:Function, args:Array = null, coverBefore:Boolean = true):void ,定时执行一次。

pause():void ,暂停时钟

resume():void ,恢复时钟

runCallLater(caller:*, method:Function):void ,立即执行 callLater 。

runTimer(caller:*, method:Function):void ,立即提前执行定时器,执行之后从队列中删除

编码示例

callLater 延迟调用

/**延迟执行一次
 * @param   caller 执行域(this)。
 * @param   method 定时器回调函数——只会执行一次
 * @param   args 回调参数。
 */
callLater(caller: any, method: Function, args?: Array<any>): void;

实现上述效果有很多的方式,这里以使用 callLater 函数为例进行说明。为 label 绑定单击事件,每点击一次label,则调用一次 callLater 方法,callLater 函数会执行一次自己的回调函数,在回调函数中修改 label  的透明度 alpha。

纯粹是为了演示用法,这个需求并不适合使用 callLater 函数,实现代码如下:

(function () {
    Laya.init(1080, 1920, Laya.WebGL);//初始化引擎,不支持WebGL时自动切换至Canvas
    Laya.stage.bgColor = "#252525";

    /**创建一个 label*/
    var label_info = createLabel("alpha=1");
    label_info.pos(250, 20);//组建显示的位置

    /**为label绑定单击事件 */
    label_info.on(Laya.Event.CLICK, this, function () {
        /**callLater:延迟执行,调用会马上执行其回调函数 */
        Laya.timer.callLater(this, animation, []);
        /**无论循环多次,callLater 也只会执行一次 animation ;只有下次点击进入时才会再次执行*/
        /* for (let i = 0; i < 10; i++) {
            Laya.timer.callLater(this, animation, []);
        } */
    });

    /** alpha_flag:为 true 时,label 的alpha值减小;为 false 时,label 的alpha值增加;*/
    var alpha_flag = true;
    function animation() {
        if (alpha_flag) {
            /**alpha:透明度,值为0-1,默认值为1,表示不透明 */
            label_info.alpha -= 0.2;
        } else {
            label_info.alpha += 0.2;
        }
        alpha_flag = label_info.alpha <= 0.1 ? false : alpha_flag;
        alpha_flag = label_info.alpha >= 1 ? true : alpha_flag;
        /**改变label的文本值
         * Number 的 toFixed 用于设置小数点位数,会四舍五入*/
        label_info.text = "alpha=" + label_info.alpha.toFixed(2);
    }

    //创建一个标签并添加到舞台
    function createLabel(message) {
        var label = new Laya.Label(message);
        label.fontSize = 30;//文本的字体大小
        label.color = "#fff";//文本颜色
        Laya.stage.addChild(label);//添加到舞台显示
        return label;
    }
})();

官网 demo:https://layaair.ldc.layabox.com/demo2/?language=ch&category=2d&group=Timer&name=CallLater

延迟执行

/**
 * 定时执行一次
 * @param   delay   延迟时间(单位为毫秒)。
 * @param   caller  执行域(this)。
 * @param   method  定时器回调函数。
 * @param   args    回调参数。
 * @param   coverBefore 是否覆盖之前的延迟执行,默认为 true 。
 */
once(delay: number, caller: any, method: Function, args?: Array<any>, coverBefore?: boolean): void;

/**
 * 定时执行一次(基于帧率)
 * @param   delay   延迟几帧(单位为帧)。
 * @param   caller  执行域(this)。
 * @param   method  定时器回调函数。
 * @param   args    回调参数。
 * @param   coverBefore 是否覆盖之前的延迟执行,默认为 true 。
 */
frameOnce(delay: number, caller: any, method: Function, args?: Array<any>, coverBefore?: boolean): void;

实现代码如下:

(function () {
    Laya.init(1080, 1920, Laya.WebGL);//初始化引擎,不支持WebGL时自动切换至Canvas
    Laya.stage.bgColor = "#252525";

    /**创建 label*/
    var label_info = createLabel("点我0.5秒后执行");
    var label_show = createLabel("点我30帧后执行");
    label_info.pos(100, 20);//组建显示的位置
    label_show.pos(400, 20);//组建显示的位置

    /**为label绑定单击事件 */
    var isLeft = false;
    label_info.on(Laya.Event.CLICK, this, function () {
        /**once在延迟指定时间后执行一次,单位为毫秒;如果多次调用 */
        Laya.timer.once(500, this, function () {
            if (isLeft) {
                label_info.x = label_info.x + 50;
                label_info.color = "#fff";
                isLeft = false;
            } else {
                label_info.x = label_info.x - 50;
                label_info.color = "#ff0";
                isLeft = true;
            }
        });
    });

    /**为label绑定单击事件 */
    var isRight = false;
    label_show.on(Laya.Event.CLICK, this, function () {
        /**frameOnce:基于帧率,在指定延迟后执行一次回调函数 */
        Laya.timer.frameOnce(30, this, function () {
            if (isRight) {
                label_show.x = label_show.x - 50;
                label_show.alpha = 1;
                isRight = false;
            } else {
                label_show.x = label_show.x + 50;
                label_show.alpha = 0.5;
                isRight = true;
            }
        });
    });

    //创建一个标签并添加到舞台
    function createLabel(message) {
        var label = new Laya.Label(message);
        label.fontSize = 30;//文本的字体大小
        label.color = "#fff";//文本颜色
        Laya.stage.addChild(label);//添加到舞台显示
        return label;
    }
})();

官网 demo:https://layaair.ldc.layabox.com/demo2/?language=ch&category=2d&group=Timer&name=DelayExcute

间隔循环

/**
 * 定时重复执行
 * @param   delay   间隔时间(单位毫秒)。
 * @param   caller  执行域(this)。
 * @param   method  定时器回调函数。
 * @param   args    回调参数。
 * @param   coverBefore 是否覆盖之前的延迟执行,默认为 true 。
 * @param   jumpFrame 时钟是否跳帧。基于时间的循环回调,单位时间间隔内,如能执行多次回调,出于性能考虑,引擎默认只执行一次,设置jumpFrame=true后,则回调会连续执行多次
 */
loop(delay: number, caller: any, method: Function, args?: Array<any>, coverBefore?: boolean, jumpFrame?: boolean): void;

/**
 * 定时重复执行(基于帧率)。
 * @param       delay   间隔几帧(单位为帧)。
 * @param       caller  执行域(this)。
 * @param       method  定时器回调函数。
 * @param       args    回调参数。
 * @param       coverBefore     是否覆盖之前的延迟执行,默认为 true 。
 */
frameLoop(delay: number, caller: any, method: Function, args?: Array<any>, coverBefore?: boolean): void;

实现代码如下:

(function () {
    Laya.init(1080, 1920, Laya.WebGL);//初始化引擎,不支持WebGL时自动切换至Canvas
    Laya.Stat.show(0, 0);/**显示性能统计面板 */
    Laya.stage.bgColor = "#252525";

    /**创建 label*/
    var label_info = createLabel("I am Loop");
    var label_show = createLabel("I am frameLoop");
    label_info.pos(Laya.Browser.clientWidth, 20);//组建显示的位置
    label_show.pos(Laya.Browser.clientWidth, 80);//组建显示的位置

    /**loop:定时重复执行(基于时间,单位为毫秒)
     * frameLoop:定时重复执行(基于帧率)*/
    Laya.timer.loop(40, this, animation_loop);
    Laya.timer.frameLoop(2, this, animation_frameLoop);

    function animation_loop() {
        label_info.x -= 2;
        if (label_info.x + label_info.width < 0) {
            label_info.x = Laya.Browser.clientWidth;
        }
    }

    function animation_frameLoop() {
        label_show.x -= 2;
        if (label_show.x + label_show.width < 0) {
            label_show.x = Laya.Browser.clientWidth;
        }
    }

    //创建一个标签并添加到舞台
    function createLabel(message) {
        var label = new Laya.Label(message);
        label.fontSize = 30;//文本的字体大小
        label.color = "#fff";//文本颜色
        Laya.stage.addChild(label);//添加到舞台显示
        return label;
    }
})();

时钟暂停与恢复

/**
 * 暂停时钟————暂停所有 Timer
 */
pause(): void;
/**
 * 恢复时钟————恢复所有 Timer
 */
resume(): void;

实现代码如下:

(function () {
    Laya.init(1080, 1920, Laya.WebGL);//初始化引擎,不支持WebGL时自动切换至Canvas
    Laya.Stat.show(0, 0);/**显示性能统计面板 */
    Laya.stage.bgColor = "#252525";

    /**创建 label*/
    var label_info = createLabel("I am Loop");
    var label_show = createLabel("I am frameLoop");
    var label_btn = createLabel("定时器暂停");
    label_info.pos(Laya.Browser.clientWidth, 20);//组件显示的位置
    label_show.pos(Laya.Browser.clientWidth, 80);//组件显示的位置
    label_btn.pos(Laya.Browser.clientWidth / 2, 150);//组件显示的位置

    /**loop:定时重复执行(基于时间,单位为毫秒)
     * frameLoop:定时重复执行(基于帧率)*/
    Laya.timer.loop(40, this, animation_loop);
    Laya.timer.frameLoop(2, this, animation_frameLoop);

    function animation_loop() {
        label_info.x -= 2;
        if (label_info.x + label_info.width < 0) {
            label_info.x = Laya.Browser.clientWidth;
        }
    }

    function animation_frameLoop() {
        label_show.x -= 2;
        if (label_show.x + label_show.width < 0) {
            label_show.x = Laya.Browser.clientWidth;
        }
    }

    var isStop = false;
    label_btn.on(Laya.Event.CLICK, this, function () {
        if (isStop) {
            Laya.timer.resume();/**恢复时钟 */
            label_btn.text = "定时器运行";
            label_btn.color = "#fff";
            isStop = false;
        } else {
            Laya.timer.pause();/**暂停时钟 */
            label_btn.text = "定时器暂停";
            label_btn.color = "#f00";
            isStop = true;
        }
    });

    //创建一个标签并添加到舞台
    function createLabel(message) {
        var label = new Laya.Label(message);
        label.fontSize = 30;//文本的字体大小
        label.color = "#fff";//文本颜色
        Laya.stage.addChild(label);//添加到舞台显示
        return label;
    }
})();

结束定时器

/**
 * 清理定时器。
 * @param   caller 执行域(this)。——定时器与 clear 必须是同一个对象
 * @param   method 定时器回调函数。——定时器回调函数的名称
 */
clear(caller: any, method: Function): void;

/**
 * 清理对象身上的所有定时器。
 * @param   caller 执行域(this)。——定时器与 clear 必须是同一个对象
 */
clearAll(caller: any): void;

对于在某个时刻需要清理/结束的定时器,在指定定时器与清理定时时,执行域都指定为 Laya.stage,而不再是 this。

实现代码如下:

(function () {
    Laya.init(1080, 1920, Laya.WebGL);//初始化引擎,不支持WebGL时自动切换至Canvas
    Laya.Stat.show(0, 0);/**显示性能统计面板 */
    Laya.stage.bgColor = "#252525";

    /**创建 label*/
    var label_info = createLabel("I am Loop");
    var label_show = createLabel("I am frameLoop");
    var label_btn = createLabel("结束第1个定时器");
    var label_btn_2 = createLabel("结束第所有定时器");

    label_info.pos(Laya.Browser.clientWidth, 20);//组件显示的位置
    label_show.pos(Laya.Browser.clientWidth, 80);//组件显示的位置
    label_btn.pos(Laya.Browser.clientWidth / 4, 150);//组件显示的位置
    label_btn_2.pos(Laya.Browser.clientWidth * (2 / 3), 150);//组件显示的位置

    /**loop:定时重复执行(基于时间,单位为毫秒)
     * frameLoop:定时重复执行(基于帧率)
     * 对于将来某个时刻需要清理的定时器,执行域设置为 Laya.stage,清理时的执行域也是 Laya.stage,如果使用 this,则定时器会结束不了*/
    Laya.timer.loop(40, Laya.stage, animation_loop);
    Laya.timer.frameLoop(2, Laya.stage, animation_frameLoop);

    function animation_loop() {
        label_info.x -= 2;
        if (label_info.x + label_info.width < 0) {
            label_info.x = Laya.Browser.clientWidth;
        }
    }

    function animation_frameLoop() {
        label_show.x -= 2;
        if (label_show.x + label_show.width < 0) {
            label_show.x = Laya.Browser.clientWidth;
        }
    }

    label_btn.on(Laya.Event.CLICK, this, function () {
        /**清理指定的定时器,通过函数名确定
         * 清理定时器同样执行域为 Laya.stage */
        Laya.timer.clear(Laya.stage, animation_loop);
    });


    label_btn_2.on(Laya.Event.CLICK, this, function () {
        /**清理对象身上的所有定时器
         * 清理定时器同样执行域为 Laya.stage */
        Laya.timer.clearAll(Laya.stage);
    });

    //创建一个标签并添加到舞台
    function createLabel(message) {
        var label = new Laya.Label(message);
        label.fontSize = 30;//文本的字体大小
        label.color = "#fff";//文本颜色
        Laya.stage.addChild(label);//添加到舞台显示
        return label;
    }
})();

当一个对象的生命周期结束时,记得清除其内部的Timer。

优化策略

1、不要在 Timer 的循环里创建对象及复杂计算。

2、由于Timer的loop()与frameLoop()方法里会不断的循环执行,当创建对象及复杂计算时,会导致大量的性能消耗出现在循环里,因此尽可能不要在循环里创建对象及复杂计算。

 

Linux 定时器 timer_list 是一个内核数据结构,用于管理内核中的定时器。它是一个双向链表,每个节点表示一个定时器timer_list 的定义位于 `<linux/timer.h>` 头文件中。 每个 timer_list 节点的定义如下: ```c struct timer_list { struct list_head entry; // 定时器节点的链表指针 unsigned long expires; // 定时器的到期时间 void (*function)(unsigned long); // 定时器回调函数 unsigned long data; // 传递给回调函数的参数 struct tvec_base *base; // 定时器所属的时间轮 int slack; // 定时器的松弛时间 }; ``` 其中,`entry` 是一个 `list_head` 结构,用于将节点连接到定时器链表中。`expires` 表示定时器的到期时间,以 jiffies 单位表示。`function` 是定时器的回调函数,在定时器到期时被调用。`data` 是传递给回调函数的参数。`base` 表示定时器所属的时间轮,`slack` 是定时器的松弛时间,用于处理定时器的精度。 在使用 timer_list 时,可以使用以下函数进行初始化和操作: - `timer_setup(struct timer_list *timer, void (*function)(unsigned long), unsigned int flags)`:初始化一个定时器,并指定回调函数和标志。 - `init_timer(struct timer_list *timer)`:初始化一个定时器。 - `add_timer(struct timer_list *timer)`:将定时器添加到定时器链表中。 - `del_timer(struct timer_list *timer)`:从定时器链表中删除定时器。 - `mod_timer(struct timer_list *timer, unsigned long expires)`:修改定时器的到期时间。 这些函数可以通过 `<linux/timer.h>` 头文件中的宏来调用。通过操作 timer_list,可以实现在 Linux 内核中的定时器功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蚩尤后裔-汪茂雄

芝兰生于深林,不以无人而不芳。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值