00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 module dcouple.slot;
00026
00027 private import dcouple.signal;
00028 private import dcouple.signalslot;
00029
00030
00031
00032 interface SlotManager
00033 {
00034
00035
00036
00037
00038
00039
00040
00041 void register(GenericSlot);
00042 void deregister(GenericSlot);
00043 }
00044
00045
00046
00047 template SlotManagement()
00048 {
00049
00050
00051
00052
00053
00054 protected:
00055 void register(GenericSlot s)
00056 {
00057
00058 int len = _slots.length;
00059 int n = len-1;
00060 while (n >= 0 && _slots[n] is null)
00061 --n;
00062 if (n < len-1)
00063 _slots[n+1] = s;
00064 else
00065 _slots ~= s;
00066 }
00067
00068 void deregister(GenericSlot s)
00069 {
00070
00071 if (_slots.length == 0) return;
00072 bool found = false;
00073 int n;
00074 for (n=0 ; n < _slots.length-1; ++n) {
00075 if (!found && _slots[n] is s) found = true;
00076 if (found) _slots[n] = _slots[n+1];
00077 if (_slots[n] is null) break;
00078 }
00079 if (found || _slots[length-1] is s)
00080 _slots[length-1] = null;
00081 }
00082
00083
00084 GenericSlot[] _slots;
00085 void deleteSlots()
00086 {
00087 debug printf("SlotManager::deleteSlots entered.\n_slots:\n");
00088 debug foreach(GenericSlot s; _slots) printf("slot %p.\n",s);
00089 foreach(GenericSlot s; _slots) {
00090 if (s is null) break;
00091
00092 s.freeFrom(this);
00093 debug printf("SlotManager::deleteSlots: deleting %p.\n", s);
00094 delete s;
00095 pragma(msg, "_slots contains dangling references. OK?");
00096 }
00097 }
00098 }
00099
00100
00101 interface GenericSlot
00102
00103 {
00104
00105
00106
00107 void disconnect();
00108 SlotManager owner();
00109
00110 void genericConnect(GenericSignal);
00111 void genericDisconnect(GenericSignal);
00112
00113 uint numberOfArguments();
00114 char[][] arguments();
00115
00116 void freeFrom(SlotManager);
00117 }
00118
00119
00120 private template SlotGenericCore() {
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 this(SlotManager owner, Function callBack)
00132 {
00133 debug printf( "contructing slot on Function.\n");
00134 _owner = owner;
00135 _callBack = new StaticCallBack(callBack);
00136 if (owner !is null) owner.register(this);
00137 initArguments();
00138 }
00139
00140 this(SlotManager owner, Delegate callBack)
00141 {
00142 debug printf( "contructing slot on Delegate.\n");
00143 _owner = owner;
00144 debug printf( "owner set.\n");
00145 _callBack = new NonStaticCallBack(callBack);
00146 debug printf( "NonStaticCallBack newed.\n");
00147 if (owner) owner.register(this);
00148 debug printf( "Going to init arguments.\n");
00149 initArguments();
00150 debug printf( "Arguments initialised.\n");
00151 }
00152
00153
00154
00155
00156
00157
00158 ~this()
00159 {
00160 disconnect();
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 if(_owner) _owner.deregister(this);
00171 }
00172
00173
00174
00175
00176
00177
00178 void connect(CompatibleSignal s)
00179 {
00180 debug printf("slot::connect entered.\n");
00181 connectToo(s);
00182 s.connectToo(this);
00183 }
00184 package void connectToo(CompatibleSignal s)
00185 {
00186 debug printf("slot::connectToo entered.\n");
00187 debug printf("_signals before:\n");
00188 debug foreach( CompatibleSignal s; _signals ) printf( "signal %p\n", s);
00189 int len = _signals.length;
00190 int n = len-1;
00191 while (n >= 0 && _signals[n] is null)
00192 --n;
00193 if (n < len-1)
00194 _signals[n+1] = s;
00195 else
00196 _signals ~= s;
00197 debug printf("_signals after:\n");
00198 debug foreach( CompatibleSignal s; _signals ) printf( "signal %p\n", s);
00199 }
00200
00201 void genericConnect(GenericSignal gs)
00202 {
00203 debug printf("slot::genericConnect entered.\n");
00204 CompatibleSignal s = cast(CompatibleSignal) gs;
00205 if( s )
00206 connect(s);
00207 else {
00208 if (_owner) printf("dcouple WARNING: %.*s.%.*s!(",
00209 _owner.classinfo.name, this.classinfo.name);
00210 else
00211 printf("dcouple WARNING: %.*s!(", this.classinfo.name);
00212 if(numberOfArguments()>0)
00213 printf("%.*s",arguments()[0]);
00214 for(int i=1; i<numberOfArguments();i++)
00215 printf(",%.*s",arguments()[i]);
00216 if (gs.owner())
00217 printf(") is incompatible with %.*s.%.*s!(",
00218 gs.owner().classinfo.name, gs.classinfo.name);
00219 else
00220 printf(") is incompatible with %.*s!(", gs.classinfo.name);
00221 if(gs.numberOfArguments()>0)
00222 printf("%.*s",gs.arguments()[0]);
00223 for(int i=1; i<gs.numberOfArguments();i++)
00224 printf(",%.*s",gs.arguments()[i]);
00225 printf("); not connected. (Sorry, no line number...)\n");
00226 }
00227 }
00228
00229
00230
00231
00232 void disconnect(CompatibleSignal s)
00233 {
00234 debug printf("slot::disconnect entered.\n");
00235 if (disconnectToo(s))
00236 s.disconnectToo(this);
00237 }
00238 package bool disconnectToo(CompatibleSignal s)
00239 {
00240 debug printf("_signals before:\n");
00241 debug foreach( CompatibleSignal s; _signals ) printf( "signal %p\n", s);
00242
00243 debug printf("slot::disconnectToo: slot %p disconnecting from signal %p.\n", this, s);
00244 if (_signals.length == 0) return false;
00245 bool found = false;
00246 int n;
00247 for (n=0 ; n < _signals.length-1; ++n) {
00248 if (!found && _signals[n] is s) found = true;
00249 if (found) _signals[n] = _signals[n+1];
00250 if (_signals[n] is null) break;
00251 }
00252 if (found || _signals[length-1] is s)
00253 _signals[length-1] = null;
00254
00255 debug printf("_signals after:\n");
00256 debug foreach( CompatibleSignal s; _signals ) printf( "signal %p\n", s);
00257
00258
00259
00260 return found;
00261 }
00262
00263 void genericDisconnect(GenericSignal gs)
00264 {
00265 debug printf("slot::genericDisconnect entered.\n");
00266 CompatibleSignal s = cast(CompatibleSignal) gs;
00267 if( s )
00268 disconnect(s);
00269 else {
00270 if (_owner )
00271 printf("dcouple WARNING: %.*s.%.*s!(", _owner.classinfo.name, this.classinfo.name);
00272 else
00273 printf("dcouple WARNING: %.*s!(", this.classinfo.name);
00274 if(numberOfArguments()>0)
00275 printf("%.*s",arguments()[0]);
00276 for(int i=1; i<numberOfArguments();i++)
00277 printf(",%.*s",arguments()[i]);
00278 if (gs.owner())
00279 printf(") is incompatible with %.*s.%.*s!(",
00280 gs.owner().classinfo.name, gs.classinfo.name);
00281 else
00282 printf(") is incompatible with %.*s!(", gs.classinfo.name);
00283 if(gs.numberOfArguments()>0)
00284 printf("%.*s",gs.arguments()[0]);
00285 for(int i=1; i<gs.numberOfArguments();i++)
00286 printf(",%.*s",gs.arguments()[i]);
00287 printf("); not disconnected. (Sorry, no line number...)\n");
00288 }
00289 }
00290
00291
00292
00293 void disconnect()
00294 {
00295 debug printf("slot::disconnect()ing all signals.\n");
00296 debug printf("_signals before:\n");
00297 debug foreach( CompatibleSignal s; _signals ) printf( "signal %p\n", s);
00298
00299
00300
00301
00302
00303
00304
00305 for( int i=_signals.length-1; i>= 0; i-- ) {
00306 if( _signals[i] !is null ) disconnect(_signals[i]);
00307 }
00308 }
00309
00310
00311 int count() {
00312 return _signals.length;
00313 }
00314
00315 uint numberOfArguments()
00316 {
00317 return _arguments.length;
00318 }
00319
00320 char[][] arguments() {return _arguments;}
00321
00322 SlotManager owner() { return _owner; }
00323
00324 void freeFrom(SlotManager owner)
00325 {
00326
00327 assert(owner is _owner);
00328 _owner = null;
00329
00330 }
00331
00332 private:
00333
00334 SlotManager _owner;
00335 protected:
00336
00337 CallBack _callBack;
00338
00339
00340 CompatibleSignal[] _signals;
00341 char[][] _arguments;
00342 }
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354 class Slot() : GenericSlot
00355 {
00356 alias void function() Function;
00357 alias void delegate() Delegate;
00358 alias PointerToFunction!() CallBack;
00359 alias PointerToStaticFunction!() StaticCallBack;
00360 alias PointerToNonStaticFunction!() NonStaticCallBack;
00361 alias Signal!() CompatibleSignal;
00362
00363 mixin SlotGenericCore;
00364
00365
00366
00367
00368 void opCall()
00369 {
00370 _callBack();
00371 }
00372 void initArguments() {}
00373 }
00374
00375 class Slot(T1) : GenericSlot
00376 {
00377 alias void function(T1) Function;
00378 alias void delegate(T1) Delegate;
00379 alias PointerToFunction!(T1) CallBack;
00380 alias PointerToStaticFunction!(T1) StaticCallBack;
00381 alias PointerToNonStaticFunction!(T1) NonStaticCallBack;
00382 alias Signal!(T1) CompatibleSignal;
00383 mixin SlotGenericCore;
00384
00385
00386
00387
00388 void opCall(T1 t1)
00389 {
00390 _callBack(t1);
00391 }
00392
00393 void initArguments()
00394 {
00395 _arguments ~= typeid(T1).toString();
00396 }
00397 }
00398
00399 class Slot(T1,T2) : GenericSlot
00400 {
00401 alias void function(T1,T2) Function;
00402 alias void delegate(T1,T2) Delegate;
00403 alias PointerToFunction!(T1,T2) CallBack;
00404 alias PointerToStaticFunction!(T1,T2) StaticCallBack;
00405 alias PointerToNonStaticFunction!(T1,T2) NonStaticCallBack;
00406 alias Signal!(T1,T2) CompatibleSignal;
00407 mixin SlotGenericCore;
00408
00409
00410
00411
00412 void opCall(T1 t1, T2 t2)
00413 {
00414 _callBack(t1, t2);
00415 }
00416
00417 void initArguments()
00418 {
00419 _arguments ~= typeid(T1).toString();
00420 _arguments ~= typeid(T2).toString();
00421 }
00422 }
00423
00424 class Slot(T1,T2,T3) : GenericSlot
00425 {
00426 alias void function(T1,T2,T3) Function;
00427 alias void delegate(T1,T2,T3) Delegate;
00428 alias PointerToFunction!(T1,T2,T3) CallBack;
00429 alias PointerToStaticFunction!(T1,T2,T3) StaticCallBack;
00430 alias PointerToNonStaticFunction!(T1,T2,T3) NonStaticCallBack;
00431 alias Signal!(T1,T2,T3) CompatibleSignal;
00432 mixin SlotGenericCore;
00433
00434
00435
00436
00437 void opCall(T1 t1, T2 t2, T3 t3)
00438 {
00439 _callBack(t1, t2, t3);
00440 }
00441
00442 void initArguments()
00443 {
00444 _arguments ~= typeid(T1).toString();
00445 _arguments ~= typeid(T2).toString();
00446 _arguments ~= typeid(T3).toString();
00447 }
00448 }
00449
00450 class Slot(T1,T2,T3,T4) : GenericSlot
00451 {
00452 alias void function(T1,T2,T3,T4) Function;
00453 alias void delegate(T1,T2,T3,T4) Delegate;
00454 alias PointerToFunction!(T1,T2,T3,T4) CallBack;
00455 alias PointerToStaticFunction!(T1,T2,T3,T4) StaticCallBack;
00456 alias PointerToNonStaticFunction!(T1,T2,T3,T4) NonStaticCallBack;
00457 alias Signal!(T1,T2,T3,T4) CompatibleSignal;
00458 mixin SlotGenericCore;
00459
00460
00461
00462
00463 void opCall(T1 t1, T2 t2, T3 t3, T4 t4)
00464 {
00465 _callBack(t1, t2, t3, t4);
00466 }
00467
00468 void initArguments()
00469 {
00470 _arguments ~= typeid(T1).toString();
00471 _arguments ~= typeid(T2).toString();
00472 _arguments ~= typeid(T3).toString();
00473 _arguments ~= typeid(T4).toString();
00474 }
00475 }
00476
00477 class Slot(T1,T2,T3,T4,T5) : GenericSlot
00478 {
00479 alias void function(T1,T2,T3,T4,T5) Function;
00480 alias void delegate(T1,T2,T3,T4,T5) Delegate;
00481 alias PointerToFunction!(T1,T2,T3,T4,T5) CallBack;
00482 alias PointerToStaticFunction!(T1,T2,T3,T4,T5) StaticCallBack;
00483 alias PointerToNonStaticFunction!(T1,T2,T3,T4,T5) NonStaticCallBack;
00484 alias Signal!(T1,T2,T3,T4,T5) CompatibleSignal;
00485 mixin SlotGenericCore;
00486
00487
00488
00489
00490 void opCall(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
00491 {
00492 _callBack(t1, t2, t3, t4, t5);
00493 }
00494
00495 void initArguments()
00496 {
00497 _arguments ~= typeid(T1).toString();
00498 _arguments ~= typeid(T2).toString();
00499 _arguments ~= typeid(T3).toString();
00500 _arguments ~= typeid(T4).toString();
00501 _arguments ~= typeid(T5).toString();
00502 }
00503 }
00504
00505 class Slot(T1,T2,T3,T4,T5,T6) : GenericSlot
00506 {
00507 alias void function(T1,T2,T3,T4,T5,T6) Function;
00508 alias void delegate(T1,T2,T3,T4,T5,T6) Delegate;
00509 alias PointerToFunction!(T1,T2,T3,T4,T5,T6) CallBack;
00510 alias PointerToStaticFunction!(T1,T2,T3,T4,T5,T6) StaticCallBack;
00511 alias PointerToNonStaticFunction!(T1,T2,T3,T4,T5,T6) NonStaticCallBack;
00512 alias Signal!(T1,T2,T3,T4,T5,T6) CompatibleSignal;
00513 mixin SlotGenericCore;
00514
00515
00516
00517
00518 void opCall(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
00519 {
00520 _callBack(t1, t2, t3, t4, t5, t6);
00521 }
00522
00523 void initArguments()
00524 {
00525 _arguments ~= typeid(T1).toString();
00526 _arguments ~= typeid(T2).toString();
00527 _arguments ~= typeid(T3).toString();
00528 _arguments ~= typeid(T4).toString();
00529 _arguments ~= typeid(T5).toString();
00530 _arguments ~= typeid(T6).toString();
00531 }
00532 }
00533
00534 class Slot(T1,T2,T3,T4,T5,T6,T7) : GenericSlot
00535 {
00536 alias void function(T1,T2,T3,T4,T5,T6,T7) Function;
00537 alias void delegate(T1,T2,T3,T4,T5,T6,T7) Delegate;
00538 alias PointerToFunction!(T1,T2,T3,T4,T5,T6,T7) CallBack;
00539 alias PointerToStaticFunction!(T1,T2,T3,T4,T5,T6,T7) StaticCallBack;
00540 alias PointerToNonStaticFunction!(T1,T2,T3,T4,T5,T6,T7) NonStaticCallBack;
00541 alias Signal!(T1,T2,T3,T4,T5,T6,T7) CompatibleSignal;
00542 mixin SlotGenericCore;
00543
00544
00545
00546
00547 void opCall(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
00548 {
00549 _callBack(t1, t2, t3, t4, t5, t6, t7);
00550 }
00551
00552 void initArguments()
00553 {
00554 _arguments ~= typeid(T1).toString();
00555 _arguments ~= typeid(T2).toString();
00556 _arguments ~= typeid(T3).toString();
00557 _arguments ~= typeid(T4).toString();
00558 _arguments ~= typeid(T5).toString();
00559 _arguments ~= typeid(T6).toString();
00560 _arguments ~= typeid(T7).toString();
00561 }
00562 }
00563
00564 private {
00565 abstract class PointerToFunction()
00566 {
00567 void opCall();
00568 }
00569 class PointerToStaticFunction() : PointerToFunction!()
00570 {
00571 this(void function() fp) { _fp = fp; }
00572 void opCall() { _fp(); }
00573 private:
00574 void function() _fp;
00575 }
00576 class PointerToNonStaticFunction() : PointerToFunction!()
00577 {
00578 this(void delegate() dg) { _dg = dg; }
00579 void opCall() { _dg(); }
00580 private:
00581 void delegate() _dg;
00582 }
00583
00584 abstract class PointerToFunction(T1)
00585 {
00586 void opCall(T1);
00587 }
00588 class PointerToStaticFunction(T1) : PointerToFunction!(T1)
00589 {
00590 this(void function(T1) fp) { _fp = fp; }
00591 void opCall(T1 t1) { _fp(t1); }
00592 private:
00593 void function(T1) _fp;
00594 }
00595 class PointerToNonStaticFunction(T1) : PointerToFunction!(T1)
00596 {
00597 this(void delegate(T1) dg) { _dg = dg; }
00598 void opCall(T1 t1) { _dg(t1); }
00599 private:
00600 void delegate(T1) _dg;
00601 }
00602
00603 abstract class PointerToFunction(T1, T2)
00604 {
00605 void opCall(T1, T2);
00606 }
00607 class PointerToStaticFunction(T1, T2) : PointerToFunction!(T1, T2)
00608 {
00609 this(void function(T1, T2) fp) { _fp = fp; }
00610 void opCall(T1 t1, T2 t2) { _fp(t1, t2); }
00611 private:
00612 void function(T1, T2) _fp;
00613 }
00614 class PointerToNonStaticFunction(T1, T2) : PointerToFunction!(T1, T2)
00615 {
00616 this(void delegate(T1, T2) dg) { _dg = dg; }
00617 void opCall(T1 t1, T2 t2) { _dg(t1, t2); }
00618 private:
00619 void delegate(T1, T2) _dg;
00620 }
00621
00622 abstract class PointerToFunction(T1, T2, T3)
00623 {
00624 void opCall(T1, T2, T3);
00625 }
00626 class PointerToStaticFunction(T1, T2, T3) : PointerToFunction!(T1, T2, T3)
00627 {
00628 this(void function(T1, T2, T3) fp) { _fp = fp; }
00629 void opCall(T1 t1, T2 t2, T3 t3) { _fp(t1, t2, t3); }
00630 private:
00631 void function(T1, T2, T3) _fp;
00632 }
00633 class PointerToNonStaticFunction(T1, T2, T3) : PointerToFunction!(T1, T2, T3)
00634 {
00635 this(void delegate(T1, T2, T3) dg) { _dg = dg; }
00636 void opCall(T1 t1, T2 t2, T3 t3) { _dg(t1, t2, t3); }
00637 private:
00638 void delegate(T1, T2, T3) _dg;
00639 }
00640
00641 abstract class PointerToFunction(T1, T2, T3, T4)
00642 {
00643 void opCall(T1, T2, T3, T4);
00644 }
00645 class PointerToStaticFunction(T1, T2, T3, T4) : PointerToFunction!(T1, T2, T3, T4)
00646 {
00647 this(void function(T1, T2, T3, T4) fp) { _fp = fp; }
00648 void opCall(T1 t1, T2 t2, T3 t3, T4 t4) { _fp(t1, t2, t3, t4); }
00649 private:
00650 void function(T1, T2, T3, T4) _fp;
00651 }
00652 class PointerToNonStaticFunction(T1, T2, T3, T4) : PointerToFunction!(T1, T2, T3, T4)
00653 {
00654 this(void delegate(T1, T2, T3, T4) dg) { _dg = dg; }
00655 void opCall(T1 t1, T2 t2, T3 t3, T4 t4) { _dg(t1, t2, t3, t4); }
00656 private:
00657 void delegate(T1, T2, T3, T4) _dg;
00658 }
00659
00660 abstract class PointerToFunction(T1, T2, T3, T4, T5)
00661 {
00662 void opCall(T1, T2, T3, T4, T5);
00663 }
00664 class PointerToStaticFunction(T1, T2, T3, T4, T5) : PointerToFunction!(T1, T2, T3, T4, T5)
00665 {
00666 this(void function(T1, T2, T3, T4, T5) fp) { _fp = fp; }
00667 void opCall(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) { _fp(t1, t2, t3, t4, t5); }
00668 private:
00669 void function(T1, T2, T3, T4, T5) _fp;
00670 }
00671 class PointerToNonStaticFunction(T1, T2, T3, T4, T5) :
00672 PointerToFunction!(T1, T2, T3, T4, T5)
00673 {
00674 this(void delegate(T1, T2, T3, T4, T5) dg) { _dg = dg; }
00675 void opCall(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) { _dg(t1, t2, t3, t4, t5); }
00676 private:
00677 void delegate(T1, T2, T3, T4, T5) _dg;
00678 }
00679
00680 abstract class PointerToFunction(T1, T2, T3, T4, T5, T6)
00681 {
00682 void opCall(T1, T2, T3, T4, T5, T6);
00683 }
00684 class PointerToStaticFunction(T1, T2, T3, T4, T5, T6) :
00685 PointerToFunction!(T1, T2, T3, T4, T5, T6)
00686 {
00687 this(void function(T1, T2, T3, T4, T5, T6) fp) { _fp = fp; }
00688 void opCall(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
00689 { _fp(t1, t2, t3, t4, t5, t6); }
00690 private:
00691 void function(T1, T2, T3, T4, T5, T6) _fp;
00692 }
00693 class PointerToNonStaticFunction(T1, T2, T3, T4, T5, T6) :
00694 PointerToFunction!(T1, T2, T3, T4, T5, T6)
00695 {
00696 this(void delegate(T1, T2, T3, T4, T5, T6) dg) { _dg = dg; }
00697 void opCall(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
00698 { _dg(t1, t2, t3, t4, t5, t6); }
00699 private:
00700 void delegate(T1, T2, T3, T4, T5, T6) _dg;
00701 }
00702
00703 abstract class PointerToFunction(T1, T2, T3, T4, T5, T6, T7)
00704 {
00705 void opCall(T1, T2, T3, T4, T5, T6, T7);
00706 }
00707 class PointerToStaticFunction(T1, T2, T3, T4, T5, T6, T7) :
00708 PointerToFunction!(T1, T2, T3, T4, T5, T6, T7)
00709 {
00710 this(void function(T1, T2, T3, T4, T5, T6, T7) fp) { _fp = fp; }
00711 void opCall(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
00712 { _fp(t1, t2, t3, t4, t5, t6, t7); }
00713 private:
00714 void function(T1, T2, T3, T4, T5, T6, T7) _fp;
00715 }
00716 class PointerToNonStaticFunction(T1, T2, T3, T4, T5, T6, T7) :
00717 PointerToFunction!(T1, T2, T3, T4, T5, T6, T7)
00718 {
00719 this(void delegate(T1, T2, T3, T4, T5, T6, T7) dg) { _dg = dg; }
00720 void opCall(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
00721 { _dg(t1, t2, t3, t4, t5, t6, t7); }
00722 private:
00723 void delegate(T1, T2, T3, T4, T5, T6, T7) _dg;
00724 }
00725 }