summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/kernel/qobject.cpp32
-rw-r--r--src/corelib/kernel/qobject.h56
-rw-r--r--src/corelib/kernel/qobject_impl.h98
-rw-r--r--src/corelib/kernel/qobject_p.h6
4 files changed, 120 insertions, 72 deletions
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index a00d528ec9..6ac29879b9 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -72,6 +72,11 @@ QT_BEGIN_NAMESPACE
static int DIRECT_CONNECTION_ONLY = 0;
+struct QSlotObjectBaseDeleter { // for use with QScopedPointer<QSlotObjectBase,...>
+ static void cleanup(QtPrivate::QSlotObjectBase *slot) {
+ if (slot && !slot->ref.deref() ) slot->destroy();
+ }
+};
static int *queuedConnectionTypes(const QList<QByteArray> &typeNames)
{
int *types = new int [typeNames.count() + 1];
@@ -432,7 +437,7 @@ QMetaCallEvent::QMetaCallEvent(ushort method_offset, ushort method_relative, QOb
/*!
\internal
*/
-QMetaCallEvent::QMetaCallEvent(QObject::QSlotObjectBase *slotO, const QObject *sender, int signalId,
+QMetaCallEvent::QMetaCallEvent(QtPrivate::QSlotObjectBase *slotO, const QObject *sender, int signalId,
int nargs, int *types, void **args, QSemaphore *semaphore)
: QEvent(MetaCall), slotObj_(slotO), sender_(sender), signalId_(signalId),
nargs_(nargs), types_(types), args_(args), semaphore_(semaphore),
@@ -460,7 +465,7 @@ QMetaCallEvent::~QMetaCallEvent()
semaphore_->release();
#endif
if (slotObj_ && !slotObj_->ref.deref())
- delete slotObj_;
+ slotObj_->destroy();
}
/*!
@@ -864,7 +869,7 @@ QObjectPrivate::Connection::~Connection()
delete [] v;
}
if (isSlotObject && !slotObj->ref.deref())
- delete slotObj;
+ slotObj->destroy();
}
@@ -3412,7 +3417,8 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
const QObjectPrivate::StaticMetaCallFunction callFunction = c->callFunction;
const int method_relative = c->method_relative;
if (c->isSlotObject) {
- QExplicitlySharedDataPointer<QObject::QSlotObjectBase> obj(c->slotObj);
+ c->slotObj->ref.ref();
+ const QScopedPointer<QtPrivate::QSlotObjectBase, QSlotObjectBaseDeleter> obj(c->slotObj);
locker.unlock();
obj->call(receiver, argv ? argv : empty_argv);
locker.relock();
@@ -4185,13 +4191,13 @@ void qDeleteInEventHandler(QObject *o)
*/
QMetaObject::Connection QObject::connectImpl(const QObject *sender, void **signal,
const QObject *receiver, void **slot,
- QObject::QSlotObjectBase *slotObj, Qt::ConnectionType type,
+ QtPrivate::QSlotObjectBase *slotObj, Qt::ConnectionType type,
const int *types, const QMetaObject *senderMetaObject)
{
if (!sender || !signal || !slotObj || !senderMetaObject) {
qWarning("QObject::connect: invalid null parametter");
if (slotObj && !slotObj->ref.deref())
- delete slotObj;
+ slotObj->destroy();
return QMetaObject::Connection();
}
int signal_index = -1;
@@ -4200,7 +4206,7 @@ QMetaObject::Connection QObject::connectImpl(const QObject *sender, void **signa
if (signal_index < 0 || signal_index >= QMetaObjectPrivate::get(senderMetaObject)->signalCount) {
qWarning("QObject::connect: signal not found in %s", senderMetaObject->className());
if (!slotObj->ref.deref())
- delete slotObj;
+ slotObj->destroy();
return QMetaObject::Connection(0);
}
signal_index += QMetaObjectPrivate::signalOffset(senderMetaObject);
@@ -4220,7 +4226,7 @@ QMetaObject::Connection QObject::connectImpl(const QObject *sender, void **signa
while (c2) {
if (c2->receiver == receiver && c2->isSlotObject && c2->slotObj->compare(slot)) {
if (!slotObj->ref.deref())
- delete slotObj;
+ slotObj->destroy();
return QMetaObject::Connection();
}
c2 = c2->nextConnectionList;
@@ -4412,16 +4418,6 @@ QMetaObject::Connection::~Connection()
the signal or the slot, or if the arguments do not match.
*/
-QObject::QSlotObjectBase::~QSlotObjectBase()
-{
-}
-
-bool QObject::QSlotObjectBase::compare(void** )
-{
- return false;
-}
-
-
QT_END_NAMESPACE
#include "moc_qobject.cpp"
diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h
index 1d2d6a6794..ee157347ea 100644
--- a/src/corelib/kernel/qobject.h
+++ b/src/corelib/kernel/qobject.h
@@ -246,7 +246,7 @@ public:
return connectImpl(sender, reinterpret_cast<void **>(&signal),
receiver, reinterpret_cast<void **>(&slot),
- new QSlotObject<Func2, typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value,
+ new QtPrivate::QSlotObject<Func2, typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value,
typename SignalType::ReturnType>(slot),
type, types, &SignalType::Object::staticMetaObject);
}
@@ -268,7 +268,7 @@ public:
"Return type of the slot is not compatible with the return type of the signal.");
return connectImpl(sender, reinterpret_cast<void **>(&signal), sender, 0,
- new QStaticSlotObject<Func2,
+ new QtPrivate::QStaticSlotObject<Func2,
typename QtPrivate::List_Left<typename SignalType::Arguments, SlotType::ArgumentCount>::Value,
typename SignalType::ReturnType>(slot),
Qt::DirectConnection, 0, &SignalType::Object::staticMetaObject);
@@ -282,7 +282,7 @@ public:
typedef QtPrivate::FunctionPointer<Func1> SignalType;
return connectImpl(sender, reinterpret_cast<void **>(&signal), sender, 0,
- new QFunctorSlotObject<Func2, SignalType::ArgumentCount, typename SignalType::Arguments, typename SignalType::ReturnType>(slot),
+ new QtPrivate::QFunctorSlotObject<Func2, SignalType::ArgumentCount, typename SignalType::Arguments, typename SignalType::ReturnType>(slot),
Qt::DirectConnection, 0, &SignalType::Object::staticMetaObject);
}
#endif //Q_QDOC
@@ -394,56 +394,10 @@ private:
Q_DISABLE_COPY(QObject)
Q_PRIVATE_SLOT(d_func(), void _q_reregisterTimers(void *))
- private:
- // internal base class (interface) containing functions required to call a slot managed by a pointer to function.
- struct Q_CORE_EXPORT QSlotObjectBase {
- QAtomicInt ref;
- QSlotObjectBase() : ref(1) {}
- virtual ~QSlotObjectBase();
- virtual void call(QObject *receiver, void **a) = 0;
- virtual bool compare(void **);
- };
- // implementation of QSlotObjectBase for which the slot is a pointer to member function of a QObject
- // Args and R are the List of arguments and the returntype of the signal to which the slot is connected.
- template<typename Func, typename Args, typename R> struct QSlotObject : QSlotObjectBase
- {
- typedef QtPrivate::FunctionPointer<Func> FuncType;
- Func function;
- QSlotObject(Func f) : function(f) {}
- virtual void call(QObject *receiver, void **a) {
- FuncType::template call<Args, R>(function, static_cast<typename FuncType::Object *>(receiver), a);
- }
- virtual bool compare(void **f) {
- return *reinterpret_cast<Func *>(f) == function;
- }
- };
- // implementation of QSlotObjectBase for which the slot is a static function
- // Args and R are the List of arguments and the returntype of the signal to which the slot is connected.
- template<typename Func, typename Args, typename R> struct QStaticSlotObject : QSlotObjectBase
- {
- typedef QtPrivate::FunctionPointer<Func> FuncType;
- Func function;
- QStaticSlotObject(Func f) : function(f) {}
- virtual void call(QObject *receiver, void **a) {
- FuncType::template call<Args, R>(function, receiver, a);
- }
- };
- // implementation of QSlotObjectBase for which the slot is a functor (or lambda)
- // N is the number of arguments
- // Args and R are the List of arguments and the returntype of the signal to which the slot is connected.
- template<typename Func, int N, typename Args, typename R> struct QFunctorSlotObject : QSlotObjectBase
- {
- typedef QtPrivate::Functor<Func, N> FuncType;
- Func function;
- QFunctorSlotObject(const Func &f) : function(f) {}
- virtual void call(QObject *receiver, void **a) {
- FuncType::template call<Args, R>(function, receiver, a);
- }
- };
-
+private:
static QMetaObject::Connection connectImpl(const QObject *sender, void **signal,
const QObject *receiver, void **slotPtr,
- QSlotObjectBase *slot, Qt::ConnectionType type,
+ QtPrivate::QSlotObjectBase *slot, Qt::ConnectionType type,
const int *types, const QMetaObject *senderMetaObject);
static bool disconnectImpl(const QObject *sender, void **signal, const QObject *receiver, void **slot,
diff --git a/src/corelib/kernel/qobject_impl.h b/src/corelib/kernel/qobject_impl.h
index e016002afa..eeb64db0dd 100644
--- a/src/corelib/kernel/qobject_impl.h
+++ b/src/corelib/kernel/qobject_impl.h
@@ -99,6 +99,104 @@ namespace QtPrivate {
template <typename... Args> struct ConnectionTypes<List<Args...>, true>
{ static const int *types() { static const int t[sizeof...(Args) + 1] = { (QtPrivate::QMetaTypeIdHelper<Args>::qt_metatype_id())..., 0 }; return t; } };
#endif
+
+ // internal base class (interface) containing functions required to call a slot managed by a pointer to function.
+ struct QSlotObjectBase {
+ QAtomicInt ref;
+ // don't use virtual functions here; we don't want the
+ // compiler to create tons of per-polymorphic-class stuff that
+ // we'll never need. We just use one function pointer.
+ enum Operation {
+ Destroy,
+ Call,
+ Compare,
+
+ NumOperations
+ };
+ typedef bool (*ImplFn)(int which, QSlotObjectBase* this_, QObject *receiver, void **args);
+ const ImplFn impl;
+
+ explicit QSlotObjectBase(ImplFn fn) : ref(1), impl(fn) {} // ### make constexpr once QAtomicInt's ctor is, too
+ inline void destroy() { impl(Destroy, this, 0, 0); }
+ inline bool compare(void **a) { return impl(Compare, this, 0, a); }
+ inline void call(QObject *r, void **a) { impl(Call, this, r, a); }
+ protected:
+ ~QSlotObjectBase() {}
+ };
+ // implementation of QSlotObjectBase for which the slot is a pointer to member function of a QObject
+ // Args and R are the List of arguments and the returntype of the signal to which the slot is connected.
+ template<typename Func, typename Args, typename R> class QSlotObject : public QSlotObjectBase
+ {
+ typedef QtPrivate::FunctionPointer<Func> FuncType;
+ Func function;
+ static bool impl(int which, QSlotObjectBase *this_, QObject *r, void **a)
+ {
+ switch (which) {
+ case Destroy:
+ delete static_cast<QSlotObject*>(this_);
+ return true;
+ case Call:
+ FuncType::template call<Args, R>(static_cast<QSlotObject*>(this_)->function, static_cast<typename FuncType::Object *>(r), a);
+ return true;
+ case Compare:
+ return *reinterpret_cast<Func *>(a) == static_cast<QSlotObject*>(this_)->function;
+ case NumOperations: ;
+ }
+ return false;
+ }
+ public:
+ explicit QSlotObject(Func f) : QSlotObjectBase(&impl), function(f) {}
+ };
+ // implementation of QSlotObjectBase for which the slot is a static function
+ // Args and R are the List of arguments and the returntype of the signal to which the slot is connected.
+ template<typename Func, typename Args, typename R> class QStaticSlotObject : public QSlotObjectBase
+ {
+ typedef QtPrivate::FunctionPointer<Func> FuncType;
+ Func function;
+ static bool impl(int which, QSlotObjectBase *this_, QObject *r, void **a)
+ {
+ switch (which) {
+ case Destroy:
+ delete static_cast<QStaticSlotObject*>(this_);
+ return true;
+ case Call:
+ FuncType::template call<Args, R>(static_cast<QStaticSlotObject*>(this_)->function, r, a);
+ return true;
+ case Compare:
+ return false; // not implemented
+ case NumOperations: ;
+ }
+ return false;
+ }
+ public:
+ explicit QStaticSlotObject(Func f) : QSlotObjectBase(&impl), function(f) {}
+ };
+ // implementation of QSlotObjectBase for which the slot is a functor (or lambda)
+ // N is the number of arguments
+ // Args and R are the List of arguments and the returntype of the signal to which the slot is connected.
+ template<typename Func, int N, typename Args, typename R> class QFunctorSlotObject : public QSlotObjectBase
+ {
+ typedef QtPrivate::Functor<Func, N> FuncType;
+ Func function;
+ static bool impl(int which, QSlotObjectBase *this_, QObject *r, void **a)
+ {
+ switch (which) {
+ case Destroy:
+ delete static_cast<QFunctorSlotObject*>(this_);
+ return true;
+ case Call:
+ FuncType::template call<Args, R>(static_cast<QFunctorSlotObject*>(this_)->function, r, a);
+ return true;
+ case Compare:
+ return false; // not implemented
+ case NumOperations: ;
+ }
+ return false;
+ }
+ public:
+ explicit QFunctorSlotObject(const Func &f) : QSlotObjectBase(&impl), function(f) {}
+ };
+
}
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index 02580caf41..d47426b14c 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -120,7 +120,7 @@ public:
QObject *receiver;
union {
StaticMetaCallFunction callFunction;
- QObject::QSlotObjectBase *slotObj;
+ QtPrivate::QSlotObjectBase *slotObj;
};
// The next pointer for the singly-linked ConnectionList
Connection *nextConnectionList;
@@ -280,7 +280,7 @@ public:
/*! \internal
\a signalId is in the signal index range (see QObjectPrivate::signalIndex()).
*/
- QMetaCallEvent(QObject::QSlotObjectBase *slotObj, const QObject *sender, int signalId,
+ QMetaCallEvent(QtPrivate::QSlotObjectBase *slotObj, const QObject *sender, int signalId,
int nargs = 0, int *types = 0, void **args = 0, QSemaphore *semaphore = 0);
~QMetaCallEvent();
@@ -293,7 +293,7 @@ public:
virtual void placeMetaCall(QObject *object);
private:
- QObject::QSlotObjectBase *slotObj_;
+ QtPrivate::QSlotObjectBase *slotObj_;
const QObject *sender_;
int signalId_;
int nargs_;