www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Timer

reply Joerg Joergonson <JJoergonson gmail.com> writes:
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;
     }
}
Jun 21 2016
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
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.
Jun 21 2016
parent Joerg Joergonson <JJoergonson gmail.com> writes:
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.
Jun 21 2016