Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2023-11-27 08:39:39 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2023-11-28 14:23:42 +0100
commit782c0757f43651e25f17cd28cda07f8293c3c107 (patch)
treeecda19d4e68c577ae2d7aae4e4ed9b3e33aa1dde /sources/pyside6/libpyside/pysidesignal.cpp
parente79aea5bdb30b88c84e92ab91366c9c0274ea21d (diff)
libpyside: Avoid parsing signatures in Signal.connect()
Store the argument count as obtained from QMetaMethod or Signal argument parsing via PySideSignalData::Signature in PySideSignalInstancePrivate and use that to find a matching slot instead of parsing the signature. Task-number: PYSIDE-2524 Change-Id: I7c30bd1ee7873b4d13c40e0a91a4ace9026890a2 Reviewed-by: Shyamnath Premnadh <Shyamnath.Premnadh@qt.io>
Diffstat (limited to 'sources/pyside6/libpyside/pysidesignal.cpp')
-rw-r--r--sources/pyside6/libpyside/pysidesignal.cpp45
1 files changed, 21 insertions, 24 deletions
diff --git a/sources/pyside6/libpyside/pysidesignal.cpp b/sources/pyside6/libpyside/pysidesignal.cpp
index 953962641..4039aaffe 100644
--- a/sources/pyside6/libpyside/pysidesignal.cpp
+++ b/sources/pyside6/libpyside/pysidesignal.cpp
@@ -448,6 +448,16 @@ static int argCount(const FunctionArgumentsResult &args)
? -1 : PepCode_GET_ARGCOUNT(args.objCode);
}
+// Find Signal Instance for argument count.
+static PySideSignalInstance *findSignalInstance(PySideSignalInstance *source, int argCount)
+{
+ for (auto *si = source; si != nullptr; si = si->d->next) {
+ if (si->d->argCount == argCount)
+ return si;
+ }
+ return nullptr;
+}
+
static PyObject *signalInstanceConnect(PyObject *self, PyObject *args, PyObject *kwds)
{
PyObject *slot = nullptr;
@@ -496,10 +506,8 @@ static PyObject *signalInstanceConnect(PyObject *self, PyObject *args, PyObject
}
} else {
// Check signature of the slot (method or function) to match signal
- bool matchedSlot = false;
-
- PySideSignalInstance *it = source;
const auto args = extractFunctionArgumentsFromSlot(slot);
+ PySideSignalInstance *matchedSlot = nullptr;
if (args.function != nullptr) {
qsizetype slotArgs = argCount(args);
@@ -507,34 +515,18 @@ static PyObject *signalInstanceConnect(PyObject *self, PyObject *args, PyObject
slotArgs -= 1;
// Get signature args
- bool isShortCircuit = false;
- QByteArrayList argsSignature = PySide::Signal::getArgsFromSignature(it->d->signature,
- &isShortCircuit);
- qsizetype signatureArgs = argsSignature.size();
-
// Iterate the possible types of connection for this signal and compare
// it with slot arguments
- if (signatureArgs != slotArgs) {
- while (it->d->next != nullptr) {
- it = it->d->next;
- argsSignature = PySide::Signal::getArgsFromSignature(it->d->signature,
- &isShortCircuit);
- signatureArgs = argsSignature.size();
- if (signatureArgs == slotArgs) {
- matchedSlot = true;
- break;
- }
- }
- }
+ matchedSlot = findSignalInstance(source, slotArgs);
}
// Adding references to pyArgs
PyList_Append(pyArgs, source->d->source);
- if (matchedSlot) {
+ if (matchedSlot != nullptr) {
// If a slot matching the same number of arguments was found,
// include signature to the pyArgs
- Shiboken::AutoDecRef signature(PySide::Signal::buildQtCompatible(it->d->signature));
+ Shiboken::AutoDecRef signature(PySide::Signal::buildQtCompatible(matchedSlot->d->signature));
PyList_Append(pyArgs, signature);
} else {
// Try the first by default if the slot was not found
@@ -964,9 +956,10 @@ static QByteArray buildSignature(const QByteArray &name, const QByteArray &signa
static PySideSignalData::Signature parseSignature(PyObject *args)
{
- PySideSignalData::Signature result{{}, QMetaMethod::Compatibility};
+ PySideSignalData::Signature result{{}, QMetaMethod::Compatibility, 0};
if (args && (Shiboken::String::check(args) || !PyTuple_Check(args))) {
result.signature = getTypeName(args);
+ result.argCount = 1;
return result;
}
@@ -977,6 +970,7 @@ static PySideSignalData::Signature parseSignature(PyObject *args)
if (!result.signature.isEmpty())
result.signature += ',';
result.signature += typeName;
+ ++result.argCount;
}
}
return result;
@@ -1001,6 +995,7 @@ static void instanceInitialize(PySideSignalInstance *self, PyObject *name, PySid
selfPvt->source = source;
const auto &signature = signal->data->signatures.at(index);
selfPvt->signature = buildSignature(self->d->signalName, signature.signature);
+ selfPvt->argCount = signature.argCount;
selfPvt->attributes = signature.attributes;
selfPvt->homonymousMethod = nullptr;
if (signal->homonymousMethod) {
@@ -1078,6 +1073,7 @@ PySideSignalInstance *newObjectFromMethod(PyObject *source, const QList<QMetaMet
// separate SignalName
selfPvt->signalName = cppName;
selfPvt->signature = m.methodSignature();
+ selfPvt->argCount = int(m.parameterCount());
selfPvt->attributes = m.attributes();
selfPvt->homonymousMethod = nullptr;
selfPvt->next = nullptr;
@@ -1121,7 +1117,8 @@ void registerSignals(PyTypeObject *pyObj, const QMetaObject *metaObject)
if (method.methodType() == QMetaMethod::Signal) {
QByteArray methodName(method.methodSignature());
methodName.chop(methodName.size() - methodName.indexOf('('));
- Signature signature{method.parameterTypes().join(','), {}};
+ Signature signature{method.parameterTypes().join(','), {},
+ short(method.parameterCount())};
if (method.attributes() & QMetaMethod::Cloned)
signature.attributes = QMetaMethod::Cloned;
signalsFound[methodName] << signature;