QSignalSpy: share more code
Add per-ctor verify() functions that take care of the warnings for invalid inputs, and return a struct { QObject*; QMetaMethod; } to feed into a delegatee constructor. This solves the problem that the varying parts between the ctors are at the beginning, not the end, using another level of indirection, and will eventually allow to make the `args` and `sig` members const, and therefore remove the need to protect either with the mutex. This patch tries to keep the diff minimal. I'm planning to de-inline most of the class in a future commit, so it doesn't matter that private and public sections are interleaved, that will be cleaned up when the code is moved to a .cpp file later. Task-number: QTBUG-123544 Change-Id: Idc628c927736880a8fd580089ed5177361c94ed9 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
parent
12a432c80f
commit
e68edd6a07
@ -19,20 +19,29 @@ class QVariant;
|
||||
|
||||
class QSignalSpy: public QObject, public QList<QList<QVariant> >
|
||||
{
|
||||
struct ObjectSignal {
|
||||
const QObject *obj;
|
||||
QMetaMethod sig;
|
||||
};
|
||||
|
||||
public:
|
||||
explicit QSignalSpy(const QObject *obj, const char *aSignal)
|
||||
: QSignalSpy(verify(obj, aSignal)) {}
|
||||
|
||||
private:
|
||||
ObjectSignal verify(const QObject *obj, const char *aSignal)
|
||||
{
|
||||
if (!isObjectValid(obj))
|
||||
return;
|
||||
return {};
|
||||
|
||||
if (!aSignal) {
|
||||
qWarning("QSignalSpy: Null signal name is not valid");
|
||||
return;
|
||||
return {};
|
||||
}
|
||||
|
||||
if (((aSignal[0] - '0') & 0x03) != QSIGNAL_CODE) {
|
||||
qWarning("QSignalSpy: Not a valid signal, use the SIGNAL macro");
|
||||
return;
|
||||
return {};
|
||||
}
|
||||
|
||||
const QByteArray ba = QMetaObject::normalizedSignature(aSignal + 1);
|
||||
@ -40,38 +49,52 @@ public:
|
||||
const int sigIndex = mo->indexOfMethod(ba.constData());
|
||||
if (sigIndex < 0) {
|
||||
qWarning("QSignalSpy: No such signal: '%s'", ba.constData());
|
||||
return;
|
||||
return {};
|
||||
}
|
||||
|
||||
init(obj, mo->method(sigIndex));
|
||||
return verify(obj, mo->method(sigIndex));
|
||||
}
|
||||
|
||||
public:
|
||||
#ifdef Q_QDOC
|
||||
template <typename PointerToMemberFunction>
|
||||
QSignalSpy(const QObject *object, PointerToMemberFunction signal);
|
||||
#else
|
||||
template <typename Func>
|
||||
QSignalSpy(const typename QtPrivate::FunctionPointer<Func>::Object *obj, Func signal0)
|
||||
: QSignalSpy(verify(obj, signal0)) {}
|
||||
|
||||
private:
|
||||
template <typename Func>
|
||||
ObjectSignal verify(const QObject *obj, Func signal0)
|
||||
{
|
||||
if (!isObjectValid(obj))
|
||||
return;
|
||||
return {};
|
||||
|
||||
if (!signal0) {
|
||||
qWarning("QSignalSpy: Null signal pointer is not valid");
|
||||
return;
|
||||
return {};
|
||||
}
|
||||
|
||||
const QMetaMethod signalMetaMethod = QMetaMethod::fromSignal(signal0);
|
||||
init(obj, signalMetaMethod);
|
||||
return verify(obj, signalMetaMethod);
|
||||
}
|
||||
public:
|
||||
#endif // Q_QDOC
|
||||
|
||||
QSignalSpy(const QObject *obj, QMetaMethod signal)
|
||||
: QSignalSpy(verify(obj, signal)) {}
|
||||
|
||||
private:
|
||||
ObjectSignal verify(const QObject *obj, QMetaMethod signal)
|
||||
{
|
||||
if (isObjectValid(obj))
|
||||
init(obj, signal);
|
||||
return {obj, signal};
|
||||
else
|
||||
return {};
|
||||
}
|
||||
|
||||
public:
|
||||
inline bool isValid() const { return !sig.isEmpty(); }
|
||||
inline QByteArray signal() const { return sig; }
|
||||
|
||||
@ -109,6 +132,13 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
explicit QSignalSpy(ObjectSignal os)
|
||||
{
|
||||
if (!os.obj)
|
||||
return;
|
||||
init(os.obj, os.sig);
|
||||
}
|
||||
|
||||
void init(const QObject *obj, QMetaMethod signal)
|
||||
{
|
||||
if (!isSignalMetaMethodValid(signal))
|
||||
|
Loading…
x
Reference in New Issue
Block a user