2008-10-22 38 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;