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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 #ifndef __SCIM_SIGNALS_H
00044 #define __SCIM_SIGNALS_H
00045
00046 namespace scim {
00047
00048
00049
00050
00051
00052
00053 class Signal;
00054
00055
00056
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
00070
00071 virtual void block();
00072
00073
00074 virtual void unblock();
00075
00076
00077 virtual void disconnect();
00078
00079 };
00080
00081
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
00099 bool marshal(const InType & newval)
00100 {
00101 value_ = newval;
00102 return false;
00103 }
00104 };
00105
00106
00107
00108
00109 class Signal
00110 {
00111 Signal(const Signal&);
00112 Signal& operator=(const Signal&);
00113
00114 protected:
00115 typedef std::vector<SlotNode*> ConnectionList;
00116
00117
00118 ConnectionList connection_list;
00119
00120
00121 public:
00122 Signal();
00123
00124
00125 virtual ~Signal();
00126
00127
00128 SlotNode* connect(Slot *slot);
00129
00130 };
00131
00132
00133
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
00149
00150 Connection connect(SlotType *slot)
00151 {
00152 return Signal::connect(slot);
00153 }
00154
00155
00156
00157
00158
00159
00160 SlotType* slot()
00161 {
00162 return new SignalSlot0<Self, R>(this, &callback);
00163 }
00164
00165
00166
00167
00168
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 (m.marshal(slot->call()))
00180 break;
00181 }
00182 ++i;
00183 }
00184 return m.value();
00185 }
00186
00187
00188
00189
00190
00191 R operator()()
00192 {
00193 return emit();
00194 }
00195
00196 };
00197
00198
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 slot->call();
00233 }
00234 ++i;
00235 }
00236 }
00237
00238 void operator()()
00239 {
00240 emit();
00241 }
00242 };
00243
00244
00245
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
00261
00262 Connection connect(SlotType *slot)
00263 {
00264 return Signal::connect(slot);
00265 }
00266
00267
00268
00269
00270
00271
00272 SlotType* slot()
00273 {
00274 return new SignalSlot1<Self, R, P1>(this, &callback);
00275 }
00276
00277
00278
00279
00280
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 (m.marshal(slot->call(p1)))
00292 break;
00293 }
00294 ++i;
00295 }
00296 return m.value();
00297 }
00298
00299
00300
00301
00302
00303
00304 R operator()(P1 p1)
00305 {
00306 return emit(p1);
00307 }
00308
00309 };
00310
00311
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 slot->call(p1);
00346 }
00347 ++i;
00348 }
00349 }
00350
00351 void operator()(P1 p1)
00352 {
00353 emit(p1);
00354 }
00355 };
00356
00357
00358
00359
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
00375
00376 Connection connect(SlotType *slot)
00377 {
00378 return Signal::connect(slot);
00379 }
00380
00381
00382
00383
00384
00385
00386 SlotType* slot()
00387 {
00388 return new SignalSlot2<Self, R, P1, P2>(this, &callback);
00389 }
00390
00391
00392
00393
00394
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 (m.marshal(slot->call(p1, p2)))
00406 break;
00407 }
00408 ++i;
00409 }
00410 return m.value();
00411 }
00412
00413
00414
00415
00416
00417
00418
00419 R operator()(P1 p1, P2 p2)
00420 {
00421 return emit(p1, p2);
00422 }
00423
00424 };
00425
00426
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 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
00473
00474
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
00490
00491 Connection connect(SlotType *slot)
00492 {
00493 return Signal::connect(slot);
00494 }
00495
00496
00497
00498
00499
00500
00501 SlotType* slot()
00502 {
00503 return new SignalSlot3<Self, R, P1, P2, P3>(this, &callback);
00504 }
00505
00506
00507
00508
00509
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 (m.marshal(slot->call(p1, p2, p3)))
00521 break;
00522 }
00523 ++i;
00524 }
00525 return m.value();
00526 }
00527
00528
00529
00530
00531
00532
00533
00534
00535 R operator()(P1 p1, P2 p2, P3 p3)
00536 {
00537 return emit(p1, p2, p3);
00538 }
00539
00540 };
00541
00542
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 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
00589
00590
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
00606
00607 Connection connect(SlotType *slot)
00608 {
00609 return Signal::connect(slot);
00610 }
00611
00612
00613
00614
00615
00616
00617 SlotType* slot()
00618 {
00619 return new SignalSlot4<Self, R, P1, P2, P3, P4>(this, &callback);
00620 }
00621
00622
00623
00624
00625
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 (m.marshal(slot->call(p1, p2, p3, p4)))
00637 break;
00638 }
00639 ++i;
00640 }
00641 return m.value();
00642 }
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652 R operator()(P1 p1, P2 p2, P3 p3, P4 p4)
00653 {
00654 return emit(p1, p2, p3, p4);
00655 }
00656
00657 };
00658
00659
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 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
00706
00707
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
00723
00724 Connection connect(SlotType *slot)
00725 {
00726 return Signal::connect(slot);
00727 }
00728
00729
00730
00731
00732
00733
00734 SlotType* slot()
00735 {
00736 return new SignalSlot5<Self, R, P1, P2, P3, P4, P5>(this, &callback);
00737 }
00738
00739
00740
00741
00742
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 (m.marshal(slot->call(p1, p2, p3, p4, p5)))
00754 break;
00755 }
00756 ++i;
00757 }
00758 return m.value();
00759 }
00760
00761
00762
00763
00764
00765
00766
00767
00768
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
00775 };
00776
00777
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 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
00824
00825
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
00841
00842 Connection connect(SlotType *slot)
00843 {
00844 return Signal::connect(slot);
00845 }
00846
00847
00848
00849
00850
00851
00852 SlotType* slot()
00853 {
00854 return new SignalSlot6<Self, R, P1, P2, P3, P4, P5, P6>(this, &callback);
00855 }
00856
00857
00858
00859
00860
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 (m.marshal(slot->call(p1, p2, p3, p4, p5, p6)))
00872 break;
00873 }
00874 ++i;
00875 }
00876 return m.value();
00877 }
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
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
00894 };
00895
00896
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 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 }
00946
00947 #endif //__SCIM_SIGNALS_H
00948
00949
00950
00951
00952