Thread overview
event based timer
Jul 19, 2011
maarten van damme
Jul 19, 2011
Piotr Szturmaj
Jul 20, 2011
maarten van damme
Jul 20, 2011
Daniel Murphy
Jul 20, 2011
maarten van damme
Jul 20, 2011
Martin Nowak
Jul 20, 2011
David Nadlinger
Jul 20, 2011
Chris Molozian
Jul 20, 2011
Martin Nowak
Jul 20, 2011
Piotr Szturmaj
July 19, 2011
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


July 19, 2011
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.
July 20, 2011
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.
>


July 20, 2011
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.


July 20, 2011
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.
>
>
>


July 20, 2011
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.
>>


July 20, 2011
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.
>>
>>
>>


July 20, 2011
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
July 20, 2011
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.
>
>
>


July 20, 2011
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.)