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;
    }
}
  • Timer Joerg Joergonson via Digitalmars-d-learn
    • Re: Timer Adam D. Ruppe via Digitalmars-d-learn
      • Re: Timer Joerg Joergonson via Digitalmars-d-learn

Reply via email to