Как известно каждому разработчику Haxe, вы можете использовать haxe.Timer.delayed()
для задержки вызова функции на некоторое время. Но этой функции у Неко вообще нет. Есть ли способ добиться таких же результатов?
Неко и haxe.Timer.delayed()
Ответы (4)
Надо сначала проверить, но
function delayed(f, time) {
neko.vm.Thread.create(function() {
neko.Sys.sleep(time);
f();
});
}
может быть самым близким из возможных. Единственным недостатком является то, что приложение становится многопоточным, что может привести к серьезным проблемам.
haxe.Timer
есть только один метод под neko или php, stamp()
. delayed()
доступен на всех других платформах, но не в неко.
- person vava; 18.05.2010
Я подумал о вашей проблеме и думаю, что лучший способ — создать собственный класс Timer для Neko. Я сделал для вас класс 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();
}
}
Надеюсь, это поможет.
Примечание: этот имеет точность 100 мс. Вы можете увеличить это, уменьшив настройку timerInterval.
Я также использовал этот класс и обнаружил одну проблему. Поскольку это не полностью реальное время, он приостанавливает интервал, вызывает функцию и снова приостанавливает интервал. Таким образом, в зависимости от того, сколько времени занимает функция, которую вы запускаете, она работает медленнее или быстрее.
Я решил это, заменив строку 39 следующим образом:
//timer.lastCallTimestamp = Sys.time() * 1000;
timer.lastCallTimestamp = timer.lastCallTimestamp + timer.interval;
Да, я ничего не знаю, кроме того, что вы упомянули в своем первом ответе. В Linux вы можете использовать SIGALARM, но это не выглядит тривиально, 100% чистый код C, и с ним нужно обращаться очень осторожно, чтобы избежать сбоя виртуальной машины.