diff options
Diffstat (limited to 'src/FbTk/Signal.hh')
-rw-r--r-- | src/FbTk/Signal.hh | 91 |
1 files changed, 58 insertions, 33 deletions
diff --git a/src/FbTk/Signal.hh b/src/FbTk/Signal.hh index 0148a17..31fd840 100644 --- a/src/FbTk/Signal.hh +++ b/src/FbTk/Signal.hh | |||
@@ -22,6 +22,7 @@ | |||
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" | ||
25 | #include "Slot.hh" | 26 | #include "Slot.hh" |
26 | #include <algorithm> | 27 | #include <algorithm> |
27 | #include <list> | 28 | #include <list> |
@@ -120,66 +121,90 @@ private: | |||
120 | unsigned m_emitting; | 121 | unsigned m_emitting; |
121 | }; | 122 | }; |
122 | 123 | ||
123 | template <typename Arg1, typename Arg2, typename Arg3> | 124 | } // namespace SigImpl |
124 | class SignalTemplate: public SignalHolder { | ||
125 | public: | ||
126 | template<typename Functor> | ||
127 | SlotID connect(const Functor& functor) { | ||
128 | return SignalHolder::connect(SlotPtr( new Slot<Arg1, Arg2, Arg3, Functor>(functor) )); | ||
129 | } | ||
130 | 125 | ||
131 | protected: | 126 | |
132 | void emit_(Arg1 arg1, Arg2 arg2, Arg3 arg3) { | 127 | /// Specialization for three arguments. |
128 | template <typename Arg1 = SigImpl::EmptyArg, typename Arg2 = SigImpl::EmptyArg, typename Arg3 = SigImpl::EmptyArg > | ||
129 | class Signal: public SigImpl::SignalHolder { | ||
130 | public: | ||
131 | void emit(Arg1 arg1, Arg2 arg2, Arg3 arg3) { | ||
133 | begin_emitting(); | 132 | begin_emitting(); |
134 | for ( Iterator it = begin(); it != end(); ++it ) { | 133 | for ( Iterator it = begin(); it != end(); ++it ) { |
135 | if(*it) | 134 | if(*it) |
136 | static_cast<SigImpl::SlotTemplate<Arg1, Arg2, Arg3> &>(**it)(arg1, arg2, arg3); | 135 | static_cast<Slot<void, Arg1, Arg2, Arg3> &>(**it)(arg1, arg2, arg3); |
137 | } | 136 | } |
138 | end_emitting(); | 137 | end_emitting(); |
139 | } | 138 | } |
140 | }; | ||
141 | |||
142 | } // namespace SigImpl | ||
143 | 139 | ||
144 | 140 | template<typename Functor> | |
145 | /// Base template for three arguments. | 141 | SlotID connect(const Functor& functor) { |
146 | template <typename Arg1 = SigImpl::EmptyArg, typename Arg2 = SigImpl::EmptyArg, typename Arg3 = SigImpl::EmptyArg > | 142 | return SignalHolder::connect(SlotPtr( |
147 | class Signal: public SigImpl::SignalTemplate<Arg1, Arg2, Arg3> { | 143 | new SlotImpl<Functor, void, Arg1, Arg2, Arg3>(functor) |
148 | public: | 144 | )); |
149 | void emit(Arg1 arg1, Arg2 arg2, Arg3 arg3) | 145 | } |
150 | { SigImpl::SignalTemplate<Arg1, Arg2, Arg3>::emit_(arg1, arg2, arg3); } | ||
151 | }; | 146 | }; |
152 | 147 | ||
153 | /// Specialization for two arguments. | 148 | /// Specialization for two arguments. |
154 | template <typename Arg1, typename Arg2> | 149 | template <typename Arg1, typename Arg2> |
155 | class Signal<Arg1, Arg2, SigImpl::EmptyArg>: | 150 | class Signal<Arg1, Arg2, SigImpl::EmptyArg>: public SigImpl::SignalHolder { |
156 | public SigImpl::SignalTemplate<Arg1, Arg2, SigImpl::EmptyArg> { | ||
157 | public: | 151 | public: |
158 | void emit(Arg1 arg1, Arg2 arg2) { | 152 | void emit(Arg1 arg1, Arg2 arg2) { |
159 | SigImpl::SignalTemplate<Arg1, Arg2, SigImpl::EmptyArg>:: | 153 | begin_emitting(); |
160 | emit_(arg1, arg2, SigImpl::EmptyArg()); | 154 | for ( Iterator it = begin(); it != end(); ++it ) { |
155 | if(*it) | ||
156 | static_cast<Slot<void, Arg1, Arg2> &>(**it)(arg1, arg2); | ||
157 | } | ||
158 | end_emitting(); | ||
159 | } | ||
160 | |||
161 | template<typename Functor> | ||
162 | SlotID connect(const Functor& functor) { | ||
163 | return SignalHolder::connect(SlotPtr( | ||
164 | new SlotImpl<Functor, void, Arg1, Arg2>(functor) | ||
165 | )); | ||
161 | } | 166 | } |
162 | }; | 167 | }; |
163 | 168 | ||
164 | /// Specialization for one argument. | 169 | /// Specialization for one argument. |
165 | template <typename Arg1> | 170 | template <typename Arg1> |
166 | class Signal<Arg1, SigImpl::EmptyArg, SigImpl::EmptyArg>: | 171 | class Signal<Arg1, SigImpl::EmptyArg, SigImpl::EmptyArg>: public SigImpl::SignalHolder { |
167 | public SigImpl::SignalTemplate<Arg1, SigImpl::EmptyArg, SigImpl::EmptyArg> { | ||
168 | public: | 172 | public: |
169 | void emit(Arg1 arg1) { | 173 | void emit(Arg1 arg) { |
170 | SigImpl::SignalTemplate<Arg1, SigImpl::EmptyArg, SigImpl::EmptyArg> | 174 | begin_emitting(); |
171 | ::emit_(arg1, SigImpl::EmptyArg(), SigImpl::EmptyArg()); | 175 | for ( Iterator it = begin(); it != end(); ++it ) { |
176 | if(*it) | ||
177 | static_cast<Slot<void, Arg1> &>(**it)(arg); | ||
178 | } | ||
179 | end_emitting(); | ||
180 | } | ||
181 | |||
182 | template<typename Functor> | ||
183 | SlotID connect(const Functor& functor) { | ||
184 | return SignalHolder::connect(SlotPtr( | ||
185 | new SlotImpl<Functor, void, Arg1>(functor) | ||
186 | )); | ||
172 | } | 187 | } |
173 | }; | 188 | }; |
174 | 189 | ||
175 | /// Specialization for no arguments. | 190 | /// Specialization for no arguments. |
176 | template <> | 191 | template <> |
177 | class Signal<SigImpl::EmptyArg, SigImpl::EmptyArg, SigImpl::EmptyArg>: | 192 | class Signal<SigImpl::EmptyArg, SigImpl::EmptyArg, SigImpl::EmptyArg>: public SigImpl::SignalHolder { |
178 | public SigImpl::SignalTemplate<SigImpl::EmptyArg, SigImpl::EmptyArg, SigImpl::EmptyArg> { | ||
179 | public: | 193 | public: |
180 | void emit() { | 194 | void emit() { |
181 | SigImpl::SignalTemplate<SigImpl::EmptyArg, SigImpl::EmptyArg, SigImpl::EmptyArg> | 195 | begin_emitting(); |
182 | ::emit_(SigImpl::EmptyArg(), SigImpl::EmptyArg(), SigImpl::EmptyArg()); | 196 | for ( Iterator it = begin(); it != end(); ++it ) { |
197 | if(*it) | ||
198 | static_cast<Slot<void> &>(**it)(); | ||
199 | } | ||
200 | end_emitting(); | ||
201 | } | ||
202 | |||
203 | template<typename Functor> | ||
204 | SlotID connect(const Functor& functor) { | ||
205 | return SignalHolder::connect(SlotPtr( | ||
206 | new SlotImpl<Functor, void>(functor) | ||
207 | )); | ||
183 | } | 208 | } |
184 | }; | 209 | }; |
185 | 210 | ||