QtGStreamer 1.2.0
Loading...
Searching...
No Matches
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
33namespace QGlib {
34
38enum ConnectFlag { //codegen: skip=true
52 PassSender = 2
53};
54Q_DECLARE_FLAGS(ConnectFlags, ConnectFlag);
55Q_DECLARE_OPERATORS_FOR_FLAGS(ConnectFlags)
56
57#if defined(DOXYGEN_RUN)
58
136template <typename T, typename R, typename... Args>
137bool 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
192template <typename T, typename R, typename... Args>
193bool disconnect(void *instance, const char *detailedSignal = 0,
194 T *receiver = 0, R (T::*slot)(Args...) = 0);
195
196#else //DOXYGEN_RUN
197
198namespace Private {
199
200//BEGIN ******** ClosureDataBase ********
201
202class QTGLIB_EXPORT ClosureDataBase
203{
204public:
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
210protected:
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 */
222class QTGLIB_EXPORT DestroyNotifierIface
223{
224public:
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
230typedef QSharedPointer<DestroyNotifierIface> DestroyNotifierIfacePtr;
231
232/* This is DestroyNotifierIface that works for signal receivers that inherit QObject. */
233class QTGLIB_EXPORT QObjectDestroyNotifier : public DestroyNotifierIface
234{
235public:
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 */
247template <typename T, typename Enable = void>
248struct GetDestroyNotifier
249{
250};
251
252/* Partial specialization for QObjects (T inherits QObject) */
253template <typename T>
254struct 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(). */
261QTGLIB_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(). */
266QTGLIB_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 */
276template <typename T>
277inline typename boost::enable_if< boost::is_member_function_pointer<T>, uint >::type
278hashMfp(const T & mfp)
279{
280 const char *data = reinterpret_cast<const char*>(&mfp);
281 return qHash(QByteArray::fromRawData(data, sizeof(T)));
282}
283
284template <typename T>
285inline typename boost::enable_if< boost::is_integral<T>, uint >::type
286hashMfp(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
297inline bool disconnect(void *instance, const char *detailedSignal = 0, void *receiver = 0)
298{
299 return Private::disconnect(instance, detailedSignal, Quark(), receiver, 0, 0);
300}
301
302template <typename T>
303inline 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
Wrapper class for GQuark.
Definition quark.h:43
Wrapper class for GValue.
Definition value.h:77
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)
ConnectFlag
Definition connect.h:38
@ PassSender
Definition connect.h:52
@ ConnectAfter
Definition connect.h:44