【问题标题】:Neko and haxe.Timer.delayed()Neko 和 haxe.Timer.delayed()
【发布时间】:2008-10-22 15:58:26
【问题描述】:

正如每个 Haxe 开发人员都知道的那样,您可以使用 haxe.Timer.delayed() 来延迟函数调用一段时间。但是对于 Neko 来说,这个功能根本不存在。有没有办法达到同样的效果?

【问题讨论】:

    标签: haxe neko


    【解决方案1】:

    必须先检查,但是

    function delayed(f, time) {
       neko.vm.Thread.create(function() {
           neko.Sys.sleep(time);
           f();
       });
    }
    

    可能是最接近的东西。唯一的缺点是应用程序变成了多线程,这可能会导致严重的问题。

    【讨论】:

    • 如果只为此目的创建一个线程会出现什么问题?
    • @Tom,函数 f() 将在另一个线程的上下文中执行。它可能使用共享资源或调用其他使用共享资源的函数。这种情况并没有什么特别之处,只是普通的多线程应用程序。
    • 在这种情况下,最好使用 haXe 创建 Neko 应用程序。你为什么不这样做?
    • @Tom,我这样做了 :) 但是haxe.Timer 在 neko 或 php 下只有一种方法,stamp()delayed() 在所有其他平台上可用,但在 neko 中不可用。
    • 啊,我明白了。在这种情况下,我建议您为 neko 创建自己的 Timer 类。静态构造函数将创建一个新线程,它只是按一定的时间间隔循环,跟踪时间戳并注册新添加的计时器。祝你好运。如果您打算这样做,如果您可以为 haXe 社区分享课程,那就太好了。
    【解决方案2】:

    我考虑了您的问题,我认为最好的方法是为 Neko 创建您自己的 Timer 类。我为你做了一个 Timer 类:

    NekoTimer.hx

    package;
    import neko.Sys;
    
        class NekoTimer 
        {
        private static var threadActive:Bool = false;
        private static var timersList:Array<TimerInfo> = new Array<TimerInfo>();
        private static var timerInterval:Float = 0.1;
    
        public static function addTimer(interval:Int, callMethod:Void->Void):Int
        {
            //setup timer thread if not yet active
            if (!threadActive) setupTimerThread();
    
            //add the given timer
            return timersList.push(new TimerInfo(interval, callMethod, Sys.time() * 1000)) - 1;
        }
    
        public static function delTimer(id:Int):Void
        {
            timersList.splice(id, 1);
        }
    
        private static function setupTimerThread():Void
        {
            threadActive = true;
            neko.vm.Thread.create(function() {
                while (true) {
                    Sys.sleep(timerInterval);
                    for (timer in timersList) {
                        if (Sys.time() * 1000 - timer.lastCallTimestamp >= timer.interval) {
                            timer.callMethod();
                            timer.lastCallTimestamp = Sys.time() * 1000;
                        }
                    }
                }
            });
        }
    }
    
    private class TimerInfo
    {
        public var interval:Int;
        public var callMethod:Void->Void;
        public var lastCallTimestamp:Float;
    
        public function new(interval:Int, callMethod:Void->Void, lastCallTimestamp:Float) {
            this.interval = interval;
            this.callMethod = callMethod;
            this.lastCallTimestamp = lastCallTimestamp;
        }
    }
    

    这样称呼它:

    package ;
    
    import neko.Lib;
    
    class Main 
    {
        private var timerId:Int;
    
        public function new()
        {
            trace("setting up timer...");
            timerId = NekoTimer.addTimer(5000, timerCallback);
            trace(timerId);
    
            //idle main app
            while (true) { }
        }
    
        private function timerCallback():Void
        {
            trace("it's now 5 seconds later");
            NekoTimer.delTimer(timerId);
            trace("removed timer");
        }
    
        //neko constructor
        static function main() 
        {
            new Main();
        }
    }
    

    希望对您有所帮助。

    注意:这个精度为 100 毫秒。您可以通过减小 timerInterval 设置来增加此值。

    【讨论】:

    • 尽管我支持您的努力,但这并不能解决任何问题:) 回调仍将在您在课堂上创建的不同线程的上下文中运行,因为您无法做到将其迁移到主要的。
    • 其实我在睡觉的时候才意识到这一点……我要去haxe邮件列表上问这个问题。
    【解决方案3】:

    我也使用了这个类,但我发现了一个问题。因为不是完全实时的,所以休眠间隔,调用函数,再次休眠间隔。因此,根据您运行的功能需要多长时间,它的滴答声会变慢或变快。

    我已经通过像这样替换第 39 行来解决它:

    //timer.lastCallTimestamp = Sys.time() * 1000;
    timer.lastCallTimestamp = timer.lastCallTimestamp + timer.interval;
    

    【讨论】:

      【解决方案4】:

      是的,除了您在第一个答案中提到的内容外,我什么都不知道。在 Linux 上,您可以使用 SIGALARM - 但这看起来并不简单,100% 纯 C 代码,需要非常小心地处理以避免 VM 崩溃。

      【讨论】:

        猜你喜欢
        • 2017-01-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多