Timer
Joerg Joergonson via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Tue Jun 21 16:15:58 PDT 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;
}
}
More information about the Digitalmars-d-learn
mailing list