Neko 和 haxe.Timer.delayed()

发布于 2024-07-08 18:25:20 字数 94 浏览 5 评论 0原文

每个 Haxe 开发人员都知道,您可以使用 haxe.Timer.delayed() 来延迟函数调用一段时间。 但Neko根本不存在这个功能。 有没有办法达到相同的结果?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

拥抱我好吗 2024-07-15 18:25:20

必须先检查一下,但这

function delayed(f, time) {
   neko.vm.Thread.create(function() {
       neko.Sys.sleep(time);
       f();
   });
}

可能是最接近的。 唯一的缺点是应用程序变成多线程,这可能会导致严重的问题。

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.

别把无礼当个性 2024-07-15 18:25:20

我考虑了你的问题,我认为最好的方法是为 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 设置来增加此值。

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.

浮世清欢 2024-07-15 18:25:20

我也使用了该类,并且发现了一个问题。 因为不是完全实时的,所以它会休眠该间隔,调用该函数,然后再次休眠该间隔。 因此,根据您运行的函数需要多长时间,它会变慢或变快。

我通过替换第 39 行解决了这个问题,如下所示:

//timer.lastCallTimestamp = Sys.time() * 1000;
timer.lastCallTimestamp = timer.lastCallTimestamp + timer.interval;

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;
当梦初醒 2024-07-15 18:25:20

是的,除了你在第一个答案中提到的内容之外,我什么都不知道。 在 Linux 上,您可以使用 SIGALARM - 但这看起来并不简单,100% 纯 C 代码,需要非常小心地处理以避免虚拟机崩溃。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文