From ab59a7ef09d56e59f9496ac59d88ba05db61e298 Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Fri, 12 Oct 2012 12:20:40 +0200 Subject: Add private API to connect to slots in QObjectPrivate Change-Id: I16ffbf91ff4c6e9fca6fe7984800d2c24e70701b Reviewed-by: Thiago Macieira --- src/corelib/kernel/qobject_p.h | 77 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) (limited to 'src/corelib/kernel') diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h index e4b4ce8b42..e849ec1599 100644 --- a/src/corelib/kernel/qobject_p.h +++ b/src/corelib/kernel/qobject_p.h @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Copyright (C) 2013 Olivier Goffart ** Contact: http://www.qt-project.org/legal ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -198,6 +199,14 @@ public: inline void connectNotify(const QMetaMethod &signal); inline void disconnectNotify(const QMetaMethod &signal); + template + static inline QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer::Object *sender, Func1 signal, + const typename QtPrivate::FunctionPointer::Object *receiverPrivate, Func2 slot, + Qt::ConnectionType type = Qt::AutoConnection); + + template + static inline bool disconnect(const typename QtPrivate::FunctionPointer::Object *sender, Func1 signal, + const typename QtPrivate::FunctionPointer::Object *receiverPrivate, Func2 slot); public: ExtraData *extraData; // extra data set by the user QThreadData *threadData; // id of the thread that owns the object @@ -267,6 +276,74 @@ inline void QObjectPrivate::disconnectNotify(const QMetaMethod &signal) q_ptr->disconnectNotify(signal); } +namespace QtPrivate { +template class QPrivateSlotObject : public QSlotObjectBase +{ + typedef QtPrivate::FunctionPointer FuncType; + Func function; + static void impl(int which, QSlotObjectBase *this_, QObject *r, void **a, bool *ret) + { + switch (which) { + case Destroy: + delete static_cast(this_); + break; + case Call: + FuncType::template call(static_cast(this_)->function, + static_cast(QObjectPrivate::get(r)), a); + break; + case Compare: + *ret = *reinterpret_cast(a) == static_cast(this_)->function; + break; + case NumOperations: ; + } + } +public: + explicit QPrivateSlotObject(Func f) : QSlotObjectBase(&impl), function(f) {} +}; +} //namespace QtPrivate + +template +inline QMetaObject::Connection QObjectPrivate::connect(const typename QtPrivate::FunctionPointer::Object *sender, Func1 signal, + const typename QtPrivate::FunctionPointer::Object *receiverPrivate, Func2 slot, + Qt::ConnectionType type) +{ + typedef QtPrivate::FunctionPointer SignalType; + typedef QtPrivate::FunctionPointer SlotType; + reinterpret_cast(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast(0)); + + //compilation error if the arguments does not match. + Q_STATIC_ASSERT_X(int(SignalType::ArgumentCount) >= int(SlotType::ArgumentCount), + "The slot requires more arguments than the signal provides."); + Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments::value), + "Signal and slot arguments are not compatible."); + Q_STATIC_ASSERT_X((QtPrivate::AreArgumentsCompatible::value), + "Return type of the slot is not compatible with the return type of the signal."); + + const int *types = 0; + if (type == Qt::QueuedConnection || type == Qt::BlockingQueuedConnection) + types = QtPrivate::ConnectionTypes::types(); + + return QObject::connectImpl(sender, reinterpret_cast(&signal), + receiverPrivate->q_func(), reinterpret_cast(&slot), + new QtPrivate::QPrivateSlotObject::Value, + typename SignalType::ReturnType>(slot), + type, types, &SignalType::Object::staticMetaObject); +} + +template +bool QObjectPrivate::disconnect(const typename QtPrivate::FunctionPointer< Func1 >::Object* sender, Func1 signal, + const typename QtPrivate::FunctionPointer< Func2 >::Object* receiverPrivate, Func2 slot) +{ + typedef QtPrivate::FunctionPointer SignalType; + typedef QtPrivate::FunctionPointer SlotType; + reinterpret_cast(0)->qt_check_for_QOBJECT_macro(*reinterpret_cast(0)); + //compilation error if the arguments does not match. + Q_STATIC_ASSERT_X((QtPrivate::CheckCompatibleArguments::value), + "Signal and slot arguments are not compatible."); + return QObject::disconnectImpl(sender, reinterpret_cast(&signal), + receiverPrivate->q_func(), reinterpret_cast(&slot), + &SignalType::Object::staticMetaObject); +} Q_DECLARE_TYPEINFO(QObjectPrivate::Connection, Q_MOVABLE_TYPE); Q_DECLARE_TYPEINFO(QObjectPrivate::Sender, Q_MOVABLE_TYPE); -- cgit v1.2.3