Thread overview
Timer
Jun 21, 2016
Joerg Joergonson
Jun 22, 2016
Adam D. Ruppe
Jun 22, 2016
Joerg Joergonson
June 21, 2016
Does D have a timer? I've tried some user code and it doesn't work. I need to be able to have a delegate called periodically. (fiber or thread, doesn't matter)



https://github.com/Dav1dde/BraLa/blob/master/brala/utils/thread.d




module lib.mTimer;

private
{
    import std.traits : ParameterTypeTuple, isCallable;
    import std.string : format;
    import core.time : Duration;
    import core.sync.mutex : Mutex;
    import core.sync.condition : Condition;


    import std.stdio : stderr;
}

public import core.thread;


private enum CATCH_DELEGATE = `
    delegate void() {
        try {
            fun();
        } catch(Throwable t) {
                stderr.writefln("--- Exception in Thread: \"%s\" ---".format(this.name));
                stderr.writeln(t.toString());
                stderr.writefln("--- End Exception in Thread \"%s\" ---".format(this.name));

            throw t;
        }
    }
`;

class VerboseThread : Thread
{
    this(void function() fun, size_t sz = 0)
	{
        super(mixin(CATCH_DELEGATE), sz);
    }

    this(void delegate() fun, size_t sz = 0)
	{
        super(mixin(CATCH_DELEGATE), sz);
    }
}

class TTimer(T...) : VerboseThread
{
    static assert(T.length <= 1);
    static if(T.length == 1)
	{
        static assert(isCallable!(T[0]));
        alias ParameterTypeTuple!(T[0]) Args;
    } else
	{
        alias T Args;
    }

    public Duration interval;
    protected Args args;
    protected void delegate(Args) func;

    protected Event finished;
    @property bool is_finished() { return finished.is_set; }


    this(Duration interval, void delegate(Args) func, Args args)
	{
        super(&run);

        finished = new Event();

        this.interval = interval;
        this.func = func;

        static if(Args.length) {
            this.args = args;
        }
    }

    final void cancel()
	{
        finished.set();
    }

    protected void run()
	{
        finished.wait(interval);

        if(!finished.is_set)
		{
            func(args);
        }

        finished.set();
    }

}




class Event
{
    protected Mutex mutex;
    protected Condition cond;

    protected bool flag;
    @property bool is_set() { return flag; }

    this()
	{
        mutex = new Mutex();
        cond = new Condition(mutex);

        flag = false;
    }

    void set()
	{
        mutex.lock();
        scope(exit) mutex.unlock();

        flag = true;
        cond.notifyAll();
    }

    void clear()
	{
        mutex.lock();
        scope(exit) mutex.unlock();

        flag = false;
    }

    bool wait(T...)(T timeout) if(T.length == 0 || (T.length == 1 && is(T[0] : Duration)))
	{
        mutex.lock();
        scope(exit) mutex.unlock();

        bool notified = flag;
        if(!notified)
		{
            static if(T.length == 0)
			{
                cond.wait();
                notified = true;
            } else
			{
                notified = cond.wait(timeout);
            }
        }
        return notified;
    }
}
June 22, 2016
On Tuesday, 21 June 2016 at 23:15:58 UTC, Joerg Joergonson wrote:
> Does D have a timer?

You could make one with threads or timeouts, or event loop and GUI libraries have one.

Like simpledisplay.d has a Timer class http://dpldocs.info/experimental-docs/arsd.simpledisplay.Timer.html and i'm sure the others do too.
June 22, 2016
On Wednesday, 22 June 2016 at 01:31:17 UTC, Adam D. Ruppe wrote:
> On Tuesday, 21 June 2016 at 23:15:58 UTC, Joerg Joergonson wrote:
>> Does D have a timer?
>
> You could make one with threads or timeouts, or event loop and GUI libraries have one.
>
> Like simpledisplay.d has a Timer class http://dpldocs.info/experimental-docs/arsd.simpledisplay.Timer.html and i'm sure the others do too.

I guess I'll just use that then ;)

Thanks again.