diff options
author | Pavel Labath <pavelo@centrum.sk> | 2011-05-03 10:49:05 (GMT) |
---|---|---|
committer | Pavel Labath <pavelo@centrum.sk> | 2011-05-10 11:00:45 (GMT) |
commit | 0775350fee345e37fb59835dda4d85664346b606 (patch) | |
tree | 390af82593f92e11033ca2a2590a5ec7b7a3d14c /src/FbTk/Signal.hh | |
parent | bef2039d2c5a31ab9f974059d991557276647af1 (diff) | |
download | fluxbox-0775350fee345e37fb59835dda4d85664346b606.zip fluxbox-0775350fee345e37fb59835dda4d85664346b606.tar.bz2 |
Last round of simplification of Signal/Slot classes
- merged all the common stuff from 0,1,2,3 argument versions into one common base class
- removed ReturnType template parameter as it was instantiated with "void" everywhere and the
current ignores the return value of the callbacks anyway
Diffstat (limited to 'src/FbTk/Signal.hh')
-rw-r--r-- | src/FbTk/Signal.hh | 102 |
1 files changed, 37 insertions, 65 deletions
diff --git a/src/FbTk/Signal.hh b/src/FbTk/Signal.hh index 432bb3f..a7b91ba 100644 --- a/src/FbTk/Signal.hh +++ b/src/FbTk/Signal.hh | |||
@@ -22,7 +22,6 @@ | |||
22 | #ifndef FBTK_SIGNAL_HH | 22 | #ifndef FBTK_SIGNAL_HH |
23 | #define FBTK_SIGNAL_HH | 23 | #define FBTK_SIGNAL_HH |
24 | 24 | ||
25 | #include "RefCount.hh" | ||
26 | #include "Slot.hh" | 25 | #include "Slot.hh" |
27 | #include <algorithm> | 26 | #include <algorithm> |
28 | #include <list> | 27 | #include <list> |
@@ -35,7 +34,7 @@ namespace FbTk { | |||
35 | namespace SigImpl { | 34 | namespace SigImpl { |
36 | 35 | ||
37 | /** | 36 | /** |
38 | * Parent class for all \c Signal[0...*] classes. | 37 | * Parent class for all \c Signal template classes. |
39 | * It handles the disconnect and holds all the slots. The connect must be | 38 | * It handles the disconnect and holds all the slots. The connect must be |
40 | * handled by the child class so it can do the type checking. | 39 | * handled by the child class so it can do the type checking. |
41 | */ | 40 | */ |
@@ -121,93 +120,66 @@ private: | |||
121 | unsigned m_emitting; | 120 | unsigned m_emitting; |
122 | }; | 121 | }; |
123 | 122 | ||
124 | struct EmptyArg {}; | 123 | template <typename Arg1, typename Arg2, typename Arg3> |
125 | 124 | class SignalTemplate: public SignalHolder { | |
126 | } // namespace SigImpl | ||
127 | |||
128 | |||
129 | /// Specialization for three arguments. | ||
130 | template <typename ReturnType, | ||
131 | typename Arg1 = SigImpl::EmptyArg, typename Arg2 = SigImpl::EmptyArg, typename Arg3 = SigImpl::EmptyArg > | ||
132 | class Signal: public SigImpl::SignalHolder { | ||
133 | public: | 125 | public: |
134 | void emit(Arg1 arg1, Arg2 arg2, Arg3 arg3) { | 126 | template<typename Functor> |
127 | SlotID connect(const Functor& functor) { | ||
128 | return SignalHolder::connect(SlotPtr( new Slot<Arg1, Arg2, Arg3, Functor>(functor) )); | ||
129 | } | ||
130 | |||
131 | protected: | ||
132 | void emit_(Arg1 arg1, Arg2 arg2, Arg3 arg3) { | ||
135 | begin_emitting(); | 133 | begin_emitting(); |
136 | for ( Iterator it = begin(); it != end(); ++it ) { | 134 | for ( Iterator it = begin(); it != end(); ++it ) { |
137 | if(*it) | 135 | if(*it) |
138 | static_cast<SigImpl::SlotBase3<ReturnType, Arg1, Arg2, Arg3> &>(**it)(arg1, arg2, arg3); | 136 | static_cast<SigImpl::SlotTemplate<Arg1, Arg2, Arg3> &>(**it)(arg1, arg2, arg3); |
139 | } | 137 | } |
140 | end_emitting(); | 138 | end_emitting(); |
141 | } | 139 | } |
140 | }; | ||
142 | 141 | ||
143 | template<typename Functor> | 142 | } // namespace SigImpl |
144 | SlotID connect(const Functor& functor) { | 143 | |
145 | return SignalHolder::connect(SlotPtr( | 144 | |
146 | new SigImpl::Slot3<ReturnType, Arg1, Arg2, Arg3, Functor>(functor) | 145 | /// Base template for three arguments. |
147 | )); | 146 | template <typename Arg1 = SigImpl::EmptyArg, typename Arg2 = SigImpl::EmptyArg, typename Arg3 = SigImpl::EmptyArg > |
148 | } | 147 | class Signal: public SigImpl::SignalTemplate<Arg1, Arg2, Arg3> { |
148 | public: | ||
149 | void emit(Arg1 arg1, Arg2 arg2, Arg3 arg3) | ||
150 | { SigImpl::SignalTemplate<Arg1, Arg2, Arg3>::emit_(arg1, arg2, arg3); } | ||
149 | }; | 151 | }; |
150 | 152 | ||
151 | /// Specialization for two arguments. | 153 | /// Specialization for two arguments. |
152 | template <typename ReturnType, typename Arg1, typename Arg2> | 154 | template <typename Arg1, typename Arg2> |
153 | class Signal<ReturnType, Arg1, Arg2, SigImpl::EmptyArg>: public SigImpl::SignalHolder { | 155 | class Signal<Arg1, Arg2, SigImpl::EmptyArg>: |
156 | public SigImpl::SignalTemplate<Arg1, Arg2, SigImpl::EmptyArg> { | ||
154 | public: | 157 | public: |
155 | void emit(Arg1 arg1, Arg2 arg2) { | 158 | void emit(Arg1 arg1, Arg2 arg2) { |
156 | begin_emitting(); | 159 | SigImpl::SignalTemplate<Arg1, Arg2, SigImpl::EmptyArg>:: |
157 | for ( Iterator it = begin(); it != end(); ++it ) { | 160 | emit_(arg1, arg2, SigImpl::EmptyArg()); |
158 | if(*it) | ||
159 | static_cast<SigImpl::SlotBase2<ReturnType, Arg1, Arg2> &>(**it)(arg1, arg2); | ||
160 | } | ||
161 | end_emitting(); | ||
162 | } | ||
163 | |||
164 | template<typename Functor> | ||
165 | SlotID connect(const Functor& functor) { | ||
166 | return SignalHolder::connect(SlotPtr( | ||
167 | new SigImpl::Slot2<ReturnType, Arg1, Arg2, Functor>(functor) | ||
168 | )); | ||
169 | } | 161 | } |
170 | }; | 162 | }; |
171 | 163 | ||
172 | /// Specialization for one argument. | 164 | /// Specialization for one argument. |
173 | template <typename ReturnType, typename Arg1> | 165 | template <typename Arg1> |
174 | class Signal<ReturnType, Arg1, SigImpl::EmptyArg, SigImpl::EmptyArg>: public SigImpl::SignalHolder { | 166 | class Signal<Arg1, SigImpl::EmptyArg, SigImpl::EmptyArg>: |
167 | public SigImpl::SignalTemplate<Arg1, SigImpl::EmptyArg, SigImpl::EmptyArg> { | ||
175 | public: | 168 | public: |
176 | void emit(Arg1 arg) { | 169 | void emit(Arg1 arg1) { |
177 | begin_emitting(); | 170 | SigImpl::SignalTemplate<Arg1, SigImpl::EmptyArg, SigImpl::EmptyArg> |
178 | for ( Iterator it = begin(); it != end(); ++it ) { | 171 | ::emit_(arg1, SigImpl::EmptyArg(), SigImpl::EmptyArg()); |
179 | if(*it) | ||
180 | static_cast<SigImpl::SlotBase1<ReturnType, Arg1> &>(**it)(arg); | ||
181 | } | ||
182 | end_emitting(); | ||
183 | } | ||
184 | |||
185 | template<typename Functor> | ||
186 | SlotID connect(const Functor& functor) { | ||
187 | return SignalHolder::connect(SlotPtr( | ||
188 | new SigImpl::Slot1<ReturnType, Arg1, Functor>(functor) | ||
189 | )); | ||
190 | } | 172 | } |
191 | }; | 173 | }; |
192 | 174 | ||
193 | /// Specialization for no arguments. | 175 | /// Specialization for no arguments. |
194 | template <typename ReturnType> | 176 | template <> |
195 | class Signal<ReturnType, SigImpl::EmptyArg, SigImpl::EmptyArg, SigImpl::EmptyArg>: public SigImpl::SignalHolder { | 177 | class Signal<SigImpl::EmptyArg, SigImpl::EmptyArg, SigImpl::EmptyArg>: |
178 | public SigImpl::SignalTemplate<SigImpl::EmptyArg, SigImpl::EmptyArg, SigImpl::EmptyArg> { | ||
196 | public: | 179 | public: |
197 | void emit() { | 180 | void emit() { |
198 | begin_emitting(); | 181 | SigImpl::SignalTemplate<SigImpl::EmptyArg, SigImpl::EmptyArg, SigImpl::EmptyArg> |
199 | for ( Iterator it = begin(); it != end(); ++it ) { | 182 | ::emit_(SigImpl::EmptyArg(), SigImpl::EmptyArg(), SigImpl::EmptyArg()); |
200 | if(*it) | ||
201 | static_cast<SigImpl::SlotBase0<ReturnType> &>(**it)(); | ||
202 | } | ||
203 | end_emitting(); | ||
204 | } | ||
205 | |||
206 | template<typename Functor> | ||
207 | SlotID connect(const Functor& functor) { | ||
208 | return SignalHolder::connect(SlotPtr( | ||
209 | new SigImpl::Slot0<ReturnType, Functor>(functor) | ||
210 | )); | ||
211 | } | 183 | } |
212 | }; | 184 | }; |
213 | 185 | ||