Timer in command-line application - haxe

Trying to create a simple command-line application in Haxe which has a ticking Timer, but it does not seem to work out; the Timer never actually starts 'ticking'.
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?! */
}
And this is the build command:
>haxe.exe -lib nme -main TimerCallback -cpp .\bin
If I am not adding -lib nme, the code does not compile (based on API doc it's OK as Timer is not supported for cpp, so only static functions are available)
If I am adding this, however, the code is compiled -as nme supports cpp Timers-, and the exe is created (win), but timer_OnTick() is never called. So exe starts, nothing happens, one press SPACE and app. quits.Additional info:
- The imported Timer.hx file is this one: haxe\lib\nme\5,1,8\haxe. And if I am right, this should be OK & working.
- Using haxe 3.1.3, nme 5.1.8, hxcpp 3.1.39 (and haxelib 3.1.0-rc.4 if matters)Any help would be much appreciated.

Okay, I've got help from the Haxe Community (mailing list). Here are the solutions if anyone happen to need them:PSEUDO CODE (not tested)
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
);
} (solution provided by 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 sys
typedef TTimerData = {
time : Float,
func : Void -> Void
}
class TimerThread {
var mutex : Mutex;
var queueLock : Lock;
var queue : Array;
var running : Bool;
public function new() {
queue = [];
queueLock = new Lock();
mutex = new Mutex();
running = true;
Thread.create( mainLoop );
}
public function addTimer( delaySec : Float, cb : Void -> Void ) {
mutex.acquire();
var time = haxe.Timer.stamp() + delaySec;
var index = 0;
while( index < queue.length && time >= queue[index].time )
index++;
queue.insert(index, { time : time, func : cb });
mutex.release();
queueLock.release();
}
public function quit( ?cb : Void -> Void ) {
var me = this;
addTimer( 0, function() {
me.running = false;
if( cb != null )
cb();
} );
}
function mainLoop() {
while( running ) {
var wake : Null = null;
var now = haxe.Timer.stamp();
var ready = new Array();
mutex.acquire();
while( queue.length > 0 )
if( queue[0].time <= now )
ready.push(queue.shift());
else {
wake = queue[0].time;
break;
}
mutex.release();
for( d in ready ) {
d.func();
if( !running )
break;
}
if( !running )
break;
if( wake == null )
queueLock.wait();
else {
var delay = wake - haxe.Timer.stamp();
if( delay > 0 )
queueLock.wait(delay);
}
}
}
}
#end
(Solution provided by Zjnue, modified code of Hugh)

Related

Using functions as map keys in Haxe

I want to use functions as keys in a Map like this:
var timers : Map<Void->Void, snow.api.Timer>;
But Haxe won't compile:
Abstract Map has no #:to function that accepts IMap<Void -> Void, snow.api.Timer>
Is there a way to do this ?
It's easy to write a custom implementation:
import haxe.Constraints;
class FunctionMap<K:Function,V> implements IMap<K,V> {
private var _keys : Array<K>;
private var _values : Array<V>;
public function new () {
_keys = [];
_values = [];
}
public function get(k:K):Null<V> {
var keyIndex = index(k);
if (keyIndex < 0) {
return null;
} else {
return _values[keyIndex];
}
}
public function set(k:K, v:V):Void {
var keyIndex = index(k);
if (keyIndex < 0) {
_keys.push(k);
_values.push(v);
} else {
_values[keyIndex] = v;
}
}
public function exists(k:K):Bool {
return index(k) >= 0;
}
public function remove(k:K):Bool {
var keyIndex = index(k);
if (keyIndex < 0) {
return false;
} else {
_keys.splice(keyIndex, 1);
_values.splice(keyIndex, 1);
return true;
}
}
public function keys():Iterator<K> {
return _keys.iterator();
}
public function iterator():Iterator<V> {
return _values
.iterator();
}
public function toString():String {
var s = new StringBuf();
s.add("{");
for( i in 0..._keys.length ) {
s.add('<function>');
s.add(" => ");
s.add(Std.string(_values[i]));
if( i < _keys.length - 1 )
s.add(", ");
}
s.add("}");
return s.toString();
}
private function index(key:K) : Int {
for (i in 0..._keys.length) {
if (Reflect.compareMethods(key, _keys[i])) {
return i;
}
}
return -1;
}}
http://try.haxe.org/#DdF31
I just tried this in try.haxe.org, and the compiler doesn't seem to like it, so I'm guessing the answer is "no."
You could get around this with some cleverness:
class Test {
static function main() {
var map:Map<VoidVoid,String>;
map = new Map<VoidVoid,String>();
var thing = {func:foo};
map.set(thing,"bar");
trace(map.get({func:foo})); //fails
trace(map.get(thing)); //succeeds;
}
static function foo():Void
{
}
}
typedef VoidVoid = {
var func:Void->Void;
}
But that's not an ideal solution because wrapping it in a typedef like that will make it fail if it's not the exact same instance, even if the value inside is the same.
I also tried making a Map<Dynamic,String> since you can stuff function references in those, but that didn't work either.
At this point I should ask, what problem are you trying to solve this way? Perhaps it could be better solved some other way.

Adobe security setting popup not showing remember option

Adobe security setting popups
I am using flash player for audio recording purpose. I want 1st popup but may program showing 2nd popup. How get I get first popup
My Action Script Code is given below.
package
{
import fr.kikko.lab.ShineMP3Encoder;
import flash.events.ErrorEvent;
import flash.events.ProgressEvent;
import flash.events.StatusEvent;
import flash.display.Sprite;
import flash.media.Microphone;
import flash.system.Security;
import org.bytearray.micrecorder.*;
import org.bytearray.micrecorder.events.RecordingEvent;
import org.bytearray.micrecorder.encoder.WaveEncoder;
import flash.events.MouseEvent;
import flash.events.Event;
import flash.events.ActivityEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestMethod;
import flash.display.LoaderInfo;
import flash.external.ExternalInterface;
import flash.media.Sound;
import org.as3wavsound.WavSound;
import org.as3wavsound.WavSoundChannel;
public class Main extends Sprite
{
// private var recBar:RecBar = new RecBar();
private var mic:Microphone;
private var waveEncoder:WaveEncoder = new WaveEncoder();
private var recorder:MicRecorder = new MicRecorder(waveEncoder);
private var maxTime:Number = 30; // default time to record in seconds
private var tts:WavSound;
private var playingChannel:WavSoundChannel;
private var mp3Encoder:ShineMP3Encoder;
private var mp3done:Boolean = false; // if we done converting to mp3
private var wasRecorded:Boolean = false; // if we done recording
private var isPreviewing:Boolean = false; // if we are in previewing state now?
private var isConverting:Boolean = false; // if we are in converting state now?
public function Main():void
{
mic = Microphone.getMicrophone();
mic.setSilenceLevel(mic.activityLevel);
mic.gain = 50;
mic.setLoopBack(false);
mic.setUseEchoSuppression(true);
recorder.addEventListener(RecordingEvent.RECORDING, recording);
addCommands();
}
public function jStartRecording(max_time:Number):void
{
if (mic != null) {
mp3done = false;
wasRecorded = false;
maxTime = max_time;
recorder.record();
// recorder.microphone.addEventListener(StatusEvent.STATUS, onMicStatus);
ExternalInterface.call("justrec.recordingStarted");
}
else
{
ExternalInterface.call("justrec.recordingError");
}
}
public function jStopRecording():void
{
recorder.stop();
wasRecorded = true;
mic.setLoopBack(false);
ExternalInterface.call("justrec.recordingStopped");
}
public function jPreview():void
{
if(wasRecorded) {
previewRecording();
}
}
public function jStopPreview():void
{
if(isPreviewing) {
stopPreviewRecording();
}
}
// convert WAV to MP3
public function jConvert2MP3():void
{
if(wasRecorded) {
convert2mp3();
}
}
public function jSendFileToServer():void
{
// do nothing if we have not converted our record
if(mp3done) {
sendRecording();
}
else {
ExternalInterface.call("justrec.mp3ConvertingError");
}
}
/* ************ */
/* Private area */
/* ************ */
private function recording(e:RecordingEvent):void
{
var currentTime:int = Math.floor(e.time / 1000);
ExternalInterface.call("justrec.recordingActivity", String(currentTime), mic.activityLevel);
if(currentTime >= maxTime )
{
// force stop recording
jStopRecording();
}
}
private function previewRecording():void
{
if(isConverting) {
return;
}
if(isPreviewing) {
stopPreviewRecording();
}
isPreviewing = true; // force into previewing mode
tts = new WavSound(recorder.output);
playingChannel = tts.play();
// ?? ExternalInterface.call("justrec.previewStarted");
}
private function stopPreviewRecording():void
{
playingChannel.stop();
isPreviewing = false;
// ?? ExternalInterface.call("justrec.previewStopped");
}
// convert to mp3 using ShineMP3Encoder
private function convert2mp3():void {
if(isConverting) {
return;
}
if(isPreviewing) {
stopPreviewRecording();
}
// set position of ByteArray with WAV data to 0
// either converting sticks if previewing is done
recorder.output.position = 0;
isConverting = true;
mp3Encoder = new ShineMP3Encoder(recorder.output);
mp3Encoder.addEventListener(Event.COMPLETE, mp3EncodeComplete);
mp3Encoder.addEventListener(ProgressEvent.PROGRESS, mp3EncodeProgress);
mp3Encoder.addEventListener(ErrorEvent.ERROR, mp3EncodeError);
mp3Encoder.start();
}
private function mp3EncodeProgress(event: ProgressEvent) : void {
var percent:int = Math.round(event.bytesLoaded / event.bytesTotal * 100);
ExternalInterface.call("justrec.mp3Converting", String(percent));
}
private function mp3EncodeError(event: ErrorEvent) : void {
isConverting = false;
ExternalInterface.call("justrec.mp3ConvertingError");
}
private function mp3EncodeComplete(event: Event) : void {
mp3done = true; // converting flag
isConverting = false;
ExternalInterface.call("justrec.mp3Converted");
}
// send data to server
private function sendRecording():void
{
var _var1:String = '';
var globalParam:Object = LoaderInfo(this.root.loaderInfo).parameters;
for (var element:String in globalParam) {
if (element == 'host'){
_var1 = globalParam[element];
}
}
if(_var1 != '') {
var req:URLRequest = new URLRequest(_var1);
req.contentType = 'application/octet-stream';
req.method = URLRequestMethod.POST;
// req.data = recorder.output; -- for WAV data
req.data = mp3Encoder.mp3Data; // for MP3 data
var loader:URLLoader = new URLLoader(req);
loader.addEventListener(Event.COMPLETE, sendComplete);
loader.addEventListener(ProgressEvent.PROGRESS, sendProgress);
}
}
private function sendProgress(event: ProgressEvent) : void {
var percent:int = Math.round(event.bytesLoaded / event.bytesTotal * 100);
ExternalInterface.call("justrec.sendingProgress", String(percent));
}
// done sending record
private function sendComplete(event: Event) : void {
ExternalInterface.call("justrec.sendingFinished");
}
/* ***************** */
// helper functions //
/* *************** */
private function addCommands():void
{
ExternalInterface.addCallback("jStartRecording", jStartRecording);
ExternalInterface.addCallback("jStopRecording", jStopRecording);
ExternalInterface.addCallback("jPreview", jPreview);
ExternalInterface.addCallback("jStopPreview", jStopPreview);
ExternalInterface.addCallback("jConvert2MP3", jConvert2MP3);
ExternalInterface.addCallback("jSendFileToServer", jSendFileToServer);
}
// dispatches on allowing/denying access to Camera/Microphone
/*
private function onMicStatus(event:StatusEvent):void
{
ExternalInterface.call("justrec.micStatus");
if (event.code == "Microphone.Muted")
{
ExternalInterface.call("justrec.recordingError");
// trace("Microphone access was denied.");
}
}
*/
} // class Main
} // package

Sound won't play at a specific time in unity

I am trying to make a sound play with the timer goes to 3, 2, 1.
My timer starts at ten and has a three second delay. If I use the following code:
if (tl.myCoolTimer == 10)
{
print("Play Sound");
myAudioSource.Play();
}
It plays the Beep over and over again until the game starts and the counter goes below 10.
If I use the code:
if (tl.myCoolTimer == 3)
{
print("Play Sound");
myAudioSource.Play();
}
It doesn't play the sound at all. It doesn't even print the print statement.
I literally only changed the number. I am not sure why this isn't working.
I have also tried setting it to 3f to see if it is a float issue.
Timer Scripts
This is the starting Timer. it counts down to 3 (then the game starts)
public Text startGameTimerText;
public float startGameTimer = 3;
public void Start ()
{
startGameTimerText = GetComponent<Text> ();
}
public void Update ()
{
startGameTimer -= Time.deltaTime;
startGameTimerText.text = startGameTimer.ToString ("f1");
if (startGameTimer < 0) {
GameObject.Find ("GameStartTimer").SetActive (false);
}
}
This is the Game Timer It starts at 10 and counts down to 0.
public StartGameTimer gt; //this is the script the other timer is on
public Text timerText;
public float myCoolTimer = 10;
public void Start ()
{
timerText = GetComponent<Text> ();
}
public void Update ()
{
if (gt.startGameTimer > 0) {
myCoolTimer = 10;
} else {
myCoolTimer -= Time.deltaTime;
timerText.text = myCoolTimer.ToString ("f1");
}
}
Thanks Joe for the help. Here was my final answer. I know it is hacked, but I haven't figured out the Invoke thing yet. When I set the into it kept playing the entire time it was at "3", so i need to make it play only once.
private AudioSource myAudioSource;
public bool isSoundPlayed;
void Start()
{
myAudioSource = GetComponent<AudioSource>();
isSoundPlayed = false;
}
void Update()
{
if((int)tl.myCoolTimer == 3)
{
if (isSoundPlayed == false)
{
myAudioSource.Play();
isSoundPlayed = true;
}
return;
}
if ((int)tl.myCoolTimer == 2)
{
if (isSoundPlayed == true)
{
myAudioSource.Play();
isSoundPlayed = false;
}
return;
}
if ((int)tl.myCoolTimer == 1)
{
if (isSoundPlayed == false)
{
myAudioSource.Play();
isSoundPlayed = true;
}
return;
}
}

Dlang,Socket,Chat Server

I want to write a chat server.
Using the programming language D. (Dlang)
It is desirable to use OOP.
My example.(Not working)
import std.stdio;
import std.concurrency;
import core.thread;
import std.conv;
import std.socket;
synchronized class DataInfo{
shared this()
{
}
public shared Socket[] sockList;
shared void AddSocket(shared Socket scket)
{
sockList ~= scket;
}
shared(Socket[]) getSockList()
{
return to!(shared Socket[])(sockList);
}
}
void UserLoop(shared DataInfo data,shared(int) id)
{
Socket client;
synchronized(data)
{
client = cast(Socket)(data.sockList[id]);
}
while(true)
{
char[1024] buffer;
int sockCount = 0;
client.receive(buffer);
synchronized(data)
{
sockCount = data.sockList.length;
}
for(int i =0 ; i < sockCount; i++)
{
synchronized(data)
{
auto sk = cast( Socket)(data.sockList[i]);
sk.send("Hello world");
}
}
}
}
int main()
{
ushort port;
port = 4444;
auto listener = new TcpSocket();
assert(listener.isAlive);
listener.blocking = false;
listener.bind(new InternetAddress(port));
listener.listen(10);
writefln("Listening on port %d.", port);
shared(DataInfo) data = new shared(DataInfo);
while(true)
{
int len = 0;
auto client = cast(shared Socket)listener.accept();
synchronized(data)
{
data.AddSocket(client);
len = data.sockList.length;
}
spawn(&UserLoop,data,cast(shared int)len);
}
return 0;
}
How? How to fix the bug?
Can I get an example of correct chat servers? (Only Dlang)
Also, can you give an example of the correct client.
import vibe.d;
import vibe.utils.array;
shared static this()
{
Chat m_chat=new Chat();
ushort port=5555;
listenTCP(port,&m_chat.connHandler,"127.0.0.1");
}
class Chat{
private:
TCPConnection[] connz;
public:
void connHandler(TCPConnection conn){
sendMessage(conn,"Hello!\n");
connz~=conn;
while(conn.connected){
while(conn.waitForData(dur!"seconds"(1L))){
ubyte[1] c;
string inMessage;
while(conn.dataAvailableForRead){
conn.read(c);
inMessage~=c;
}
foreach(TCPConnection _con; connz){
if(_con!=conn)
sendMessage(_con,"Someone says: "~inMessage);
}
}
}
connz.removeFromArray(conn);
}
void sendMessage(TCPConnection conn, string message){
conn.write(cast(ubyte[])message);
}
}
Solution suggested by Lord_Evil

Trying to handle thread pool in a class

I'm trying to handle thread pool in a class.
below is my code.
#include <Windows.h>
class ClassA
{
public : // user API
ClassA()
{
}
~ClassA()
{
}
public : //my muiti-thread func
void init()
{
//*************************************
// multithread Initialization
//*************************************
pool = NULL;
cleanupgroup = NULL;
rollback = 0;
bool bRet = false;
pool = CreateThreadpool(NULL);
if(NULL == pool)
{
goto cleanPool;
}
rollback = 1;
SetThreadpoolThreadMaximum(pool, 5);
bRet = SetThreadpoolThreadMinimum(pool, 10);
if (FALSE == bRet) {
goto cleanPool;
}
cleanupgroup = CreateThreadpoolCleanupGroup();
if (NULL == cleanupgroup) {
goto cleanPool;
}
rollback = 2;
SetThreadpoolCallbackPool(&CallBackEnviron, pool);
SetThreadpoolCallbackCleanupGroup(&CallBackEnviron,
cleanupgroup,
NULL);
return ;
cleanPool:
switch (rollback)
{
case 2:
// Clean up the cleanup group.
CloseThreadpoolCleanupGroup(cleanupgroup);
case 1:
// Clean up the pool.
CloseThreadpool(pool);
default:
break;
}
return ;
}
void foo()
{
PTP_WORK work = NULL;
work = CreateThreadpoolWork(ClassA::_delegate,
NULL,
&CallBackEnviron);
}
static void __stdcall _delegate(PTP_CALLBACK_INSTANCE Instance, PVOID Parameter, PTP_WORK Work)
{
//some code
}
PTP_POOL pool;
UINT rollback;
TP_CALLBACK_ENVIRON CallBackEnviron;
PTP_CLEANUP_GROUP cleanupgroup;
};
int main()
{
ClassA a;
a.init();
a.foo();
}
If you make a project and execute this code, it gets unhandled execption...
I have no clue why...
I think the exception is caused by an uninitialized structure CallBackEnviron. The documentation states that this structure must be initialized by InitializeThreadpoolEnvironment

Resources