1 module des.util.arch.slot; 2 3 import des.util.arch.emm; 4 5 package interface SignalLeverage 6 { void disconnect( SlotController ); } 7 8 /// 9 class SlotController : ExternalMemoryManager 10 { 11 mixin EMM; 12 13 protected: 14 15 size_t[SignalLeverage] signals; /// 16 17 package: 18 19 /// 20 void connect( SignalLeverage sl ) 21 in { assert( sl !is null ); } 22 body { signals[sl]++; } 23 24 /// 25 void disconnect( SignalLeverage sl ) 26 in { assert( sl !is null ); } 27 body 28 { 29 if( sl in signals ) 30 { 31 if( signals[sl] > 0 ) signals[sl]--; 32 else signals.remove(sl); 33 } 34 } 35 36 protected: 37 38 void selfDestroy() 39 { 40 foreach( key, count; signals ) 41 key.disconnect(this); 42 } 43 } 44 45 /// 46 class Slot(Args...) 47 { 48 package: 49 /// 50 Func func; 51 52 /// 53 SlotController control() @property { return ctrl; } 54 55 protected: 56 57 /// 58 SlotController ctrl; 59 60 public: 61 alias void delegate(Args) Func; /// 62 63 /// 64 this( SlotController ctrl, Func func ) 65 in 66 { 67 assert( ctrl !is null ); 68 assert( func !is null ); 69 } 70 body 71 { 72 this.ctrl = ctrl; 73 this.func = func; 74 } 75 76 /// 77 this( SlotHandler handler, Func func ) 78 { this( handler.slotController, func ); } 79 80 /// 81 void opCall( Args args ) { func( args ); } 82 } 83 84 /// 85 template isSlot(T) 86 { 87 enum isSlot = is( typeof( impl(T.init) ) ); 88 void impl(Args...)( Slot!Args ) {} 89 } 90 91 unittest 92 { 93 static assert( isSlot!( Slot!string ) ); 94 static assert( isSlot!( Slot!(float,int) ) ); 95 static assert( !isSlot!( string ) ); 96 } 97 98 /// 99 interface SlotHandler 100 { 101 SlotController slotController() @property; 102 }