QtGStreamer  1.2.0
connect.h
1 /*
2  Copyright (C) 2010 George Kiagiadakis <kiagiadakis.george@gmail.com>
3  Copyright (C) 2010 Collabora Ltd.
4  @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk>
5 
6  This library is free software; you can redistribute it and/or modify
7  it under the terms of the GNU Lesser General Public License as published
8  by the Free Software Foundation; either version 2.1 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #ifndef QGLIB_CONNECT_H
20 #define QGLIB_CONNECT_H
21 
22 #include "global.h"
23 #include "quark.h"
24 #include <QtCore/QObject>
25 #include <QtCore/QSharedPointer>
26 #include <QtCore/QFlags>
27 #include <QtCore/QHash>
28 #ifndef Q_MOC_RUN
29 #include <boost/type_traits.hpp>
30 #endif
31 #include <boost/utility/enable_if.hpp>
32 
33 namespace QGlib {
34 
38 enum ConnectFlag { //codegen: skip=true
52  PassSender = 2
53 };
54 Q_DECLARE_FLAGS(ConnectFlags, ConnectFlag);
55 Q_DECLARE_OPERATORS_FOR_FLAGS(ConnectFlags)
56 
57 #if defined(DOXYGEN_RUN)
58 
136 template <typename T, typename R, typename... Args>
137 bool connect(void *instance, const char *detailedSignal,
138  T *receiver, R (T::*slot)(Args...), ConnectFlags flags = 0);
139 
140 //Fake disconnect() declaration.
141 //Doxygen should document a version with optional arguments. In reality we have to use
142 //two versions to avoid having to type the template parameters in case the user wants
143 //to use NULL for the receiver and slot arguments. Also, a version that takes void*
144 //for everything is not possible since member function pointers do not cast to void*.
145 
192 template <typename T, typename R, typename... Args>
193 bool disconnect(void *instance, const char *detailedSignal = 0,
194  T *receiver = 0, R (T::*slot)(Args...) = 0);
195 
196 #else //DOXYGEN_RUN
197 
198 namespace Private {
199 
200 //BEGIN ******** ClosureDataBase ********
201 
202 class QTGLIB_EXPORT ClosureDataBase
203 {
204 public:
205  inline virtual ~ClosureDataBase() {}
206  virtual void marshaller(Value &, const QList<Value> &) = 0;
207 
208  bool passSender; //whether to pass the sender instance as the first slot argument
209 
210 protected:
211  inline ClosureDataBase(bool passSender)
212  : passSender(passSender) {}
213 };
214 
215 //END ******** ClosureDataBase ********
216 
217 
218 /* This interface specifies the methods that will be used to connect/disconnect a
219  * signal receiver to/from a slot that should be called when the receiver is destroyed.
220  * This notification is used to disconnect the signal automatically.
221  */
222 class QTGLIB_EXPORT DestroyNotifierIface
223 {
224 public:
225  virtual ~DestroyNotifierIface() {}
226  virtual bool connect(void *receiver, QObject *notificationReceiver, const char *slot) = 0;
227  virtual bool disconnect(void *receiver, QObject *notificationReceiver) = 0;
228 };
229 
230 typedef QSharedPointer<DestroyNotifierIface> DestroyNotifierIfacePtr;
231 
232 /* This is DestroyNotifierIface that works for signal receivers that inherit QObject. */
233 class QTGLIB_EXPORT QObjectDestroyNotifier : public DestroyNotifierIface
234 {
235 public:
236  static DestroyNotifierIfacePtr instance();
237 
238  virtual bool connect(void *receiver, QObject *notificationReceiver, const char *slot);
239  virtual bool disconnect(void *receiver, QObject *notificationReceiver);
240 };
241 
242 /* This is provided for future expansion.
243  * It should implement operator DestroyNotifierIfacePtr() and return
244  * the appropriate DestroyNotifierIface for the given type T
245  * (i.e. the signal receiver is of type T)
246  */
247 template <typename T, typename Enable = void>
248 struct GetDestroyNotifier
249 {
250 };
251 
252 /* Partial specialization for QObjects (T inherits QObject) */
253 template <typename T>
254 struct GetDestroyNotifier<T, typename boost::enable_if< boost::is_base_of<QObject, T> >::type>
255 {
256  inline operator DestroyNotifierIfacePtr() { return QObjectDestroyNotifier::instance(); }
257 };
258 
259 
260 /* This method is used internally from QGlib::connect(). */
261 QTGLIB_EXPORT ulong connect(void *instance, const char *signal, Quark detail,
262  void *receiver, const DestroyNotifierIfacePtr & notifier,
263  uint slotHash, ClosureDataBase *closureData, ConnectFlags flags);
264 
265 /* This method is used internally from QGlib::disconnect(). */
266 QTGLIB_EXPORT bool disconnect(void *instance, const char *signal, Quark detail,
267  void *receiver, uint slotHash, ulong handlerId);
268 
269 
270 /* This is a helper that returns a hash value for a member function pointer.
271  * Because of the nature of member function pointers, it is not possible to cast
272  * them to void* or any integral type and as a result we need to create a hash value
273  * of their data to be able to store them in the connections store. This value is
274  * only used for disconnection, so storing the real pointer is not necessary.
275  */
276 template <typename T>
277 inline typename boost::enable_if< boost::is_member_function_pointer<T>, uint >::type
278 hashMfp(const T & mfp)
279 {
280  const char *data = reinterpret_cast<const char*>(&mfp);
281  return qHash(QByteArray::fromRawData(data, sizeof(T)));
282 }
283 
284 template <typename T>
285 inline typename boost::enable_if< boost::is_integral<T>, uint >::type
286 hashMfp(const T & mfp)
287 {
288  Q_ASSERT(mfp == 0);
289  return 0;
290 }
291 
292 } //namespace Private
293 
294 
295 //The real QGlib::disconnect
296 
297 inline bool disconnect(void *instance, const char *detailedSignal = 0, void *receiver = 0)
298 {
299  return Private::disconnect(instance, detailedSignal, Quark(), receiver, 0, 0);
300 }
301 
302 template <typename T>
303 inline bool disconnect(void *instance, const char *detailedSignal, void *receiver, T slot)
304 {
305  return Private::disconnect(instance, detailedSignal, Quark(), receiver, Private::hashMfp(slot), 0);
306 }
307 
308 #endif //DOXYGEN_RUN
309 
310 } //namespace QGlib
311 
312 #if !QGLIB_HAVE_CXX0X
313 //boost::bind restricts us to 9 arguments. if you need more,
314 //consider using a modern compiler with variadic template support ;)
315 # define QGLIB_CONNECT_MAX_ARGS 9
316 #endif
317 
318 #define IN_QGLIB_CONNECT_H
319 # include "connectimpl.h"
320 #undef IN_QGLIB_CONNECT_H
321 
322 #if defined(QGLIB_CONNECT_MAX_ARGS)
323 # undef QGLIB_CONNECT_MAX_ARGS
324 #endif
325 
326 #endif //QGLIB_CONNECT_H
Wrappers for Glib and GObject classes.
bool disconnect(void *instance, const char *detailedSignal=0, T *receiver=0, R(T::*slot)(Args...)=0)
bool connect(void *instance, const char *detailedSignal, T *receiver, R(T::*slot)(Args...), ConnectFlags flags=0)
Definition: connectimpl.h:188
ConnectFlag
Definition: connect.h:38
@ PassSender
Definition: connect.h:52
@ ConnectAfter
Definition: connect.h:44