aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk/Signal.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/FbTk/Signal.hh')
-rw-r--r--src/FbTk/Signal.hh91
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
123template <typename Arg1, typename Arg2, typename Arg3> 124} // namespace SigImpl
124class SignalTemplate: public SignalHolder {
125public:
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
131protected: 126
132 void emit_(Arg1 arg1, Arg2 arg2, Arg3 arg3) { 127/// Specialization for three arguments.
128template <typename Arg1 = SigImpl::EmptyArg, typename Arg2 = SigImpl::EmptyArg, typename Arg3 = SigImpl::EmptyArg >
129class Signal: public SigImpl::SignalHolder {
130public:
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) {
146template <typename Arg1 = SigImpl::EmptyArg, typename Arg2 = SigImpl::EmptyArg, typename Arg3 = SigImpl::EmptyArg > 142 return SignalHolder::connect(SlotPtr(
147class Signal: public SigImpl::SignalTemplate<Arg1, Arg2, Arg3> { 143 new SlotImpl<Functor, void, Arg1, Arg2, Arg3>(functor)
148public: 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.
154template <typename Arg1, typename Arg2> 149template <typename Arg1, typename Arg2>
155class Signal<Arg1, Arg2, SigImpl::EmptyArg>: 150class Signal<Arg1, Arg2, SigImpl::EmptyArg>: public SigImpl::SignalHolder {
156 public SigImpl::SignalTemplate<Arg1, Arg2, SigImpl::EmptyArg> {
157public: 151public:
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.
165template <typename Arg1> 170template <typename Arg1>
166class Signal<Arg1, SigImpl::EmptyArg, SigImpl::EmptyArg>: 171class Signal<Arg1, SigImpl::EmptyArg, SigImpl::EmptyArg>: public SigImpl::SignalHolder {
167 public SigImpl::SignalTemplate<Arg1, SigImpl::EmptyArg, SigImpl::EmptyArg> {
168public: 172public:
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.
176template <> 191template <>
177class Signal<SigImpl::EmptyArg, SigImpl::EmptyArg, SigImpl::EmptyArg>: 192class Signal<SigImpl::EmptyArg, SigImpl::EmptyArg, SigImpl::EmptyArg>: public SigImpl::SignalHolder {
178 public SigImpl::SignalTemplate<SigImpl::EmptyArg, SigImpl::EmptyArg, SigImpl::EmptyArg> {
179public: 193public:
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