Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | 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 Thu Dec 30 21:03:19 2004 for scim by doxygen 1.3.8