Domanda
Come tutti gli sviluppatori Haxe sanno, è possibile utilizzare haxe.Timer.delayed ()
per ritardare la chiamata della funzione per qualche tempo. Ma questa funzione non esiste per Neko. C'è un modo per ottenere gli stessi risultati?
Soluzione
Devo prima controllarlo ma
function delayed(f, time) {
neko.vm.Thread.create(function() {
neko.Sys.sleep(time);
f();
});
}
potrebbe essere la cosa più vicina possibile. L'unico svantaggio è che l'applicazione diventa multi-thread che potrebbe causare seri problemi.
Altri suggerimenti
Ho pensato al tuo problema e penso che il modo migliore sia creare la tua classe Timer per Neko. Ho creato una classe Timer per te:
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;
}
}
Chiamalo così:
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();
}
}
Spero che sia d'aiuto.
Nota: questo ha una precisione di 100ms. Puoi aumentarlo diminuendo l'impostazione timerInterval.
Ho usato anche la classe e ho riscontrato un problema. Poiché non è completamente in tempo reale, dorme l'intervallo, chiama la funzione e reinserisce l'intervallo. Quindi, a seconda di quanto tempo impiega la funzione in esecuzione, scorre sempre più lentamente.
L'ho risolto sostituendo la riga 39 in questo modo:
//timer.lastCallTimestamp = Sys.time() * 1000;
timer.lastCallTimestamp = timer.lastCallTimestamp + timer.interval;
Sì, non conosco nulla tranne quello che menzioni nella tua prima risposta. Su Linux puoi usare SIGALARM - ma questo non sembra banale, codice C puro al 100%, e deve essere gestito con grande cura per evitare l'arresto anomalo della VM.