1 module utils; 2 3 import core.time; 4 import std.traits; 5 import rx; 6 import dlangui.core.signals; 7 import dlangui.widgets.widget; 8 9 ///Wrap a Signal!T as Observable 10 auto asObservable(T)(ref T signal) if (is(T == Signal!U, U) && is(U == interface)) 11 { 12 static if (is(T == Signal!U, U)) 13 { 14 alias return_t = ReturnType!(__traits(getMember, U, __traits(allMembers, U)[0])); 15 alias param_t = ParameterTypeTuple!(__traits(getMember, U, __traits(allMembers, U)[0])); 16 static assert(param_t.length == 1); 17 } 18 19 static struct LocalObservable 20 { 21 alias ElementType = param_t[0]; 22 this(ref T signal) 23 { 24 _subscribe = (Observer!ElementType o) { 25 auto dg = (ElementType w) { 26 o.put(w); 27 static if (is(return_t == bool)) 28 { 29 return true; 30 } 31 }; 32 33 signal.connect(dg); 34 35 return new AnonymouseDisposable({ signal.disconnect(dg); }); 36 }; 37 } 38 39 auto subscribe(U)(U observer) 40 { 41 return _subscribe(observerObject!ElementType(observer)); 42 } 43 44 Disposable delegate(Observer!ElementType) _subscribe; 45 } 46 47 return LocalObservable(signal); 48 } 49 50 struct TimerHandler 51 { 52 CancellationToken token; 53 void delegate() action; 54 } 55 56 class DlangUIScheduler : Widget, AsyncScheduler 57 { 58 TimerHandler[ulong] _actions; 59 Object _gate = new Object(); 60 ulong _timerId; 61 62 void start(void delegate() op) 63 { 64 auto id = setTimer(0); 65 synchronized (_gate) 66 { 67 _actions[id] = TimerHandler(null, op); 68 } 69 } 70 71 CancellationToken schedule(void delegate() op, Duration val) 72 { 73 auto ms = val.total!"msecs"; 74 auto id = setTimer(ms); 75 auto token = new CancellationToken(); 76 synchronized (_gate) 77 { 78 _actions[id] = TimerHandler(token, op); 79 } 80 return token; 81 } 82 83 override bool onTimer(ulong id) 84 { 85 CancellationToken token; 86 void delegate() action; 87 88 synchronized (_gate) 89 { 90 auto temp = id in _actions; 91 if (temp) 92 { 93 token = (*temp).token; 94 action = (*temp).action; 95 96 _actions.remove(id); 97 } 98 else 99 { 100 return false; 101 } 102 } 103 104 if (token is null || !token.isCanceled) 105 { 106 action(); 107 return true; 108 } 109 110 return false; 111 } 112 }