尝试在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 doc它可以正常,因为cpp不支持Timer,因此只有静态函数可用)
但是,如果我要添加它,则编译代码 - 如果nme支持cpp Timers-,则创建exe(win),但永远不会调用timer_OnTick()
。所以exe开始,没有任何反应,只需按SPACE
和app。退出。
其他信息:
- 导入的Timer.hx
文件就是这个文件:haxe\lib\nme\5,1,8\haxe
。如果我是对的,这应该是好的&工作。
- 使用haxe 3.1.3,nme 5.1.8,hxcpp 3.1.39(如果有问题,则使用haxelib 3.1.0-rc.4)
非常感谢任何帮助。
答案 0 :(得分:1)
好的,我得到了Haxe社区(邮件列表)的帮助。如果有人碰巧需要它们,可以使用以下解决方案:
PSEUDO CODE(未经测试)
(由back2dos提供的解决方案)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 ); }
(Zjnue提供的解决方案,Hugh的修改代码)/* 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 sys typedef TTimerData = { time : Float, func : Void -> Void
}
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 }