Pregunta
Como todos los desarrolladores de Haxe saben, podría usar haxe.Timer.delayed ()
para retrasar la llamada a la función por un tiempo. Pero esta función no existe para Neko en absoluto. ¿Hay alguna manera de lograr los mismos resultados?
Solución
Hay que comprobarlo primero pero
function delayed(f, time) {
neko.vm.Thread.create(function() {
neko.Sys.sleep(time);
f();
});
}
podría ser lo más cercano posible. El único inconveniente es que la aplicación se vuelve multiproceso, lo que podría generar problemas graves.
Otros consejos
Pensé en tu problema y creo que la mejor manera es crear tu propia clase Timer para Neko. Hice una clase de temporizador para ti:
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;
}
}
Llámalo así:
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();
}
}
Espero que ayude.
Nota: esta tiene una precisión de 100 ms. Puede aumentar esto disminuyendo la configuración timerInterval.
También utilicé la clase, y encontré un problema. Debido a que no es completamente en tiempo real, duerme el intervalo, llama a la función y vuelve a dormir el intervalo. Entonces, dependiendo de cuánto tiempo tome la función que está ejecutando, funciona más lento o más rápido.
Lo resolví reemplazando la línea 39 así:
//timer.lastCallTimestamp = Sys.time() * 1000;
timer.lastCallTimestamp = timer.lastCallTimestamp + timer.interval;
Sí, no sé nada excepto lo que mencionas en tu primera respuesta. En Linux puede usar SIGALARM, pero esto no parece un código C trivial y 100% puro, y debe manejarse con mucho cuidado para evitar que se caiga la máquina virtual.