aboutsummaryrefslogtreecommitdiff
path: root/src/FbTk/Slot.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/FbTk/Slot.hh')
-rw-r--r--src/FbTk/Slot.hh275
1 files changed, 43 insertions, 232 deletions
diff --git a/src/FbTk/Slot.hh b/src/FbTk/Slot.hh
index 9080d53..3daca4e 100644
--- a/src/FbTk/Slot.hh
+++ b/src/FbTk/Slot.hh
@@ -27,268 +27,79 @@ namespace FbTk {
27/// \namespace Implementation details for signals, do not use anything in this namespace 27/// \namespace Implementation details for signals, do not use anything in this namespace
28namespace SigImpl { 28namespace SigImpl {
29 29
30class CallbackHolder; 30class SlotBase {
31
32/// Placeholder type for typed callbacks
33typedef void* (*CallbackFunc)(void *);
34/// Clone function callback type for cloning typed callback holders
35typedef CallbackHolder* (*CloneFunc)(CallbackHolder*);
36/// Kill function callback type for destroying type specific information in
37/// FunctorHolder
38typedef void (*KillFunc)(CallbackHolder*);
39
40/// Holds clone, functor callback, and the kill function for FunctorHolder.
41class CallbackHolder {
42public: 31public:
43 /** 32 virtual ~SlotBase() {}
44 * @param callback The callback to call when a slot receives a signal.
45 * @param clone The callback to use for cloning a type specific instance of
46 * this classinstance.
47 * @param kill The callback that knows how to free the memory in type
48 * specific instance of this class.
49 */
50 CallbackHolder(CallbackFunc callback,
51 CloneFunc clone,
52 KillFunc kill):
53 m_callback(callback),
54 m_kill(kill),
55 m_clone(clone) { }
56
57 ~CallbackHolder() {
58 (*m_kill)(this);
59 }
60
61 /// @return a clone of this instance
62 CallbackHolder* clone() {
63 return (*m_clone)(this);
64 }
65
66 /// \c Callback to \c Functor specific callback
67 CallbackFunc m_callback;
68
69protected:
70
71 CallbackHolder& operator = (const CallbackHolder& other) {
72 if ( this == &other ) {
73 return *this;
74 }
75 m_callback = other.m_callback;
76 m_clone = other.m_clone;
77 m_kill = other.m_kill;
78
79 return *this;
80 }
81
82 CallbackHolder(const CallbackHolder& other) {
83 *this = other;
84 }
85
86private:
87 /// This function is called to kill this instance
88 KillFunc m_kill;
89 /// Functions that knows how to clone a specific \c Functor type
90 CloneFunc m_clone;
91}; 33};
92 34
93 35template<typename ReturnType>
94/// Holds the functor and creates a clone callback for \c Functor specific type 36class SlotBase0: public SlotBase {
95template <typename Functor>
96class FunctorHolder: public CallbackHolder {
97public: 37public:
98 /// This type. 38 virtual ReturnType operator()() = 0;
99 typedef FunctorHolder<Functor> Self;
100 /**
101 * @param functor The functor to be used when a signal is emitted.
102 * @param callback The callback to call when a signal is emitted.
103 */
104 FunctorHolder(const Functor& functor, CallbackFunc callback):
105 CallbackHolder(callback, &clone, &kill),
106 m_functor(functor) {
107 }
108
109 /// Specific clone for this Functor type
110 static CallbackHolder* clone(CallbackHolder* self) {
111 return new Self( static_cast<Self&>(*self));
112 }
113
114 static void kill(CallbackHolder* self) {
115 // Destroy functor
116 static_cast<Self*>( self )->m_functor.~Functor();
117 }
118
119 Functor m_functor; ///< the functor to use when a signal is emitted.
120};
121
122
123
124/// Callback with no arguments.
125template <typename Functor, typename ReturnType >
126struct Callback0 {
127 static ReturnType callback(CallbackHolder* base) {
128 static_cast< FunctorHolder<Functor>* >( base )->m_functor();
129 return ReturnType();
130 }
131
132 static CallbackFunc functionAddress() {
133 return reinterpret_cast<CallbackFunc>(&callback);
134 }
135}; 39};
136 40
137/// Callback with one argument 41template<typename ReturnType, typename Functor>
138template <typename Functor, typename ReturnType, typename Arg1> 42class Slot0: public SlotBase0<ReturnType> {
139struct Callback1 { 43public:
140 typedef ReturnType (Functor::* CallbackType)(CallbackHolder*, Arg1); 44 virtual ReturnType operator()() { return m_functor(); }
141
142 static ReturnType callback(CallbackHolder* base, Arg1 arg1) {
143 static_cast< FunctorHolder<Functor>* >( base )->m_functor(arg1);
144 return ReturnType();
145 }
146
147 static CallbackFunc functionAddress() {
148 return reinterpret_cast<CallbackFunc>(&callback);
149 }
150};
151
152/// Callback with two arguments
153template <typename Functor, typename ReturnType,
154 typename Arg1, typename Arg2>
155struct Callback2 {
156 typedef ReturnType (Functor::* CallbackType)(CallbackHolder*, Arg1, Arg2);
157 45
158 static ReturnType callback(CallbackHolder* base, Arg1 arg1, Arg2 arg2) { 46 Slot0(Functor functor) : m_functor(functor) {}
159 static_cast< FunctorHolder<Functor>* >( base )->m_functor(arg1, arg2);
160 return ReturnType();
161 }
162 47
163 static CallbackFunc functionAddress() { 48private:
164 return reinterpret_cast<CallbackFunc>(&callback); 49 Functor m_functor;
165 }
166}; 50};
167 51
168/// Callback with three arguments 52template<typename ReturnType, typename Arg1>
169template <typename Functor, typename ReturnType, 53class SlotBase1: public SlotBase {
170 typename Arg1, typename Arg2, typename Arg3> 54public:
171struct Callback3 { 55 virtual ReturnType operator()(Arg1) = 0;
172 typedef ReturnType (Functor::* CallbackType)(CallbackHolder*, Arg1, Arg2, Arg3);
173
174 static ReturnType callback(CallbackHolder* base, Arg1 arg1, Arg2 arg2, Arg3 arg3) {
175 static_cast< FunctorHolder<Functor>* >( base )->m_functor( arg1, arg2, arg3 );
176 return ReturnType();
177 }
178
179 static CallbackFunc functionAddress() {
180 return reinterpret_cast<CallbackFunc>(&callback);
181 }
182}; 56};
183 57
184/// Holds callback holder and handles the copying of callback holders for the 58template<typename ReturnType, typename Arg1, typename Functor>
185/// \c Slots. 59class Slot1: public SlotBase1<ReturnType, Arg1> {
186class SlotHolder {
187public: 60public:
188 SlotHolder(const SlotHolder& other): 61 virtual ReturnType operator()(Arg1 arg1) { return m_functor(arg1); }
189 m_holder( other.m_holder ? other.m_holder->clone() : 0 ) {
190 }
191
192 ~SlotHolder() {
193 delete m_holder;
194 }
195
196 SlotHolder& operator = (const SlotHolder& other) {
197 if ( &other == this ) {
198 return *this;
199 }
200 delete m_holder;
201 if ( other.m_holder ) {
202 m_holder = other.m_holder->clone();
203 } else {
204 m_holder = 0;
205 }
206 return *this;
207 }
208 62
209 SlotHolder():m_holder( 0 ) { } 63 Slot1(Functor functor) : m_functor(functor) {}
210 64
211protected: 65private:
212 explicit SlotHolder(CallbackHolder* holder): 66 Functor m_functor;
213 m_holder( holder ) {
214 }
215
216 CallbackHolder* m_holder;
217}; 67};
218 68
219/// Slot with no argument. 69template<typename ReturnType, typename Arg1, typename Arg2>
220template <typename ReturnType> 70class SlotBase2: public SlotBase {
221class Slot0: public SlotHolder {
222public: 71public:
223 typedef ReturnType (*CallbackType)(CallbackHolder*); 72 virtual ReturnType operator()(Arg1, Arg2) = 0;
224
225 template <typename Functor>
226 Slot0( const Functor& functor ):
227 SlotHolder( new FunctorHolder<Functor>
228 (functor, Callback0<Functor, ReturnType>::functionAddress())) {
229 }
230
231 void operator()() {
232 if (m_holder)
233 reinterpret_cast<CallbackType>(m_holder->m_callback)( m_holder );
234 }
235}; 73};
236 74
237/// Slot with one argument. 75template<typename ReturnType, typename Arg1, typename Arg2, typename Functor>
238template <typename ReturnType, typename Arg1> 76class Slot2: public SlotBase2<ReturnType, Arg1, Arg2> {
239class Slot1:public SlotHolder {
240public: 77public:
241 typedef ReturnType (*CallbackType)(CallbackHolder*, Arg1); 78 virtual ReturnType operator()(Arg1 arg1, Arg2 arg2) { return m_functor(arg1, arg2); }
242
243 template <typename Functor>
244 Slot1( const Functor& functor ):
245 SlotHolder( new FunctorHolder<Functor>
246 (functor, Callback1<Functor, ReturnType, Arg1>::functionAddress())){
247
248 }
249 79
250 void operator()(Arg1 arg) { 80 Slot2(Functor functor) : m_functor(functor) {}
251 if (m_holder)
252 reinterpret_cast<CallbackType>(m_holder->m_callback)(m_holder, arg);
253 }
254 81
82private:
83 Functor m_functor;
255}; 84};
256 85
257/// Slot with two arguments 86template<typename ReturnType, typename Arg1, typename Arg2, typename Arg3>
258template <typename ReturnType, typename Arg1, typename Arg2> 87class SlotBase3: public SlotBase {
259class Slot2: public SlotHolder {
260public: 88public:
261 typedef ReturnType (*CallbackType)(CallbackHolder*, Arg1, Arg2); 89 virtual ReturnType operator()(Arg1, Arg2, Arg3) = 0;
262 template <typename Functor> 90 virtual ~SlotBase3() {}
263 Slot2( const Functor& functor ):
264 SlotHolder( new FunctorHolder<Functor>
265 (functor, Callback2<Functor, ReturnType, Arg1, Arg2>::functionAddress())){
266
267 }
268
269 void operator()(Arg1 arg1, Arg2 arg2) {
270 if (m_holder)
271 reinterpret_cast<CallbackType>(m_holder->m_callback)(m_holder, arg1, arg2);
272 }
273}; 91};
274 92
275/// Slot with three arguments 93template<typename ReturnType, typename Arg1, typename Arg2, typename Arg3, typename Functor>
276template <typename ReturnType, typename Arg1, typename Arg2, typename Arg3> 94class Slot3: public SlotBase3<ReturnType, Arg1, Arg2, Arg3> {
277class Slot3: public SlotHolder {
278public: 95public:
279 typedef ReturnType (*CallbackType)(CallbackHolder*, Arg1, Arg2, Arg3); 96 virtual ReturnType operator()(Arg1 arg1, Arg2 arg2, Arg3 arg3)
280 template <typename Functor> 97 { return m_functor(arg1, arg2, arg3); }
281 Slot3( const Functor& functor ):
282 SlotHolder( new FunctorHolder<Functor>
283 (functor, Callback3<Functor, ReturnType, Arg1, Arg2, Arg3>::functionAddress())){
284
285 }
286 98
287 void operator()(Arg1 arg1, Arg2 arg2, Arg3 arg3) { 99 Slot3(Functor functor) : m_functor(functor) {}
288 if (m_holder) 100
289 reinterpret_cast<CallbackType>(m_holder->m_callback) 101private:
290 ( m_holder, arg1, arg2, arg3 ); 102 Functor m_functor;
291 }
292}; 103};
293 104
294} // namespace SigImpl 105} // namespace SigImpl