Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

slot.d

Go to the documentation of this file.
00001 /*
00002 
00003     Copyright 2004 Bastiaan Veelo
00004 
00005     This file is part of dcouple.
00006 
00007     Dcouple is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 2 of the License, or
00010     (at your option) any later version.
00011 
00012     You are free to negociate a different license with the copyright holder.
00013 
00014     Dcouple is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017     GNU General Public License for more details.
00018 
00019     You should have received a copy of the GNU General Public License
00020     along with dcouple; if not, write to the Free Software
00021     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 
00023 */
00024 
00025 module dcouple.slot;
00026 
00027 private import dcouple.signal;
00028 private import dcouple.signalslot;
00029 
00030 //! An interface for the management of slots.
00031 /*! Provides an interface that must be implemented by classes that own \link Slot Slots \endlink in a managed way. */
00032 interface SlotManager
00033 {
00034   /*! Deriving classes must mixin SlotManagement, or implement these functions to keep a list of \link 
00035   Slot Slots \endlink that it owns, and disconnect() them in the destructor 
00036   (so that connected \link Signal Signals \endlink remove their reference). 
00037   Also, deriving classes must provide and use a method (say, .discard()) to 
00038   disconnect all slots when the object is no longer used, so that it may be 
00039   garbage collected.
00040   */
00041   void register(GenericSlot);
00042   void deregister(GenericSlot);
00043 }
00044 
00045 
00046 /*! SlotManager implementation */
00047 template SlotManagement()
00048 {
00049 /*      ~this()
00050         {
00051                 deleteSlots();
00052         }
00053 */      
00054   protected:
00055     void register(GenericSlot s)
00056     {
00057       //_slots[s] = s;
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       //_slots.remove(s);
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     //GenericSlot[GenericSlot] _slots;
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         // prevent s from manipulating _slots:
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 //! An interface shared by all Slots
00101 interface GenericSlot
00102 //abstract class GenericSlot
00103 {
00104   //! Disconnect all. 
00105   /*! Breaks all connections from this Slot. */
00106   //    void disconnect();
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 /*! The generic part of \link Slot Slots. \endlink */
00120 private template SlotGenericCore() {
00121   //! Constructor.
00122   /*! The Slot \link SlotManager::register(Slot) registers \endlink 
00123   itself with its \a owner. \a callBack must be a member function of \a 
00124   owner, and is the method that is called when a signal is received.
00125   */
00126 
00127   //    this(SlotManager owner, CallBack callBack)
00128 
00129   //    Waiting for fix to http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/1890
00130   //    this(Function callBack) { this(null, callBack); }
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   //    this(Delegate callBack) { this(null, callBack); }
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   //! Destructor.
00154   /*! Disconnects all connected \link Signal Signals \endlink, and \link 
00155   SlotManager::deregister(Slot) de-registers \endlink itself with its 
00156   owner. 
00157   */
00158   ~this()
00159   {
00160     disconnect();
00161     /* Strictly spoken, destructors are not allowed to reference 
00162     other objects, because the order in which the GC calls 
00163     destructors is not defined, so those objects may not exist 
00164     anymore. The disconnect() function above breaks this rule 
00165     indirectly. But this particular case is OK, because we only 
00166     consider references to CompatibleSignals that *are still alive*. 
00167     Signals that are already destructed have removed our reference to 
00168     them, just like we have removed references to us in other signals 
00169     in disconnect(). */
00170     if(_owner) _owner.deregister(this);
00171   }
00172 
00173   /*! Establishes a connection between this Slot and Signal \a s, and vice 
00174   versa (i.e., registers this Slot within Signal \a s). Multiple identical 
00175   connections may exist, which causes the slot to receive the same signal as 
00176   many times per emission as connections have been made.
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   /*! Breaks the connection between this Slot and Signal \a s (if it 
00230   exists), and vice versa (i.e., de-registers this Slot from Signal \a s).
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   //! Disconnect all. 
00292   /*! Breaks all connections from this Slot. */
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     //foreach does not work because disconnect(s) manipulates _signals. Is this a dmd bug or feature?
00299     /*
00300     foreach(CompatibleSignal s; _signals) {
00301       if (s is null) break;
00302       disconnect(s);
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   /*! \returns the number of connected \link Signal Signals. \endlink */
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     // Only the real owner can set us free.
00327     assert(owner is _owner);
00328     _owner = null;
00329     // Do not deregister, the owner is in charge.
00330   }
00331 
00332 private:
00333   //! This Slot is managed by _owner.
00334   SlotManager _owner;
00335 protected:
00336   //! "delegate", or pointer-to-member-function.
00337   CallBack _callBack;
00338   //! Collection of connected \link Signal Signals. \endlink
00339   //CompatibleSignal[CompatibleSignal] _signals;
00340   CompatibleSignal[] _signals;
00341   char[][] _arguments;
00342 }
00343 
00344 
00345 
00346 //! A slot to which signals can be connected.
00347 /*! A Slot should be owned by a \link SlotManager managing \endlink class,
00348 and can be \link connect() connected \endlink to one or more \link Signal Signals, \endlink possibly in other classes. This Slot is then notified when a connected Signal is \link Signal::emit() emitted, \endlink and the corresponding call-back function ("delegate") called.
00349 
00350 \todo Free slots have a problem. When they receive a signal during a garbage collection run, e.g., from an object that is configured to emit a "destroyed" signal, at a time when they themselves have become garbage (or more importantly, their call back function) they can cause a segmentation fault when calling the collected function. This situation is likely to occur at program termination (when "almost" verything is collected).
00351 This is supposedly not a problem for owned slots that refer to member functions of the owner, because the destructor of the owner is called before its members are invalidated (right?).
00352 Solution: have all free slots register with a global static SlotManager. Before letting the program terminate, this owner must be instructed to disconnect all slots.
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                       // Signal!() is a Signal!(), so it is compatible too.
00363   mixin SlotGenericCore;
00364 
00365   /*! Calls the registered callBack member function. Allows the 
00366   Slot to be called like a function.
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   /*! Calls the registered callBack member function. Allows the 
00386   Slot to be called like a function.
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         /*! Calls the registered callBack member function. Allows the 
00410         Slot to be called like a function.
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         /*! Calls the registered callBack member function. Allows the 
00435         Slot to be called like a function.
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         /*! Calls the registered callBack member function. Allows the 
00461         Slot to be called like a function.
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         /*! Calls the registered callBack member function. Allows the 
00488         Slot to be called like a function.
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         /*! Calls the registered callBack member function. Allows the 
00516         Slot to be called like a function.
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         /*! Calls the registered callBack member function. Allows the 
00545         Slot to be called like a function.
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 }       // private

Generated on Mon Sep 12 22:10:39 2005 for dcouple by  doxygen 1.4.3