2008-10-22 19 views
3

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

回答

4

不得不检查第一,但

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

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

+0

什么样的问题,如果你只为此创建一个线程? – Tom 2010-05-17 18:17:55

+0

@Tom,函数f()将在另一个线程的上下文中执行。它可能使用共享资源或调用其他函数,它们使用共享资源。这种情况没有什么特别的,只是普通的多线程应用程序。 – vava 2010-05-17 19:06:38

0

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

1

我想过你的问题,我认为最好的方法是为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(); 
    } 
} 

希望有所帮助。

注意:这个有100ms的精度。您可以通过减少timerInterval设置来增加此值。

1

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

我更换39行,像这样解决了这个问题:

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