QtGStreamer 0.10.1
|
00001 /* 00002 Copyright (C) 2010 George Kiagiadakis <kiagiadakis.george@gmail.com> 00003 Copyright (C) 2010 Collabora Ltd. 00004 @author George Kiagiadakis <george.kiagiadakis@collabora.co.uk> 00005 00006 This library is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU Lesser General Public License as published 00008 by the Free Software Foundation; either version 2.1 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU Lesser General Public License 00017 along with this program. If not, see <http://www.gnu.org/licenses/>. 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 { //codegen: skip=true 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 //Fake disconnect() declaration. 00139 //Doxygen should document a version with optional arguments. In reality we have to use 00140 //two versions to avoid having to type the template parameters in case the user wants 00141 //to use NULL for the receiver and slot arguments. Also, a version that takes void* 00142 //for everything is not possible since member function pointers do not cast to void*. 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 //BEGIN ******** ClosureDataBase ******** 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; //whether to pass the sender instance as the first slot argument 00207 00208 protected: 00209 inline ClosureDataBase(bool passSender) 00210 : passSender(passSender) {} 00211 }; 00212 00213 //END ******** ClosureDataBase ******** 00214 00215 00216 /* This interface specifies the methods that will be used to connect/disconnect a 00217 * signal receiver to/from a slot that should be called when the receiver is destroyed. 00218 * This notification is used to disconnect the signal automatically. 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 /* This is DestroyNotifierIface that works for signal receivers that inherit QObject. */ 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 /* This is provided for future expansion. 00241 * It should implement operator DestroyNotifierIfacePtr() and return 00242 * the appropriate DestroyNotifierIface for the given type T 00243 * (i.e. the signal receiver is of type T) 00244 */ 00245 template <typename T, typename Enable = void> 00246 struct GetDestroyNotifier 00247 { 00248 }; 00249 00250 /* Partial specialization for QObjects (T inherits QObject) */ 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 /* This method is used internally from QGlib::connect(). */ 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 /* This method is used internally from QGlib::disconnect(). */ 00264 QTGLIB_EXPORT bool disconnect(void *instance, const char *signal, Quark detail, 00265 void *receiver, uint slotHash, ulong handlerId); 00266 00267 00268 /* This is a helper that returns a hash value for a member function pointer. 00269 * Because of the nature of member function pointers, it is not possible to cast 00270 * them to void* or any integral type and as a result we need to create a hash value 00271 * of their data to be able to store them in the connections store. This value is 00272 * only used for disconnection, so storing the real pointer is not necessary. 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 } //namespace Private 00291 00292 00293 //The real QGlib::disconnect 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 } //namespace QGlib 00309 00310 #if !QGLIB_HAVE_CXX0X 00311 //boost::bind restricts us to 9 arguments. if you need more, 00312 //consider using a modern compiler with variadic template support ;) 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