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