Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

scim_signals.h

Go to the documentation of this file.
00001 /**
00002  * @file scim_signals.h
00003  * @brief C++ signal interface.
00004  * 
00005  * Provides a set of signal class templates you can use to create signals
00006  * that can pass up to 6 arguments to signal handlers connected via the
00007  * slot interface (see scim_slot.h). The signal classes are named Signal0
00008  * to Signal6, where 0 to 6 specifies the number of arguments that can be
00009  * passed to a slot.
00010  *
00011  * Most code of this file are came from Inti project.
00012  */
00013 
00014 /*
00015  * Smart Common Input Method
00016  * 
00017  * Copyright (c) 2004 James Su <suzhe@turbolinux.com.cn>
00018  * Copyright (c) 2003 James Su <suzhe@turbolinux.com.cn>
00019  * Copyright (c) 2002 James Su <suzhe@turbolinux.com.cn>
00020  * Copyright (c) 2002 The Inti Development Team.
00021  * Copyright (c) 2000 Red Hat, Inc.
00022  * Copyright 1999, Karl Einar Nelson
00023  *
00024  *
00025  * This library is free software; you can redistribute it and/or
00026  * modify it under the terms of the GNU Lesser General Public
00027  * License as published by the Free Software Foundation; either
00028  * version 2 of the License, or (at your option) any later version.
00029  *
00030  * This library is distributed in the hope that it will be useful,
00031  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00032  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00033  * GNU Lesser General Public License for more details.
00034  *
00035  * You should have received a copy of the GNU Lesser General Public
00036  * License along with this program; if not, write to the
00037  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
00038  * Boston, MA  02111-1307  USA
00039  *
00040  * $Id: scim_signals.h,v 1.9 2004/05/21 15:18:29 suzhe Exp $
00041  */
00042 
00043 #ifndef __SCIM_SIGNALS_H
00044 #define __SCIM_SIGNALS_H
00045 
00046 namespace scim {
00047    
00048 /**
00049  * @addtogroup SignalSlot
00050  * @{
00051  */
00052 
00053 class Signal;
00054 
00055 //! @class SlotNode 
00056 //! @brief A node class for managing slots connected to scim::Signal's.
00057 
00058 class SlotNode : public Node
00059 {
00060     friend class Signal;
00061 
00062     SlotNode(Slot *slot);
00063     ~SlotNode();
00064 
00065     bool is_blocked;
00066 
00067 public:
00068     bool blocked() const { return is_blocked; }
00069     //!< Returns true if the slot is blocked.
00070     
00071     virtual void block();
00072     //!< Block signal emission to the slot until unblock is called.
00073 
00074     virtual void unblock();
00075     //!< Unblock the slot so signal emmissions can be received.
00076 
00077     virtual void disconnect();
00078     //!< Disconnect the slot. The slot will no longer recieve signal emissions.
00079 };
00080 
00081 // DefaultMarshal class (from marshal.h, libsigc++)
00082 
00083 template <typename R>
00084 class DefaultMarshal
00085 {
00086 public:
00087     typedef R OutType;
00088     typedef R InType;
00089 
00090 private:
00091     OutType value_;
00092 
00093 public:
00094     DefaultMarshal() :value_() {}
00095     
00096     OutType& value() { return value_; }
00097     
00098     // Return true to stop emission.
00099     bool marshal(const InType & newval)
00100     {
00101         value_ = newval;
00102         return false;
00103     }
00104 };
00105 
00106 //! @class Signal 
00107 //! @brief Base class for the C++ signal interface.
00108 
00109 class Signal
00110 {
00111     Signal(const Signal&);
00112     Signal& operator=(const Signal&);
00113 
00114 protected:
00115     typedef std::vector< Pointer<SlotNode> > ConnectionList;
00116     //!< ConnectionList type.
00117 
00118     ConnectionList connection_list;
00119     //!< A list of all the slots connected to the signal.
00120 
00121 public:
00122     Signal();
00123     //!< Constructor.
00124 
00125     virtual ~Signal();
00126     //!< Destructor.
00127 
00128     SlotNode* connect(Slot *slot);
00129     //!< Creates a new SlotNode for slot and adds it to the <EM>connection_list</EM>.
00130 };
00131 
00132 //! @class Signal0 
00133 //! @brief A template for a signal passing no arguments and returning a value of type R.
00134 
00135 template<typename R, typename Marshal = class DefaultMarshal<R> >
00136 class Signal0 : public Signal
00137 {
00138     typedef Signal0<R> Self;
00139 
00140     static R callback(void *data)
00141     {
00142         Self *s = static_cast<Self*>(data);
00143         return s->emit();
00144     }
00145 
00146 public:
00147     typedef Slot0<R> SlotType;
00148     //!< Function signature for handlers connecting the signal.
00149 
00150     Connection connect(SlotType *slot)
00151     { 
00152         return Signal::connect(slot);
00153     }
00154     //!< Connect a slot to the signal.
00155     //!< @param slot - a slot of type Slot0<R>.
00156     //!< @return a connection object.
00157     //!<
00158     //!< <BR>The returned connection object can be used alter or change the connection.
00159 
00160     SlotType* slot()
00161     {
00162         return new SignalSlot0<Self, R>(this, &callback);
00163     }
00164     //!< Returns a slot for this signal.
00165     //!< @return a new slot of type Slot0<R>.
00166     //!<
00167     //!< <BR>The returned slot can be passed to another signal allowing the
00168     //!< other signal to call this signal when it gets emitted.
00169 
00170     R emit()
00171     {
00172         Marshal m;
00173         ConnectionList::iterator i = connection_list.begin();
00174         while (i != connection_list.end())
00175         {
00176             if (!(*i)->blocked())
00177             {
00178                 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot());
00179                 if (slot && m.marshal(slot->call()))
00180                     break;
00181             }
00182             ++i;
00183         }
00184         return m.value();    
00185     }
00186     //!< Emit the signal.
00187     //!< @return the value returned by the signal handler.
00188     //!<
00189     //!< <BR>Calls every slot connected to this signal, in order of connection.
00190 
00191     R operator()() 
00192     {
00193         return emit(); 
00194     }
00195     //!< Function operator; calls emit().
00196 };
00197 
00198 // Signal0 partially specialized for void return
00199 
00200 template<typename IgnoreMarshal>
00201 class Signal0<void, IgnoreMarshal> : public Signal
00202 {
00203     typedef Signal0<void, IgnoreMarshal> Self;
00204 
00205     static void callback(void *data)
00206     {
00207         Self *s = static_cast<Self*>(data);
00208         s->emit();
00209     }
00210 
00211 public:
00212     typedef Slot0<void> SlotType;
00213 
00214     Connection connect(SlotType *slot)
00215     { 
00216         return Signal::connect(slot);
00217     }
00218 
00219     SlotType* slot()
00220     {
00221         return new SignalSlot0<Self, void>(this, &callback);
00222     }
00223 
00224     void emit()
00225     {
00226         ConnectionList::iterator i = connection_list.begin();
00227         while (i != connection_list.end())
00228         {
00229             if (!(*i)->blocked())
00230             {
00231                 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot());
00232                 if (slot) slot->call();
00233             }
00234             ++i;
00235         }
00236     }
00237         
00238     void operator()()
00239     {
00240         emit(); 
00241     }
00242 };
00243 
00244 //! @class Signal1 
00245 //! @brief A template for a signal passing one argument of type P1 and returning a value of type R.
00246 
00247 template<typename R, typename P1, typename Marshal = class DefaultMarshal<R> >
00248 class Signal1 : public Signal
00249 {
00250     typedef Signal1<R, P1> Self;
00251 
00252     static R callback(void *data, P1 p1)
00253     {
00254         Self *s = static_cast<Self*>(data);
00255         return s->emit(p1);
00256     }
00257 
00258 public:
00259     typedef Slot1<R, P1> SlotType;
00260     //!< Function signature for handlers connecting to the signal.
00261 
00262     Connection connect(SlotType *slot)
00263     { 
00264         return Signal::connect(slot);
00265     }
00266     //!< Connect a slot to the signal.
00267     //!< @param slot - a slot of type Slot1<R, P1>.
00268     //!< @return a connection object.
00269     //!<
00270     //!< <BR>The returned connection object can be used alter or change the connection.
00271 
00272     SlotType* slot()
00273     {
00274         return new SignalSlot1<Self, R, P1>(this, &callback);
00275     }
00276     //!< Returns a slot for this signal.
00277     //!< @return a new slot of type Slot1<R, P1>.
00278     //!<
00279     //!< <BR>The returned slot can be passed to another signal allowing the
00280     //!< other signal to call this signal when it gets emitted.
00281 
00282     R emit(P1 p1)
00283     {
00284         Marshal m;
00285         ConnectionList::iterator i = connection_list.begin();
00286         while (i != connection_list.end())
00287         {
00288             if (!(*i)->blocked())
00289             {
00290                 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot());
00291                 if (slot && m.marshal(slot->call(p1)))
00292                     break;
00293             }
00294             ++i;        
00295         }
00296         return m.value();    
00297     }
00298     //!< Emit the signal.
00299     //!< @param p1 - passes p1 to the signal handler.
00300     //!< @return the value returned by the signal handler.
00301     //!<
00302     //!< <BR>Calls every slot connected to this signal, in order of connection.
00303 
00304     R operator()(P1 p1) 
00305     {
00306         return emit(p1); 
00307     }
00308     //!< Function operator; calls emit().
00309 };
00310 
00311 // Signal1 partially specialized for void return
00312 
00313 template<typename P1, typename IgnoreMarshal>
00314 class Signal1<void, P1, IgnoreMarshal> : public Signal
00315 {
00316     typedef Signal1<void, P1, IgnoreMarshal> Self;
00317 
00318     static void callback(void *data, P1 p1)
00319     {
00320         Self *s = static_cast<Self*>(data);
00321         s->emit(p1);
00322     }
00323 
00324 public:
00325     typedef Slot1<void, P1> SlotType;
00326 
00327     Connection connect(SlotType *slot)
00328     { 
00329         return Signal::connect(slot);
00330     }
00331 
00332     SlotType* slot()
00333     {
00334         return new SignalSlot1<Self, void, P1>(this, &callback);
00335     }
00336 
00337     void emit(P1 p1)
00338     {
00339         ConnectionList::iterator i = connection_list.begin();
00340         while (i != connection_list.end())
00341         {
00342             if (!(*i)->blocked())
00343             {
00344                 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot());
00345                 if (slot) slot->call(p1);
00346             }
00347             ++i;
00348         }
00349     }
00350         
00351     void operator()(P1 p1)
00352     {
00353         emit(p1); 
00354     }
00355 };
00356 
00357 //! @class Signal2 
00358 //! @brief A template for a signal passing two arguments of type P1 and P2,
00359 //! and returning a value of type R.
00360 
00361 template<typename R, typename P1, typename P2, typename Marshal = class DefaultMarshal<R> >
00362 class Signal2 : public Signal
00363 {
00364     typedef Signal2<R, P1, P2> Self;
00365 
00366     static R callback(void *data, P1 p1, P2 p2)
00367     {
00368         Self *s = static_cast<Self*>(data);
00369         return s->emit(p1, p2);
00370     }
00371 
00372 public:
00373     typedef Slot2<R, P1, P2> SlotType;
00374     //!< Function signature for handlers connecting to the signal.
00375 
00376     Connection connect(SlotType *slot)
00377     { 
00378         return Signal::connect(slot);
00379     }
00380     //!< Connect a slot to the signal.
00381     //!< @param slot - a slot of type Slot2<R, P1, P2>.
00382     //!< @return a connection object.
00383     //!<
00384     //!< <BR>The returned connection object can be used alter or change the connection.
00385 
00386     SlotType* slot()
00387     {
00388         return new SignalSlot2<Self, R, P1, P2>(this, &callback);
00389     }
00390     //!< Returns a slot for this signal.
00391     //!< @return a new slot of type Slot2<R, P1, P2>.
00392     //!<
00393     //!< <BR>The returned slot can be passed to another signal allowing the
00394     //!< other signal to call this signal when it gets emitted.
00395 
00396     R emit(P1 p1, P2 p2)
00397     {
00398         Marshal m;
00399         ConnectionList::iterator i = connection_list.begin();
00400         while (i != connection_list.end())
00401         {
00402             if (!(*i)->blocked())
00403             {
00404                 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot());
00405                 if (slot && m.marshal(slot->call(p1, p2)))
00406                     break;
00407             }
00408             ++i;        
00409         }
00410         return m.value();    
00411     }
00412     //!< Emit the signal.
00413     //!< @param p1 - passes p1 to the signal handler.
00414     //!< @param p2 - passes p2 to the signal handler.
00415     //!< @return the value returned by the signal handler.
00416     //!<
00417     //!< <BR>Calls every slot connected to this signal, in order of connection.
00418 
00419     R operator()(P1 p1, P2 p2) 
00420     {
00421         return emit(p1, p2); 
00422     }
00423     //!< Function operator; calls emit().
00424 };
00425 
00426 // Signal2 partially specialized for void return
00427 
00428 template<typename P1, typename P2, typename IgnoreMarshal>
00429 class Signal2<void, P1, P2, IgnoreMarshal> : public Signal
00430 {
00431     typedef Signal2<void, P1, P2, IgnoreMarshal> Self;
00432 
00433     static void callback(void *data, P1 p1, P2 p2)
00434     {
00435         Self *s = static_cast<Self*>(data);
00436         s->emit(p1, p2);
00437     }
00438 
00439 public:
00440     typedef Slot2<void, P1, P2> SlotType;
00441 
00442     Connection connect(SlotType *slot)
00443     { 
00444         return Signal::connect(slot);
00445     }
00446 
00447     SlotType* slot()
00448     {
00449         return new SignalSlot2<Self, void, P1, P2>(this, &callback);
00450     }
00451 
00452     void emit(P1 p1, P2 p2)
00453     {
00454         ConnectionList::iterator i = connection_list.begin();
00455         while (i != connection_list.end())
00456         {
00457             if (!(*i)->blocked())
00458             {
00459                 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot());
00460                 if (slot) slot->call(p1, p2);
00461             }
00462             ++i;
00463         }
00464     }
00465         
00466     void operator()(P1 p1, P2 p2)
00467     {
00468         emit(p1, p2); 
00469     }
00470 };
00471 
00472 //! @class Signal3 
00473 //! @brief A template for a signal passing three arguments of type P1, P2 and P3,
00474 //! and returning a value of type R.
00475 
00476 template<typename R, typename P1, typename P2, typename P3, typename Marshal = class DefaultMarshal<R> >
00477 class Signal3 : public Signal
00478 {
00479     typedef Signal3<R, P1, P2, P3> Self;
00480 
00481     static R callback(void *data, P1 p1, P2 p2, P3 p3)
00482     {
00483         Self *s = static_cast<Self*>(data);
00484         return s->emit(p1, p2, p3);
00485     }
00486 
00487 public:
00488     typedef Slot3<R, P1, P2, P3> SlotType;
00489     //!< Function signature for handlers connecting to the signal.
00490 
00491     Connection connect(SlotType *slot)
00492     { 
00493         return Signal::connect(slot);
00494     }
00495     //!< Connect a slot to the signal.
00496     //!< @param slot - a slot of type Slot3<R, P1, P2, P3>.
00497     //!< @return a connection object.
00498     //!<
00499     //!< <BR>The returned connection object can be used alter or change the connection.
00500 
00501     SlotType* slot()
00502     {
00503         return new SignalSlot3<Self, R, P1, P2, P3>(this, &callback);
00504     }
00505     //!< Returns a slot for this signal.
00506     //!< @return a new slot of type Slot3<R, P1, P2, P3>.
00507     //!<
00508     //!< <BR>The returned slot can be passed to another signal allowing the
00509     //!< other signal to call this signal when it gets emitted.
00510 
00511     R emit(P1 p1, P2 p2, P3 p3)
00512     {
00513         Marshal m;
00514         ConnectionList::iterator i = connection_list.begin();
00515         while (i != connection_list.end())
00516         {
00517             if (!(*i)->blocked())
00518             {
00519                 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot());
00520                 if (slot && m.marshal(slot->call(p1, p2, p3)))
00521                     break;
00522             }
00523             ++i;        
00524         }
00525         return m.value();    
00526     }
00527     //!< Emit the signal.
00528     //!< @param p1 - passes p1 to the signal handler.
00529     //!< @param p2 - passes p2 to the signal handler.
00530     //!< @param p3 - passes p3 to the signal handler.
00531     //!< @return the value returned by the signal handler.
00532     //!<
00533     //!< <BR>Calls every slot connected to this signal, in order of connection.
00534 
00535     R operator()(P1 p1, P2 p2, P3 p3) 
00536     {
00537         return emit(p1, p2, p3); 
00538     }
00539     //!< Function operator; calls emit().
00540 };
00541 
00542 // Signal3 partially specialized for void return
00543 
00544 template<typename P1, typename P2, typename P3, typename IgnoreMarshal>
00545 class Signal3<void, P1, P2, P3, IgnoreMarshal> : public Signal
00546 {
00547     typedef Signal3<void, P1, P2, P3, IgnoreMarshal> Self;
00548 
00549     static void callback(void *data, P1 p1, P2 p2, P3 p3)
00550     {
00551         Self *s = static_cast<Self*>(data);
00552         s->emit(p1, p2, p3);
00553     }
00554 
00555 public:
00556     typedef Slot3<void, P1, P2, P3> SlotType;
00557 
00558     Connection connect(SlotType *slot)
00559     { 
00560         return Signal::connect(slot);
00561     }
00562 
00563     SlotType* slot()
00564     {
00565         return new SignalSlot3<Self, void, P1, P2, P3>(this, &callback);
00566     }
00567 
00568     void emit(P1 p1, P2 p2, P3 p3)
00569     {
00570         ConnectionList::iterator i = connection_list.begin();
00571         while (i != connection_list.end())
00572         {
00573             if (!(*i)->blocked())
00574             {
00575                 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot());
00576                 if (slot) slot->call(p1, p2, p3);
00577             }
00578             ++i;
00579         }
00580     }
00581         
00582     void operator()(P1 p1, P2 p2, P3 p3)
00583     {
00584         emit(p1, p2, p3); 
00585     }
00586 };
00587 
00588 //! @class Signal4 
00589 //! @brief A template for a signal passing four arguments of type P1, P2, P3 and P4,
00590 //! and returning a value of type R.
00591 
00592 template<typename R, typename P1, typename P2, typename P3, typename P4, typename Marshal = class DefaultMarshal<R> >
00593 class Signal4 : public Signal
00594 {
00595     typedef Signal4<R, P1, P2, P3, P4> Self;
00596 
00597     static R callback(void *data, P1 p1, P2 p2, P3 p3, P4 p4)
00598     {
00599         Self *s = static_cast<Self*>(data);
00600         return s->emit(p1, p2, p3, p4);
00601     }
00602 
00603 public:
00604     typedef Slot4<R, P1, P2, P3, P4> SlotType;
00605     //!< Function signature for handlers connecting to the signal.
00606 
00607     Connection connect(SlotType *slot)
00608     { 
00609         return Signal::connect(slot);
00610     }
00611     //!< Connect a slot to the signal.
00612     //!< @param slot - a slot of type Slot4<R, P1, P2, P3, P4>.
00613     //!< @return a connection object.
00614     //!<
00615     //!< <BR>The returned connection object can be used alter or change the connection.
00616 
00617     SlotType* slot()
00618     {
00619         return new SignalSlot4<Self, R, P1, P2, P3, P4>(this, &callback);
00620     }
00621     //!< Returns a slot for this signal.
00622     //!< @return a new slot of type Slot4<R, P1, P2, P3, P4>.
00623     //!<
00624     //!< <BR>The returned slot can be passed to another signal allowing the
00625     //!< other signal to call this signal when it gets emitted.
00626 
00627     R emit(P1 p1, P2 p2, P3 p3, P4 p4)
00628     {
00629         Marshal m;
00630         ConnectionList::iterator i = connection_list.begin();
00631         while (i != connection_list.end())
00632         {
00633             if (!(*i)->blocked())
00634             {
00635                 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot());
00636                 if (slot && m.marshal(slot->call(p1, p2, p3, p4)))
00637                     break;
00638             }
00639             ++i;        
00640         }
00641         return m.value();    
00642     }
00643     //!< Emit the signal.
00644     //!< @param p1 - passes p1 to the signal handler.
00645     //!< @param p2 - passes p2 to the signal handler.
00646     //!< @param p3 - passes p3 to the signal handler.
00647     //!< @param p4 - passes p4 to the signal handler.
00648     //!< @return the value returned by the signal handler.
00649     //!<
00650     //!< <BR>Calls every slot connected to this signal, in order of connection.
00651 
00652     R operator()(P1 p1, P2 p2, P3 p3, P4 p4) 
00653     {
00654         return emit(p1, p2, p3, p4); 
00655     }
00656     //!< Function operator; calls emit().
00657 };
00658 
00659 // Signal4 partially specialized for void return
00660 
00661 template<typename P1, typename P2, typename P3, typename P4, typename IgnoreMarshal>
00662 class Signal4<void, P1, P2, P3, P4, IgnoreMarshal> : public Signal
00663 {
00664     typedef Signal4<void, P1, P2, P3, P4, IgnoreMarshal> Self;
00665 
00666     static void callback(void *data, P1 p1, P2 p2, P3 p3, P4 p4)
00667     {
00668         Self *s = static_cast<Self*>(data);
00669         s->emit(p1, p2, p3, p4);
00670     }
00671 
00672 public:
00673     typedef Slot4<void, P1, P2, P3, P4> SlotType;
00674 
00675     Connection connect(SlotType *slot)
00676     { 
00677         return Signal::connect(slot);
00678     }
00679 
00680     SlotType* slot()
00681     {
00682         return new SignalSlot4<Self, void, P1, P2, P3, P4>(this, &callback);
00683     }
00684 
00685     void emit(P1 p1, P2 p2, P3 p3, P4 p4)
00686     {
00687         ConnectionList::iterator i = connection_list.begin();
00688         while (i != connection_list.end())
00689         {
00690             if (!(*i)->blocked())
00691             {
00692                 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot());
00693                 if (slot) slot->call(p1, p2, p3, p4);
00694             }
00695             ++i;
00696         }
00697     }
00698         
00699     void operator()(P1 p1, P2 p2, P3 p3, P4 p4)
00700     {
00701         emit(p1, p2, p3, p4); 
00702     }
00703 };
00704 
00705 //! @class Signal5 
00706 //! @brief A template for a signal passing five arguments of type P1, P2, P3, P4 and P5,
00707 //! and returning a value of type R.
00708 
00709 template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename Marshal = class DefaultMarshal<R> >
00710 class Signal5 : public Signal
00711 {
00712     typedef Signal5<R, P1, P2, P3, P4, P5> Self;
00713 
00714     static R callback(void *data, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
00715     {
00716         Self *s = static_cast<Self*>(data);
00717         return s->emit(p1, p2, p3, p4, p5);
00718     }
00719 
00720 public:
00721     typedef Slot5<R, P1, P2, P3, P4, P5> SlotType;
00722     //!< Function signature for handlers connecting to the signal.
00723 
00724     Connection connect(SlotType *slot)
00725     { 
00726         return Signal::connect(slot);
00727     }
00728     //!< Connect a slot to the signal.
00729     //!< @param slot - a slot of type Slot5<R, P1, P2, P3, P4, P5>.
00730     //!< @return a connection object.
00731     //!<
00732     //!< <BR>The returned connection object can be used alter or change the connection.
00733 
00734     SlotType* slot()
00735     {
00736         return new SignalSlot5<Self, R, P1, P2, P3, P4, P5>(this, &callback);
00737     }
00738     //!< Returns a slot for this signal.
00739     //!< @return a new slot of type Slot5<R, P1, P2, P3, P4, P5>.
00740     //!<
00741     //!< <BR>The returned slot can be passed to another signal allowing the
00742     //!< other signal to call this signal when it gets emitted.
00743 
00744     R emit(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
00745     {
00746         Marshal m;
00747         ConnectionList::iterator i = connection_list.begin();
00748         while (i != connection_list.end())
00749         {
00750             if (!(*i)->blocked())
00751             {
00752                 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot());
00753                 if (slot && m.marshal(slot->call(p1, p2, p3, p4, p5)))
00754                     break;
00755             }
00756             ++i;        
00757         }
00758         return m.value();    
00759     }
00760     //!< Emit the signal.
00761     //!< @param p1 - passes p1 to the signal handler.
00762     //!< @param p2 - passes p2 to the signal handler.
00763     //!< @param p3 - passes p3 to the signal handler.
00764     //!< @param p4 - passes p4 to the signal handler.
00765     //!< @param p5 - passes p5 to the signal handler.
00766     //!< @return the value returned by the signal handler.
00767     //!<
00768     //!< <BR>Calls every slot connected to this signal, in order of connection.
00769 
00770     R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) 
00771     {
00772         return emit(p1, p2, p3, p4, p5); 
00773     }
00774     //!< Function operator; calls emit().
00775 };
00776 
00777 // Signal5 partially specialized for void return
00778 
00779 template<typename P1, typename P2, typename P3, typename P4, typename P5, typename IgnoreMarshal>
00780 class Signal5<void, P1, P2, P3, P4, P5, IgnoreMarshal> : public Signal
00781 {
00782     typedef Signal5<void, P1, P2, P3, P4, P5, IgnoreMarshal> Self;
00783 
00784     static void callback(void *data, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
00785     {
00786         Self *s = static_cast<Self*>(data);
00787         s->emit(p1, p2, p3, p4, p5);
00788     }
00789 
00790 public:
00791     typedef Slot5<void, P1, P2, P3, P4, P5> SlotType;
00792 
00793     Connection connect(SlotType *slot)
00794     { 
00795         return Signal::connect(slot);
00796     }
00797 
00798     SlotType* slot()
00799     {
00800         return new SignalSlot5<Self, void, P1, P2, P3, P4, P5>(this, &callback);
00801     }
00802 
00803     void emit(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
00804     {
00805         ConnectionList::iterator i = connection_list.begin();
00806         while (i != connection_list.end())
00807         {
00808             if (!(*i)->blocked())
00809             {
00810                 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot());
00811                 if (slot) slot->call(p1, p2, p3, p4, p5);
00812             }
00813             ++i;
00814         }
00815     }
00816         
00817     void operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5)
00818     {
00819         emit(p1, p2, p3, p4, p5); 
00820     }
00821 };
00822 
00823 //! @class Signal6 
00824 //! @brief A template for a signal passing six arguments of type P1, P2, P3, P4, P5 and P6,
00825 //! and returning a value of type R.
00826 
00827 template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename Marshal = class DefaultMarshal<R> >
00828 class Signal6 : public Signal
00829 {
00830     typedef Signal6<R, P1, P2, P3, P4, P5, P6> Self;
00831 
00832     static R callback(void *data, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)
00833     {
00834         Self *s = static_cast<Self*>(data);
00835         return s->emit(p1, p2, p3, p4, p5, p6);
00836     }
00837 
00838 public:
00839     typedef Slot6<R, P1, P2, P3, P4, P5, P6> SlotType;
00840     //!< Function signature for handlers connecting to the signal.
00841 
00842     Connection connect(SlotType *slot)
00843     { 
00844         return Signal::connect(slot);
00845     }
00846     //!< Connect a slot to the signal.
00847     //!< @param slot - a slot of type Slot6<R, P1, P2, P3, P4, P5, P6>.
00848     //!< @return a connection object.
00849     //!<
00850     //!< <BR>The returned connection object can be used alter or change the connection.
00851 
00852     SlotType* slot()
00853     {
00854         return new SignalSlot6<Self, R, P1, P2, P3, P4, P5, P6>(this, &callback);
00855     }
00856     //!< Returns a slot for this signal.
00857     //!< @return a new slot of type Slot6<R, P1, P2, P3, P4, P5, P6>.
00858     //!<
00859     //!< <BR>The returned slot can be passed to another signal allowing the
00860     //!< other signal to call this signal when it gets emitted.
00861 
00862     R emit(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)
00863     {
00864         Marshal m;
00865         ConnectionList::iterator i = connection_list.begin();
00866         while (i != connection_list.end())
00867         {
00868             if (!(*i)->blocked())
00869             {
00870                 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot());
00871                 if (slot && m.marshal(slot->call(p1, p2, p3, p4, p5, p6)))
00872                     break;
00873             }
00874             ++i;        
00875         }
00876         return m.value();    
00877     }
00878     //!< Emit the signal.
00879     //!< @param p1 - passes p1 to the signal handler.
00880     //!< @param p2 - passes p2 to the signal handler.
00881     //!< @param p3 - passes p3 to the signal handler.
00882     //!< @param p4 - passes p4 to the signal handler.
00883     //!< @param p5 - passes p5 to the signal handler.
00884     //!< @param p6 - passes p6 to the signal handler.
00885     //!< @return the value returned by the signal handler.
00886     //!<
00887     //!< <BR>Calls every slot connected to this signal, in order of connection.
00888 
00889     R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) 
00890     {
00891         return emit(p1, p2, p3, p4, p5, p6); 
00892     }
00893     //!< Function operator; calls emit().
00894 };
00895 
00896 /*  Signal6 partially specialized for void return
00897  */
00898  
00899 template<typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename IgnoreMarshal>
00900 class Signal6<void, P1, P2, P3, P4, P5, P6, IgnoreMarshal> : public Signal
00901 {
00902     typedef Signal6<void, P1, P2, P3, P4, P5, P6, IgnoreMarshal> Self;
00903 
00904     static void callback(void *data, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)
00905     {
00906         Self *s = static_cast<Self*>(data);
00907         s->emit(p1, p2, p3, p4, p5, p6);
00908     }
00909 
00910 public:
00911     typedef Slot6<void, P1, P2, P3, P4, P5, P6> SlotType;
00912 
00913     Connection connect(SlotType *slot)
00914     { 
00915         return Signal::connect(slot);
00916     }
00917 
00918     SlotType* slot()
00919     {
00920         return new SignalSlot6<Self, void, P1, P2, P3, P4, P5, P6>(this, &callback);
00921     }
00922 
00923     void emit(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)
00924     {
00925         ConnectionList::iterator i = connection_list.begin();
00926         while (i != connection_list.end())
00927         {
00928             if (!(*i)->blocked())
00929             {
00930                 SlotType *slot = dynamic_cast<SlotType*>((*i)->slot());
00931                 if (slot) slot->call(p1, p2, p3, p4, p5, p6);
00932             }
00933             ++i;
00934         }
00935     }
00936 
00937     void operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6)
00938     {
00939         emit(p1, p2, p3, p4, p5, p6); 
00940     }
00941 };
00942 
00943 /** @} */
00944 
00945 } // namespace scim
00946 
00947 #endif //__SCIM_SIGNALS_H
00948 
00949 /*
00950 vi:ts=4:nowrap:ai:expandtab
00951 */
00952 

Generated on Tue Apr 19 00:10:59 2005 for scim by  doxygen 1.4.1