QtGStreamer  1.2.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Pages
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 #include <boost/type_traits.hpp>
29 #include <boost/utility/enable_if.hpp>
30 
31 namespace QGlib {
32 
36 enum ConnectFlag { //codegen: skip=true
51 };
52 Q_DECLARE_FLAGS(ConnectFlags, ConnectFlag);
53 Q_DECLARE_OPERATORS_FOR_FLAGS(ConnectFlags)
54 
55 #if defined(DOXYGEN_RUN)
56 
134 template <typename T, typename R, typename... Args>
135 bool connect(void *instance, const char *detailedSignal,
136  T *receiver, R (T::*slot)(Args...), ConnectFlags flags = 0);
137 
138 //Fake disconnect() declaration.
139 //Doxygen should document a version with optional arguments. In reality we have to use
140 //two versions to avoid having to type the template parameters in case the user wants
141 //to use NULL for the receiver and slot arguments. Also, a version that takes void*
142 //for everything is not possible since member function pointers do not cast to void*.
143 
190 template <typename T, typename R, typename... Args>
191 bool disconnect(void *instance, const char *detailedSignal = 0,
192  T *receiver = 0, R (T::*slot)(Args...) = 0);
193 
194 #else //DOXYGEN_RUN
195 
196 namespace Private {
197 
198 //BEGIN ******** ClosureDataBase ********
199 
200 class QTGLIB_EXPORT ClosureDataBase
201 {
202 public:
203  inline virtual ~ClosureDataBase() {}
204  virtual void marshaller(Value &, const QList<Value> &) = 0;
205 
206  bool passSender; //whether to pass the sender instance as the first slot argument
207 
208 protected:
209  inline ClosureDataBase(bool passSender)
210  : passSender(passSender) {}
211 };
212 
213 //END ******** ClosureDataBase ********
214 
215 
216 /* This interface specifies the methods that will be used to connect/disconnect a
217  * signal receiver to/from a slot that should be called when the receiver is destroyed.
218  * This notification is used to disconnect the signal automatically.
219  */
220 class QTGLIB_EXPORT DestroyNotifierIface
221 {
222 public:
223  virtual ~DestroyNotifierIface() {}
224  virtual bool connect(void *receiver, QObject *notificationReceiver, const char *slot) = 0;
225  virtual bool disconnect(void *receiver, QObject *notificationReceiver) = 0;
226 };
227 
228 typedef QSharedPointer<DestroyNotifierIface> DestroyNotifierIfacePtr;
229 
230 /* This is DestroyNotifierIface that works for signal receivers that inherit QObject. */
231 class QTGLIB_EXPORT QObjectDestroyNotifier : public DestroyNotifierIface
232 {
233 public:
234  static DestroyNotifierIfacePtr instance();
235 
236  virtual bool connect(void *receiver, QObject *notificationReceiver, const char *slot);
237  virtual bool disconnect(void *receiver, QObject *notificationReceiver);
238 };
239 
240 /* This is provided for future expansion.
241  * It should implement operator DestroyNotifierIfacePtr() and return
242  * the appropriate DestroyNotifierIface for the given type T
243  * (i.e. the signal receiver is of type T)
244  */
245 template <typename T, typename Enable = void>
246 struct GetDestroyNotifier
247 {
248 };
249 
250 /* Partial specialization for QObjects (T inherits QObject) */
251 template <typename T>
252 struct GetDestroyNotifier<T, typename boost::enable_if< boost::is_base_of<QObject, T> >::type>
253 {
254  inline operator DestroyNotifierIfacePtr() { return QObjectDestroyNotifier::instance(); }
255 };
256 
257 
258 /* This method is used internally from QGlib::connect(). */
259 QTGLIB_EXPORT ulong connect(void *instance, const char *signal, Quark detail,
260  void *receiver, const DestroyNotifierIfacePtr & notifier,
261  uint slotHash, ClosureDataBase *closureData, ConnectFlags flags);
262 
263 /* This method is used internally from QGlib::disconnect(). */
264 QTGLIB_EXPORT bool disconnect(void *instance, const char *signal, Quark detail,
265  void *receiver, uint slotHash, ulong handlerId);
266 
267 
268 /* This is a helper that returns a hash value for a member function pointer.
269  * Because of the nature of member function pointers, it is not possible to cast
270  * them to void* or any integral type and as a result we need to create a hash value
271  * of their data to be able to store them in the connections store. This value is
272  * only used for disconnection, so storing the real pointer is not necessary.
273  */
274 template <typename T>
275 inline typename boost::enable_if< boost::is_member_function_pointer<T>, uint >::type
276 hashMfp(const T & mfp)
277 {
278  const char *data = reinterpret_cast<const char*>(&mfp);
279  return qHash(QByteArray::fromRawData(data, sizeof(T)));
280 }
281 
282 template <typename T>
283 inline typename boost::enable_if< boost::is_integral<T>, uint >::type
284 hashMfp(const T & mfp)
285 {
286  Q_ASSERT(mfp == 0);
287  return 0;
288 }
289 
290 } //namespace Private
291 
292 
293 //The real QGlib::disconnect
294 
295 inline bool disconnect(void *instance, const char *detailedSignal = 0, void *receiver = 0)
296 {
297  return Private::disconnect(instance, detailedSignal, Quark(), receiver, 0, 0);
298 }
299 
300 template <typename T>
301 inline bool disconnect(void *instance, const char *detailedSignal, void *receiver, T slot)
302 {
303  return Private::disconnect(instance, detailedSignal, Quark(), receiver, Private::hashMfp(slot), 0);
304 }
305 
306 #endif //DOXYGEN_RUN
307 
308 } //namespace QGlib
309 
310 #if !QGLIB_HAVE_CXX0X
311 //boost::bind restricts us to 9 arguments. if you need more,
312 //consider using a modern compiler with variadic template support ;)
313 # define QGLIB_CONNECT_MAX_ARGS 9
314 #endif
315 
316 #define IN_QGLIB_CONNECT_H
317 # include "connectimpl.h"
318 #undef IN_QGLIB_CONNECT_H
319 
320 #if defined(QGLIB_CONNECT_MAX_ARGS)
321 # undef QGLIB_CONNECT_MAX_ARGS
322 #endif
323 
324 #endif //QGLIB_CONNECT_H
ConnectFlag
Definition: connect.h:36
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:186