Reputation: 25401
As every Haxe developer knows, you could use haxe.Timer.delayed()
to delay function call for some time. But this function doesn't exist for Neko at all. Is there a way to achieve the same results?
Upvotes: 3
Views: 1642
Reputation: 11
I used the class as well, and I found one issue. Because is not completely realtime, it sleeps the interval, calls the function, and sleeps the interval again. So, depending on how long the function you are running takes, it ticks slower or faster.
I've solved it by replacing line 39 like so:
//timer.lastCallTimestamp = Sys.time() * 1000;
timer.lastCallTimestamp = timer.lastCallTimestamp + timer.interval;
Upvotes: 1
Reputation: 8127
I thought about your issue and I think the best way is to create your own Timer class for Neko. I made a Timer class for you:
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;
}
}
Call it like this:
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();
}
}
Hope that helps.
Note: this one has an accuracy of 100ms. You can increase this by decreasing the timerInterval setting.
Upvotes: 1
Reputation: 2352
Yes I don't know anything except for what you mention in your first answer. On Linux you can use SIGALARM - but this doesn't look trivial, 100% pure C code, and needs to be handled with great care to avoid crashing the VM.
Upvotes: 0
Reputation: 25401
Have to check it first but
function delayed(f, time) {
neko.vm.Thread.create(function() {
neko.Sys.sleep(time);
f();
});
}
might be the closest thing possible. The only cons is that application becomes multi threaded which could lead to serious problems.
Upvotes: 4