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 #include "global.h"
00023 #include "quark.h"
00024 #include <QtCore/QObject>
00025 #include <QtCore/QSharedPointer>
00026 #include <QtCore/QFlags>
00027 #include <QtCore/QHash>
00028 #include <boost/type_traits.hpp>
00029 #include <boost/utility/enable_if.hpp>
00030
00031 namespace QGlib {
00032
00036 enum ConnectFlag {
00042 ConnectAfter = 1,
00050 PassSender = 2
00051 };
00052 Q_DECLARE_FLAGS(ConnectFlags, ConnectFlag);
00053 Q_DECLARE_OPERATORS_FOR_FLAGS(ConnectFlags)
00054
00055 #if defined(DOXYGEN_RUN)
00056
00134 template <typename T, typename R, typename... Args>
00135 bool connect(void *instance, const char *detailedSignal,
00136 T *receiver, R (T::*slot)(Args...), ConnectFlags flags = 0);
00137
00138
00139
00140
00141
00142
00143
00190 template <typename T, typename R, typename... Args>
00191 bool disconnect(void *instance, const char *detailedSignal = 0,
00192 T *receiver = 0, R (T::*slot)(Args...) = 0);
00193
00194 #else //DOXYGEN_RUN
00195
00196 namespace Private {
00197
00198
00199
00200 class QTGLIB_EXPORT ClosureDataBase
00201 {
00202 public:
00203 inline virtual ~ClosureDataBase() {}
00204 virtual void marshaller(Value &, const QList<Value> &) = 0;
00205
00206 bool passSender;
00207
00208 protected:
00209 inline ClosureDataBase(bool passSender)
00210 : passSender(passSender) {}
00211 };
00212
00213
00214
00215
00216
00217
00218
00219
00220 class QTGLIB_EXPORT DestroyNotifierIface
00221 {
00222 public:
00223 virtual ~DestroyNotifierIface() {}
00224 virtual bool connect(void *receiver, QObject *notificationReceiver, const char *slot) = 0;
00225 virtual bool disconnect(void *receiver, QObject *notificationReceiver) = 0;
00226 };
00227
00228 typedef QSharedPointer<DestroyNotifierIface> DestroyNotifierIfacePtr;
00229
00230
00231 class QTGLIB_EXPORT QObjectDestroyNotifier : public DestroyNotifierIface
00232 {
00233 public:
00234 static DestroyNotifierIfacePtr instance();
00235
00236 virtual bool connect(void *receiver, QObject *notificationReceiver, const char *slot);
00237 virtual bool disconnect(void *receiver, QObject *notificationReceiver);
00238 };
00239
00240
00241
00242
00243
00244
00245 template <typename T, typename Enable = void>
00246 struct GetDestroyNotifier
00247 {
00248 };
00249
00250
00251 template <typename T>
00252 struct GetDestroyNotifier<T, typename boost::enable_if< boost::is_base_of<QObject, T> >::type>
00253 {
00254 inline operator DestroyNotifierIfacePtr() { return QObjectDestroyNotifier::instance(); }
00255 };
00256
00257
00258
00259 QTGLIB_EXPORT ulong connect(void *instance, const char *signal, Quark detail,
00260 void *receiver, const DestroyNotifierIfacePtr & notifier,
00261 uint slotHash, ClosureDataBase *closureData, ConnectFlags flags);
00262
00263
00264 QTGLIB_EXPORT bool disconnect(void *instance, const char *signal, Quark detail,
00265 void *receiver, uint slotHash, ulong handlerId);
00266
00267
00268
00269
00270
00271
00272
00273
00274 template <typename T>
00275 inline typename boost::enable_if< boost::is_member_function_pointer<T>, uint >::type
00276 hashMfp(const T & mfp)
00277 {
00278 const char *data = reinterpret_cast<const char*>(&mfp);
00279 return qHash(QByteArray::fromRawData(data, sizeof(T)));
00280 }
00281
00282 template <typename T>
00283 inline typename boost::enable_if< boost::is_integral<T>, uint >::type
00284 hashMfp(const T & mfp)
00285 {
00286 Q_ASSERT(mfp == 0);
00287 return 0;
00288 }
00289
00290 }
00291
00292
00293
00294
00295 inline bool disconnect(void *instance, const char *detailedSignal = 0, void *receiver = 0)
00296 {
00297 return Private::disconnect(instance, detailedSignal, Quark(), receiver, 0, 0);
00298 }
00299
00300 template <typename T>
00301 inline bool disconnect(void *instance, const char *detailedSignal, void *receiver, T slot)
00302 {
00303 return Private::disconnect(instance, detailedSignal, Quark(), receiver, Private::hashMfp(slot), 0);
00304 }
00305
00306 #endif //DOXYGEN_RUN
00307
00308 }
00309
00310 #if !QGLIB_HAVE_CXX0X
00311
00312
00313 # define QGLIB_CONNECT_MAX_ARGS 9
00314 #endif
00315
00316 #define IN_QGLIB_CONNECT_H
00317 # include "connectimpl.h"
00318 #undef IN_QGLIB_CONNECT_H
00319
00320 #if defined(QGLIB_CONNECT_MAX_ARGS)
00321 # undef QGLIB_CONNECT_MAX_ARGS
00322 #endif
00323
00324 #endif //QGLIB_CONNECT_H