命令行应用程序中的计时器



试图在Haxe中创建一个简单的命令行应用程序,它有一个滴答作响的Timer,但似乎没有成功;计时器从未真正开始"滴答"。

package;
import haxe.Timer;
class TimerCallback {
    private static inline var CHAR_SPACE : Int = 32;
    public static function main() : Void {
        var myME = new TimerTicker();
        while (Sys.getChar(false) != CHAR_SPACE) {
            //loop until [space] detected, do nothing here
        }
    }
}
class TimerTicker {
    private var myTimer : Timer = null;
    public function new() {
        myTimer = new Timer(20);
        myTimer.run = timer_OnTick;
    }
    private function timer_OnTick() : Void {
        Sys.println ("foobar");
    }
/* destructor?! */
}


这是构建命令:

>haxe.exe -lib nme -main TimerCallback -cpp .bin

如果我不添加-lib nme,则代码不会编译(基于API文档,可以,因为cpp不支持Timer,因此只有静态函数可用

然而,如果我添加这个,代码会被编译——因为nme支持cpp-Timers——并创建exe(win),但timer_OnTick()永远不会被调用。于是exe启动,什么也没发生,只需按下SPACE和应用程序。退出

其他信息:
-导入的Timer.hx文件如下:haxelibnme5,1,8haxe。如果我是对的,这应该是可以的;正在工作
-使用haxe 3.1.3、nme 5.1.8、hxcpp 3.1.39(以及haxelib 3.1.0-rc.4(如果重要的话))

如有任何帮助,我们将不胜感激。

好的,我得到了Haxe社区(邮件列表)的帮助。如果有人碰巧需要,以下是解决方案:

PSEUDO CODE(未测试)

class RunLoop {
   static var queue = new Deque<Void->Void>();
   static var keepAlives:Int; = 1;

static public function release() enque(function () keepAlives--);

static public function retain() enque(function () keepAlives++);

static public function enque(task:Void->Void) queue.add(task);

static function main() { enque(entryPoint); release(); } static function entryPoint() { //code goes here } static function run() while (keepAlives:Int > 0) queue.pop()(); }

//Now you can go an implement a timer like so:

class Timer { var active:Bool = true; public function new(msecs:Int) { RunLoop.retain(); Thread.create(function () while(active) { Sys.sleep(msecs / 1000); if (active) RunLoop.enque(this.run); }); } public dynamic function run() {} public function stop() { active = false; RunLoop.release(); } }

//And a helper for blocking code:

class Task { var task:Void->T; var onDone:T->Void; public function new(task:Void->T, onDone:T->Void) { RunLoop.retain(); Thread.create(function () { var result = task(); RunLoop.enque(onDone.bind(result)); }); } }

//So then the code you want would look roughly like this:

static function entryPoint() { var timer = new Timer(); timer.run = function () trace('foobar'); function waitForSpace() { while (Sys.getChar(false) != CHAR_SPACE) { //loop until [space] detected, do nothing here } return true; } new Task( waitForSpace, function (_) timer.stop() //stop the timer so that the run loop can exit ); }

(back2dos提供的解决方案)

/*
1. Neko : works
2. C++: works, However, incrementing count in the if statement instead ( if( count++ == 0 ) { ... ) fails to increment count!  Fixed on Git?
3. Flash : works
4. Java : fails using Haxe 3.1.3
*/

### build.hxml ###

-main Main -swf main.swf -swf-version 12

--next

-main Main -neko main.n

--next

-main Main -cpp cpp -cmd cp cpp/Main ./main

--next

-main Main -java java -cmd cp java/Main.jar ./main-jar

### Main.hx ###

class Main { public static function main() { #if sys var count = 0; while( true ) { if( count == 0 ) { Timer.delay(function() trace("doThing1"), 3000); Timer.delay(function() trace("doThing2"), 1000); count++; } } #else Timer.delay(function() trace("doThing1"), 3000); Timer.delay(function() trace("doThing2"), 1000); #end } }

### Timer.hx ###

#if neko import neko.vm.Deque; import neko.vm.Thread; import neko.vm.Mutex; import neko.vm.Lock; #elseif cpp import cpp.vm.Deque; import cpp.vm.Thread; import cpp.vm.Mutex; import cpp.vm.Lock; #elseif java import java.vm.Deque; import java.vm.Thread; import java.vm.Mutex; import java.vm.Lock; #end

class Timer { #if sys static var timerThread : TimerThread; #else static var timers : Array; #end

static function __init__() {
    #if sys
    timerThread = new TimerThread();
    #else
    timers = [];
    #end
}
public static function stop() {
    #if sys
    timerThread.quit();
    #else
    for( t in timers )
        t.stop();
    #end
}
public static function delay( func : Void -> Void, delayMillis : Int ) {
    #if sys
    timerThread.addTimer(delayMillis/1000, func);
    #else
    timers.push( haxe.Timer.delay(func, delayMillis) );
    #end
}

}#if systypedef TTimerData={时间:浮动,函数:无效->无效
}

类TimerThread{var互斥:互斥;var queueLock:Lock;var队列:数组;var运行:布尔;公共函数new(){队列=[];queueLock=新锁定();mutex=新mutex();running=true;Thread.create(mainLoop);}公共函数addTimer(delaySec:foat,cb:Void->Void){mutex.aquire();var时间=haxe。Timer.stamp()+delaySec;var索引=0;while(index<queue.length&&time>=queue[index].time)索引++;queue.insert(index,{time:time,func:cb});互斥释放();queueLock.release();}公共函数退出(?cb:Void->Void){var me=这个;addTimer(0,function(){me.running=false;if(cb!=null)cb();});}函数mainLoop(){while(running){var唤醒:Null=Null;var现在=haxe。Timer.stamp();var ready=new Array();mutex.aquire();while(queue.length>0)if(queue[0].time<=now)ready.push(queue.shift());其他{wake=队列[0].time;打破}互斥释放();for(d in ready){d.函数();if(!running)打破}if(!running)打破if(wake==null)queueLock.wait();其他{var延迟=唤醒-haxe。Timer.stamp();如果(延迟>0)queueLock.wait(延迟);}}}}#完(Zjnue提供的解决方案,Hugh的修改代码)

相关内容

  • 没有找到相关文章

最新更新