www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - event based timer

reply maarten van damme <maartenvd1994 gmail.com> writes:
Hi everyone,
for getting to know d a little bit I'm writing a simple pingpong game using
gtk.
for it to work I need to be able to do something every 0.1 seconds so I was
wondering if there was some kind of timer in the phobos library.
I've looked everywhere but couldn't find one. Is it missing and do i have to
write my own or have I overlooked it?

maarten
Jul 19 2011
parent reply Piotr Szturmaj <bncrbme jadamspam.pl> writes:
maarten van damme wrote:
 Hi everyone,
 for getting to know d a little bit I'm writing a simple pingpong game
 using gtk.
 for it to work I need to be able to do something every 0.1 seconds so I
 was wondering if there was some kind of timer in the phobos library.
 I've looked everywhere but couldn't find one. Is it missing and do i
 have to write my own or have I overlooked it?

 maarten
There is no callback timer in Phobos. But here's my implementation of timer wheel I used in one of my projects: http://pastebin.com/dRRZtPVW. Feel free to use it if you want.
Jul 19 2011
next sibling parent reply maarten van damme <maartenvd1994 gmail.com> writes:
Thanks but it seems way more complex then I need, I tried writing my own but
I get an acces violation error. here is my try :
http://dl.dropbox.com/u/15024434/Timer.d . Can someone spot the error? keep
in mind I don't really understand the threading model and pointers.


2011/7/19 Piotr Szturmaj <bncrbme jadamspam.pl>

 maarten van damme wrote:

 Hi everyone,
 for getting to know d a little bit I'm writing a simple pingpong game
 using gtk.
 for it to work I need to be able to do something every 0.1 seconds so I
 was wondering if there was some kind of timer in the phobos library.
 I've looked everywhere but couldn't find one. Is it missing and do i
 have to write my own or have I overlooked it?

 maarten
There is no callback timer in Phobos. But here's my implementation of timer wheel I used in one of my projects: http://pastebin.com/dRRZtPVW. Feel free to use it if you want.
Jul 20 2011
parent reply "Daniel Murphy" <yebblies nospamgmail.com> writes:
private void  function() *  callBack;

should be private void  function() callBack;

void function() is a function pointer, void function()* is a pointer to a 
function pointer.

On lines 23 and 41, you shouldn't be dereferencing callBack.  Just use 
callBack() to call the function and 'this.callBack = callBack' to set it. 
Jul 20 2011
next sibling parent maarten van damme <maartenvd1994 gmail.com> writes:
Thanks a lot, now those errors are gone. Still it refuses to work
properly...
I have a method clockTick in Main.d and that should be called every 0.1
seconds, when I place a call to that method in a onmousenotify event(when
the mouse moves) It runs correctly apart from the odd fact I need to move my
mouse to play the game.
When I use that method in the timerclass it reaches only the lines where I
print something in the console but doesn't go any further without giving any
errors.

The complete code can be seen at:
http://dl.dropbox.com/u/15024434/d/Main.d
http://dl.dropbox.com/u/15024434/d/Timer.d
http://dl.dropbox.com/u/15024434/d/Sprite.d
http://dl.dropbox.com/u/15024434/d/Bain.d
http://dl.dropbox.com/u/15024434/d/PingPongBox.d

The code for the timer in Main.d is at line 63
clockTick method in Main.d is at line 93

2011/7/20 Daniel Murphy <yebblies nospamgmail.com>

 private void  function() *  callBack;

 should be private void  function() callBack;

 void function() is a function pointer, void function()* is a pointer to a
 function pointer.

 On lines 23 and 41, you shouldn't be dereferencing callBack.  Just use
 callBack() to call the function and 'this.callBack = callBack' to set it.
Jul 20 2011
prev sibling next sibling parent reply "Martin Nowak" <dawg dawgfoto.de> writes:
Well, I guessed right I think. In you're main file you are using global  
//VARIABLES but in fact they are thread local.
That is each thread has it's own copy of them, so that different threads  
don't mess up each others data.
You can try the other timer approach or solve your sharing.

It would be really better if phobos had some kind of timer. The thread  
solution is really suboptimal.

On Wed, 20 Jul 2011 11:20:24 +0200, maarten van damme  
<maartenvd1994 gmail.com> wrote:

 Thanks a lot, now those errors are gone. Still it refuses to work
 properly...
 I have a method clockTick in Main.d and that should be called every 0.1
 seconds, when I place a call to that method in a onmousenotify event(when
 the mouse moves) It runs correctly apart from the odd fact I need to  
 move my
 mouse to play the game.
 When I use that method in the timerclass it reaches only the lines where  
 I
 print something in the console but doesn't go any further without giving  
 any
 errors.

 The complete code can be seen at:
 http://dl.dropbox.com/u/15024434/d/Main.d
 http://dl.dropbox.com/u/15024434/d/Timer.d
 http://dl.dropbox.com/u/15024434/d/Sprite.d
 http://dl.dropbox.com/u/15024434/d/Bain.d
 http://dl.dropbox.com/u/15024434/d/PingPongBox.d

 The code for the timer in Main.d is at line 63
 clockTick method in Main.d is at line 93

 2011/7/20 Daniel Murphy <yebblies nospamgmail.com>

 private void  function() *  callBack;

 should be private void  function() callBack;

 void function() is a function pointer, void function()* is a pointer to  
 a
 function pointer.

 On lines 23 and 41, you shouldn't be dereferencing callBack.  Just use
 callBack() to call the function and 'this.callBack = callBack' to set  
 it.
Jul 20 2011
parent David Nadlinger <see klickverbot.at> writes:
On 7/20/11 12:05 PM, Martin Nowak wrote:
 It would be really better if phobos had some kind of timer. The thread
 solution is really suboptimal.
I think a major problem when trying to implement a general-purpose solution is that, by its very nature, a timer depends on the event handling scheme used. For example, if you wanted to use a timer on Posix to interrupt your potentially blocking system calls, you would use alarm() to set a signal-based timeout and register a signal handler for it. On the other hand, a typical GUI application has its own event loop to integrate with, for an application using non-blocking I/O, you would like to transparently map your timers on select()/… timeout arguments, etc. David
Jul 20 2011
prev sibling parent Chris Molozian <chris cmoz.me> writes:
As you're creating a Gtk app, have you considered using glib.Timer 
<http://gtkd.mikewey.eu/src/glib/Timer.html> or glib.Timeout 
<http://gtkd.mikewey.eu/src/glib/Timeout.html> (depending on your 
needs)? I do almost all my Gtk development in Vala these days, so I 
haven't used them from D (so not sure if you've encountered problems 
with them).

Cheers,

Chris


On 07/20/11 10:20, maarten van damme wrote:
 Thanks a lot, now those errors are gone. Still it refuses to work 
 properly...
 I have a method clockTick in Main.d and that should be called every 
 0.1 seconds, when I place a call to that method in a onmousenotify 
 event(when the mouse moves) It runs correctly apart from the odd fact 
 I need to move my mouse to play the game.
 When I use that method in the timerclass it reaches only the lines 
 where I print something in the console but doesn't go any further 
 without giving any errors.

 The complete code can be seen at:
 http://dl.dropbox.com/u/15024434/d/Main.d
 http://dl.dropbox.com/u/15024434/d/Timer.d
 http://dl.dropbox.com/u/15024434/d/Sprite.d
 http://dl.dropbox.com/u/15024434/d/Bain.d
 http://dl.dropbox.com/u/15024434/d/PingPongBox.d

 The code for the timer in Main.d is at line 63
 clockTick method in Main.d is at line 93

 2011/7/20 Daniel Murphy <yebblies nospamgmail.com 
 <mailto:yebblies nospamgmail.com>>

     private void  function() *  callBack;

     should be private void  function() callBack;

     void function() is a function pointer, void function()* is a
     pointer to a
     function pointer.

     On lines 23 and 41, you shouldn't be dereferencing callBack.  Just use
     callBack() to call the function and 'this.callBack = callBack' to
     set it.
Jul 20 2011
prev sibling parent reply "Martin Nowak" <dawg dawgfoto.de> writes:
You are aware though that in your timer, the callback is executed from  
within a different thread.
You could let the timer thread send messages as clock ticks and wait on  
them, that way risking less issues
with implicit sharing.

Martin

----

import std.concurrency, std.stdio;
import core.thread;

struct Timer {
     private Tid clock;
     private bool running;
     enum Terminate { _ };
     enum Ping { _ };

     ~this() {
         stop();
     }

     void start(Duration duration) {
         avoidMailboxSpam();
         stop();
         clock = spawnLinked(&runClock, thisTid, duration);
         running = true;
     }

     void stop() {
         if (running)
             clock.send(Terminate._);
         running = false;
     }

     void wait() {
         receiveOnly!Ping();
     }

     private static void avoidMailboxSpam() {
         setMaxMailboxSize(thisTid, 5, OnCrowding.throwException);
     }

     private static void runClock(Tid tick, Duration duration) {
         bool cont = true;
         size_t cnt;
         try {
             while (cont) {
                 auto timedOut = !receiveTimeout(
                     duration,
                     (Terminate) { cont = false; },
                 );
                 if (timedOut) {
                     writefln("  #%-5d   Ping  ", cnt++);
                     tick.send(Ping._);
                 }
             }
         } catch (Exception ex) {
             stderr.writeln(ex.msg);
             throw ex;
         }
     }
}

void main() {
     Timer timer;
     auto interval = dur!"msecs"(500);
     timer.start(interval);

     foreach(cnt; 0 .. 200) {
         timer.wait();

         // Play some pong, if it takes too long our mailbox gets flooded
         Thread.sleep(interval / 2);
         writefln("  Pong     #%-5d", cnt);
     }
     timer.stop();
}


On Wed, 20 Jul 2011 09:34:39 +0200, maarten van damme  
<maartenvd1994 gmail.com> wrote:

 Thanks but it seems way more complex then I need, I tried writing my own  
 but
 I get an acces violation error. here is my try :
 http://dl.dropbox.com/u/15024434/Timer.d . Can someone spot the error?  
 keep
 in mind I don't really understand the threading model and pointers.


 2011/7/19 Piotr Szturmaj <bncrbme jadamspam.pl>

 maarten van damme wrote:
<snip>
 There is no callback timer in Phobos. But here's my implementation of  
 timer
 wheel I used in one of my projects: http://pastebin.com/dRRZtPVW. Feel
 free to use it if you want.
Jul 20 2011
parent Piotr Szturmaj <bncrbme jadamspam.pl> writes:
Martin Nowak wrote:
 You are aware though that in your timer, the callback is executed from
 within a different thread.
Yes. User should be aware of this different thread and should perform synchronization manually. Anyway, it is possible to relay callbacks to a queue and then one can wait for events on that queue. (This timer class was designed to handle thousands of concurrent timers.)
Jul 20 2011