00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef QGLIB_CONNECT_H
00020 #define QGLIB_CONNECT_H
00021
00022 #ifdef Q_MOC_RUN
00023 #define BOOST_TT_HAS_OPERATOR_HPP_INCLUDED
00024 #endif
00025
00026
00027 #include "global.h"
00028 #include "quark.h"
00029 #include <QtCore/QObject>
00030 #include <QtCore/QSharedPointer>
00031 #include <QtCore/QFlags>
00032 #include <QtCore/QHash>
00033 #include <boost/type_traits.hpp>
00034 #include <boost/utility/enable_if.hpp>
00035
00036 namespace QGlib {
00037
00041 enum ConnectFlag {
00047 ConnectAfter = 1,
00055 PassSender = 2
00056 };
00057 Q_DECLARE_FLAGS(ConnectFlags, ConnectFlag);
00058 Q_DECLARE_OPERATORS_FOR_FLAGS(ConnectFlags)
00059
00060 #if defined(DOXYGEN_RUN)
00061
00139 template <typename T, typename R, typename... Args>
00140 bool connect(void *instance, const char *detailedSignal,
00141 T *receiver, R (T::*slot)(Args...), ConnectFlags flags = 0);
00142
00143
00144
00145
00146
00147
00148
00195 template <typename T, typename R, typename... Args>
00196 bool disconnect(void *instance, const char *detailedSignal = 0,
00197 T *receiver = 0, R (T::*slot)(Args...) = 0);
00198
00199 #else //DOXYGEN_RUN
00200
00201 namespace Private {
00202
00203
00204
00205 class QTGLIB_EXPORT ClosureDataBase
00206 {
00207 public:
00208 inline virtual ~ClosureDataBase() {}
00209 virtual void marshaller(Value &, const QList<Value> &) = 0;
00210
00211 bool passSender;
00212
00213 protected:
00214 inline ClosureDataBase(bool passSender)
00215 : passSender(passSender) {}
00216 };
00217
00218
00219
00220
00221
00222
00223
00224
00225 class QTGLIB_EXPORT DestroyNotifierIface
00226 {
00227 public:
00228 virtual ~DestroyNotifierIface() {}
00229 virtual bool connect(void *receiver, QObject *notificationReceiver, const char *slot) = 0;
00230 virtual bool disconnect(void *receiver, QObject *notificationReceiver) = 0;
00231 };
00232
00233 typedef QSharedPointer<DestroyNotifierIface> DestroyNotifierIfacePtr;
00234
00235
00236 class QTGLIB_EXPORT QObjectDestroyNotifier : public DestroyNotifierIface
00237 {
00238 public:
00239 static DestroyNotifierIfacePtr instance();
00240
00241 virtual bool connect(void *receiver, QObject *notificationReceiver, const char *slot);
00242 virtual bool disconnect(void *receiver, QObject *notificationReceiver);
00243 };
00244
00245
00246
00247
00248
00249
00250 template <typename T, typename Enable = void>
00251 struct GetDestroyNotifier
00252 {
00253 };
00254
00255
00256 template <typename T>
00257 struct GetDestroyNotifier<T, typename boost::enable_if< boost::is_base_of<QObject, T> >::type>
00258 {
00259 inline operator DestroyNotifierIfacePtr() { return QObjectDestroyNotifier::instance(); }
00260 };
00261
00262
00263
00264 QTGLIB_EXPORT ulong connect(void *instance, const char *signal, Quark detail,
00265 void *receiver, const DestroyNotifierIfacePtr & notifier,
00266 uint slotHash, ClosureDataBase *closureData, ConnectFlags flags);
00267
00268
00269 QTGLIB_EXPORT bool disconnect(void *instance, const char *signal, Quark detail,
00270 void *receiver, uint slotHash, ulong handlerId);
00271
00272
00273
00274
00275
00276
00277
00278
00279 template <typename T>
00280 inline typename boost::enable_if< boost::is_member_function_pointer<T>, uint >::type
00281 hashMfp(const T & mfp)
00282 {
00283 const char *data = reinterpret_cast<const char*>(&mfp);
00284 return qHash(QByteArray::fromRawData(data, sizeof(T)));
00285 }
00286
00287 template <typename T>
00288 inline typename boost::enable_if< boost::is_integral<T>, uint >::type
00289 hashMfp(const T & mfp)
00290 {
00291 Q_ASSERT(mfp == 0);
00292 return 0;
00293 }
00294
00295 }
00296
00297
00298
00299
00300 inline bool disconnect(void *instance, const char *detailedSignal = 0, void *receiver = 0)
00301 {
00302 return Private::disconnect(instance, detailedSignal, Quark(), receiver, 0, 0);
00303 }
00304
00305 template <typename T>
00306 inline bool disconnect(void *instance, const char *detailedSignal, void *receiver, T slot)
00307 {
00308 return Private::disconnect(instance, detailedSignal, Quark(), receiver, Private::hashMfp(slot), 0);
00309 }
00310
00311 #endif //DOXYGEN_RUN
00312
00313 }
00314
00315 #if !QGLIB_HAVE_CXX0X
00316
00317
00318 # define QGLIB_CONNECT_MAX_ARGS 9
00319 #endif
00320
00321 #define IN_QGLIB_CONNECT_H
00322 # include "connectimpl.h"
00323 #undef IN_QGLIB_CONNECT_H
00324
00325 #if defined(QGLIB_CONNECT_MAX_ARGS)
00326 # undef QGLIB_CONNECT_MAX_ARGS
00327 #endif
00328
00329 #endif //QGLIB_CONNECT_H