@@ -915,16 +915,14 void PythonQtPrivate::addDecorators(QObject* o, int decoTypes) | |||||
915 | QMetaMethod m = o->metaObject()->method(i); |
|
915 | QMetaMethod m = o->metaObject()->method(i); | |
916 | if ((m.methodType() == QMetaMethod::Method || |
|
916 | if ((m.methodType() == QMetaMethod::Method || | |
917 | m.methodType() == QMetaMethod::Slot) && m.access() == QMetaMethod::Public) { |
|
917 | m.methodType() == QMetaMethod::Slot) && m.access() == QMetaMethod::Public) { | |
918 | const PythonQtMethodInfo* info = PythonQtMethodInfo::getCachedMethodInfo(m); |
|
918 | const PythonQtMethodInfo* info = PythonQtMethodInfo::getCachedMethodInfo(m, NULL); | |
919 | if (qstrncmp(m.signature(), "new_", 4)==0) { |
|
919 | if (qstrncmp(m.signature(), "new_", 4)==0) { | |
920 | if ((decoTypes & ConstructorDecorator) == 0) continue; |
|
920 | if ((decoTypes & ConstructorDecorator) == 0) continue; | |
921 | // either it returns a * or a QVariant and the name starts with "new_" |
|
921 | if (info->parameters().at(0).isPointer) { | |
922 | bool isVariantReturn = info->parameters().at(0).typeId == PythonQtMethodInfo::Variant; |
|
|||
923 | if ((info->parameters().at(0).isPointer || isVariantReturn)) { |
|
|||
924 | QByteArray signature = m.signature(); |
|
922 | QByteArray signature = m.signature(); | |
925 | QByteArray nameOfClass = signature.mid(4, signature.indexOf('(')-4); |
|
923 | QByteArray nameOfClass = signature.mid(4, signature.indexOf('(')-4); | |
926 | PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(nameOfClass); |
|
924 | PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(nameOfClass); | |
927 | PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(m, i, o, PythonQtSlotInfo::ClassDecorator); |
|
925 | PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(NULL, m, i, o, PythonQtSlotInfo::ClassDecorator); | |
928 | classInfo->addConstructor(newSlot); |
|
926 | classInfo->addConstructor(newSlot); | |
929 | } |
|
927 | } | |
930 | } else if (qstrncmp(m.signature(), "delete_", 7)==0) { |
|
928 | } else if (qstrncmp(m.signature(), "delete_", 7)==0) { | |
@@ -932,7 +930,7 void PythonQtPrivate::addDecorators(QObject* o, int decoTypes) | |||||
932 | QByteArray signature = m.signature(); |
|
930 | QByteArray signature = m.signature(); | |
933 | QByteArray nameOfClass = signature.mid(7, signature.indexOf('(')-7); |
|
931 | QByteArray nameOfClass = signature.mid(7, signature.indexOf('(')-7); | |
934 | PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(nameOfClass); |
|
932 | PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(nameOfClass); | |
935 | PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(m, i, o, PythonQtSlotInfo::ClassDecorator); |
|
933 | PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(NULL, m, i, o, PythonQtSlotInfo::ClassDecorator); | |
936 | classInfo->setDestructor(newSlot); |
|
934 | classInfo->setDestructor(newSlot); | |
937 | } else if (qstrncmp(m.signature(), "static_", 7)==0) { |
|
935 | } else if (qstrncmp(m.signature(), "static_", 7)==0) { | |
938 | if ((decoTypes & StaticDecorator) == 0) continue; |
|
936 | if ((decoTypes & StaticDecorator) == 0) continue; | |
@@ -940,7 +938,7 void PythonQtPrivate::addDecorators(QObject* o, int decoTypes) | |||||
940 | QByteArray nameOfClass = signature.mid(signature.indexOf('_')+1); |
|
938 | QByteArray nameOfClass = signature.mid(signature.indexOf('_')+1); | |
941 | nameOfClass = nameOfClass.mid(0, nameOfClass.indexOf('_')); |
|
939 | nameOfClass = nameOfClass.mid(0, nameOfClass.indexOf('_')); | |
942 | PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(nameOfClass); |
|
940 | PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(nameOfClass); | |
943 | PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(m, i, o, PythonQtSlotInfo::ClassDecorator); |
|
941 | PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(NULL, m, i, o, PythonQtSlotInfo::ClassDecorator); | |
944 | classInfo->addDecoratorSlot(newSlot); |
|
942 | classInfo->addDecoratorSlot(newSlot); | |
945 | } else { |
|
943 | } else { | |
946 | if ((decoTypes & InstanceDecorator) == 0) continue; |
|
944 | if ((decoTypes & InstanceDecorator) == 0) continue; | |
@@ -948,7 +946,7 void PythonQtPrivate::addDecorators(QObject* o, int decoTypes) | |||||
948 | PythonQtMethodInfo::ParameterInfo p = info->parameters().at(1); |
|
946 | PythonQtMethodInfo::ParameterInfo p = info->parameters().at(1); | |
949 | if (p.isPointer) { |
|
947 | if (p.isPointer) { | |
950 | PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(p.name); |
|
948 | PythonQtClassInfo* classInfo = lookupClassInfoAndCreateIfNotPresent(p.name); | |
951 | PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(m, i, o, PythonQtSlotInfo::InstanceDecorator); |
|
949 | PythonQtSlotInfo* newSlot = new PythonQtSlotInfo(NULL, m, i, o, PythonQtSlotInfo::InstanceDecorator); | |
952 | classInfo->addDecoratorSlot(newSlot); |
|
950 | classInfo->addDecoratorSlot(newSlot); | |
953 | } |
|
951 | } | |
954 | } |
|
952 | } |
@@ -186,7 +186,7 PythonQtSlotInfo* PythonQtClassInfo::findDecoratorSlotsFromDecoratorProvider(con | |||||
186 | // check if same length and same name |
|
186 | // check if same length and same name | |
187 | if (memberNameLen == offset && qstrncmp(memberName, sigStart, offset)==0) { |
|
187 | if (memberNameLen == offset && qstrncmp(memberName, sigStart, offset)==0) { | |
188 | found = true; |
|
188 | found = true; | |
189 | PythonQtSlotInfo* info = new PythonQtSlotInfo(m, i, decoratorProvider, isClassDeco?PythonQtSlotInfo::ClassDecorator:PythonQtSlotInfo::InstanceDecorator); |
|
189 | PythonQtSlotInfo* info = new PythonQtSlotInfo(this, m, i, decoratorProvider, isClassDeco?PythonQtSlotInfo::ClassDecorator:PythonQtSlotInfo::InstanceDecorator); | |
190 | info->setUpcastingOffset(upcastingOffset); |
|
190 | info->setUpcastingOffset(upcastingOffset); | |
191 | //qDebug()<< "adding " << decoratorProvider->metaObject()->className() << " " << memberName << " " << upcastingOffset; |
|
191 | //qDebug()<< "adding " << decoratorProvider->metaObject()->className() << " " << memberName << " " << upcastingOffset; | |
192 | if (tail) { |
|
192 | if (tail) { | |
@@ -225,7 +225,7 bool PythonQtClassInfo::lookForMethodAndCache(const char* memberName) | |||||
225 | // check if same length and same name |
|
225 | // check if same length and same name | |
226 | if (memberNameLen == offset && qstrncmp(memberName, sigStart, offset)==0) { |
|
226 | if (memberNameLen == offset && qstrncmp(memberName, sigStart, offset)==0) { | |
227 | found = true; |
|
227 | found = true; | |
228 | PythonQtSlotInfo* info = new PythonQtSlotInfo(m, i); |
|
228 | PythonQtSlotInfo* info = new PythonQtSlotInfo(this, m, i); | |
229 | if (tail) { |
|
229 | if (tail) { | |
230 | tail->setNextInfo(info); |
|
230 | tail->setNextInfo(info); | |
231 | } else { |
|
231 | } else { | |
@@ -458,12 +458,9 QStringList PythonQtClassInfo::memberList(bool metaOnly) | |||||
458 | QMetaMethod m = _meta->method(i); |
|
458 | QMetaMethod m = _meta->method(i); | |
459 | if ((m.methodType() == QMetaMethod::Method || |
|
459 | if ((m.methodType() == QMetaMethod::Method || | |
460 | m.methodType() == QMetaMethod::Slot) && m.access() == QMetaMethod::Public) { |
|
460 | m.methodType() == QMetaMethod::Slot) && m.access() == QMetaMethod::Public) { | |
461 |
QByteArray signa(m.signature()); |
|
461 | QByteArray signa(m.signature()); | |
462 | if (signa.startsWith("new_")) continue; |
|
462 | signa = signa.left(signa.indexOf('(')); | |
463 | if (signa.startsWith("delete_")) continue; |
|
463 | l << signa; | |
464 | if (signa.startsWith("static_")) continue; |
|
|||
465 | PythonQtSlotInfo slot(m, i); |
|
|||
466 | l << slot.slotName(); |
|
|||
467 | } |
|
464 | } | |
468 | } |
|
465 | } | |
469 | } |
|
466 | } | |
@@ -586,11 +583,7 QString PythonQtClassInfo::help() | |||||
586 | QMetaMethod m = _meta->method(i); |
|
583 | QMetaMethod m = _meta->method(i); | |
587 | if ((m.methodType() == QMetaMethod::Method || |
|
584 | if ((m.methodType() == QMetaMethod::Method || | |
588 | m.methodType() == QMetaMethod::Slot) && m.access() == QMetaMethod::Public) { |
|
585 | m.methodType() == QMetaMethod::Slot) && m.access() == QMetaMethod::Public) { | |
589 | QByteArray signa(m.signature()); |
|
586 | PythonQtSlotInfo slot(this, m, i); | |
590 | if (signa.startsWith("new_")) continue; |
|
|||
591 | if (signa.startsWith("delete_")) continue; |
|
|||
592 | if (signa.startsWith("static_")) continue; |
|
|||
593 | PythonQtSlotInfo slot(m, i); |
|
|||
594 | h += slot.fullSignature()+ "\n"; |
|
587 | h += slot.fullSignature()+ "\n"; | |
595 | } |
|
588 | } | |
596 | } |
|
589 | } | |
@@ -681,9 +674,14 QObject* PythonQtClassInfo::decorator() | |||||
681 | _decoratorProvider = (*_decoratorProviderCB)(); |
|
674 | _decoratorProvider = (*_decoratorProviderCB)(); | |
682 | if (_decoratorProvider) { |
|
675 | if (_decoratorProvider) { | |
683 | _decoratorProvider->setParent(PythonQt::priv()); |
|
676 | _decoratorProvider->setParent(PythonQt::priv()); | |
|
677 | // setup enums early, since they might be needed by the constructor decorators: | |||
|
678 | if (!_enumsCreated) { | |||
|
679 | createEnumWrappers(); | |||
|
680 | } | |||
684 | PythonQt::priv()->addDecorators(_decoratorProvider, PythonQtPrivate::ConstructorDecorator | PythonQtPrivate::DestructorDecorator); |
|
681 | PythonQt::priv()->addDecorators(_decoratorProvider, PythonQtPrivate::ConstructorDecorator | PythonQtPrivate::DestructorDecorator); | |
685 | } |
|
682 | } | |
686 | } |
|
683 | } | |
|
684 | // check if enums need to be created and create them if they are not yet created | |||
687 | if (!_enumsCreated) { |
|
685 | if (!_enumsCreated) { | |
688 | createEnumWrappers(); |
|
686 | createEnumWrappers(); | |
689 | } |
|
687 | } |
@@ -40,12 +40,13 | |||||
40 | //---------------------------------------------------------------------------------- |
|
40 | //---------------------------------------------------------------------------------- | |
41 |
|
41 | |||
42 | #include "PythonQtMethodInfo.h" |
|
42 | #include "PythonQtMethodInfo.h" | |
|
43 | #include "PythonQtClassInfo.h" | |||
43 | #include <iostream> |
|
44 | #include <iostream> | |
44 |
|
45 | |||
45 | QHash<QByteArray, PythonQtMethodInfo*> PythonQtMethodInfo::_cachedSignatures; |
|
46 | QHash<QByteArray, PythonQtMethodInfo*> PythonQtMethodInfo::_cachedSignatures; | |
46 | QHash<QByteArray, QByteArray> PythonQtMethodInfo::_parameterNameAliases; |
|
47 | QHash<QByteArray, QByteArray> PythonQtMethodInfo::_parameterNameAliases; | |
47 |
|
48 | |||
48 | PythonQtMethodInfo::PythonQtMethodInfo(const QMetaMethod& meta) |
|
49 | PythonQtMethodInfo::PythonQtMethodInfo(const QMetaMethod& meta, PythonQtClassInfo* classInfo) | |
49 | { |
|
50 | { | |
50 | #ifdef PYTHONQT_DEBUG |
|
51 | #ifdef PYTHONQT_DEBUG | |
51 | QByteArray sig(meta.signature()); |
|
52 | QByteArray sig(meta.signature()); | |
@@ -65,14 +66,14 PythonQtMethodInfo::PythonQtMethodInfo(const QMetaMethod& meta) | |||||
65 | } |
|
66 | } | |
66 | } |
|
67 | } | |
67 |
|
68 | |||
68 | const PythonQtMethodInfo* PythonQtMethodInfo::getCachedMethodInfo(const QMetaMethod& signal) |
|
69 | const PythonQtMethodInfo* PythonQtMethodInfo::getCachedMethodInfo(const QMetaMethod& signal, PythonQtClassInfo* classInfo) | |
69 | { |
|
70 | { | |
70 | QByteArray sig(signal.signature()); |
|
71 | QByteArray sig(signal.signature()); | |
71 | sig = sig.mid(sig.indexOf('(')); |
|
72 | sig = sig.mid(sig.indexOf('(')); | |
72 | QByteArray fullSig = QByteArray(signal.typeName()) + " " + sig; |
|
73 | QByteArray fullSig = QByteArray(signal.typeName()) + " " + sig; | |
73 | PythonQtMethodInfo* result = _cachedSignatures.value(fullSig); |
|
74 | PythonQtMethodInfo* result = _cachedSignatures.value(fullSig); | |
74 | if (!result) { |
|
75 | if (!result) { | |
75 | result = new PythonQtMethodInfo(signal); |
|
76 | result = new PythonQtMethodInfo(signal, classInfo); | |
76 | _cachedSignatures.insert(fullSig, result); |
|
77 | _cachedSignatures.insert(fullSig, result); | |
77 | } |
|
78 | } | |
78 | return result; |
|
79 | return result; | |
@@ -83,7 +84,7 const PythonQtMethodInfo* PythonQtMethodInfo::getCachedMethodInfoFromMetaObjectA | |||||
83 | QByteArray sig = QMetaObject::normalizedSignature(signature); |
|
84 | QByteArray sig = QMetaObject::normalizedSignature(signature); | |
84 | int idx = metaObject->indexOfMethod(sig); |
|
85 | int idx = metaObject->indexOfMethod(sig); | |
85 | QMetaMethod meta = metaObject->method(idx); |
|
86 | QMetaMethod meta = metaObject->method(idx); | |
86 | return PythonQtMethodInfo::getCachedMethodInfo(meta); |
|
87 | return PythonQtMethodInfo::getCachedMethodInfo(meta, NULL); | |
87 | } |
|
88 | } | |
88 |
|
89 | |||
89 | void PythonQtMethodInfo::fillParameterInfo(ParameterInfo& type, const QByteArray& orgName) |
|
90 | void PythonQtMethodInfo::fillParameterInfo(ParameterInfo& type, const QByteArray& orgName) |
@@ -49,6 +49,8 | |||||
49 | #include <QList> |
|
49 | #include <QList> | |
50 | #include <QMetaMethod> |
|
50 | #include <QMetaMethod> | |
51 |
|
51 | |||
|
52 | class PythonQtClassInfo; | |||
|
53 | ||||
52 | //! stores information about a specific signal/slot/method |
|
54 | //! stores information about a specific signal/slot/method | |
53 | class PYTHONQT_EXPORT PythonQtMethodInfo |
|
55 | class PYTHONQT_EXPORT PythonQtMethodInfo | |
54 | { |
|
56 | { | |
@@ -68,16 +70,16 public: | |||||
68 |
|
70 | |||
69 | PythonQtMethodInfo() {}; |
|
71 | PythonQtMethodInfo() {}; | |
70 | ~PythonQtMethodInfo() {}; |
|
72 | ~PythonQtMethodInfo() {}; | |
71 | PythonQtMethodInfo(const QMetaMethod& meta); |
|
73 | PythonQtMethodInfo(const QMetaMethod& meta, PythonQtClassInfo* classInfo); | |
72 | PythonQtMethodInfo(const PythonQtMethodInfo& other) { |
|
74 | PythonQtMethodInfo(const PythonQtMethodInfo& other) { | |
73 | _parameters = other._parameters; |
|
75 | _parameters = other._parameters; | |
74 | } |
|
76 | } | |
75 |
|
77 | |||
76 | //! returns the method info of the signature, uses a cache internally to speed up |
|
78 | //! returns the method info of the signature, uses a cache internally to speed up | |
77 | //! multiple requests for the same method |
|
79 | //! multiple requests for the same method, classInfo is passed to allow local enum resolution (if NULL is passed, no local enums are recognized) | |
78 | static const PythonQtMethodInfo* getCachedMethodInfo(const QMetaMethod& method); |
|
80 | static const PythonQtMethodInfo* getCachedMethodInfo(const QMetaMethod& method, PythonQtClassInfo* classInfo); | |
79 |
|
81 | |||
80 | //! get the cached method info by finding the meta method on the meta object via its signature |
|
82 | //! get the cached method info by finding the meta method on the meta object via its signature, enums are only supported with leading namespace:: | |
81 | static const PythonQtMethodInfo* getCachedMethodInfoFromMetaObjectAndSignature(const QMetaObject* metaObject, const char* signature); |
|
83 | static const PythonQtMethodInfo* getCachedMethodInfoFromMetaObjectAndSignature(const QMetaObject* metaObject, const char* signature); | |
82 |
|
84 | |||
83 | //! cleanup the cache |
|
85 | //! cleanup the cache | |
@@ -125,9 +127,9 public: | |||||
125 | _upcastingOffset = 0; |
|
127 | _upcastingOffset = 0; | |
126 | } |
|
128 | } | |
127 |
|
129 | |||
128 | PythonQtSlotInfo(const QMetaMethod& meta, int slotIndex, QObject* decorator = NULL, Type type = MemberSlot ):PythonQtMethodInfo() |
|
130 | PythonQtSlotInfo(PythonQtClassInfo* classInfo, const QMetaMethod& meta, int slotIndex, QObject* decorator = NULL, Type type = MemberSlot ):PythonQtMethodInfo() | |
129 | { |
|
131 | { | |
130 | const PythonQtMethodInfo* info = getCachedMethodInfo(meta); |
|
132 | const PythonQtMethodInfo* info = getCachedMethodInfo(meta, classInfo); | |
131 | _meta = meta; |
|
133 | _meta = meta; | |
132 | _parameters = info->parameters(); |
|
134 | _parameters = info->parameters(); | |
133 | _slotIndex = slotIndex; |
|
135 | _slotIndex = slotIndex; |
@@ -142,6 +142,17 PyObject* PythonQtSignalTarget::call(PyObject* callable, const PythonQtMethodInf | |||||
142 | PythonQtSignalReceiver::PythonQtSignalReceiver(QObject* obj):PythonQtSignalReceiverBase(obj) |
|
142 | PythonQtSignalReceiver::PythonQtSignalReceiver(QObject* obj):PythonQtSignalReceiverBase(obj) | |
143 | { |
|
143 | { | |
144 | _obj = obj; |
|
144 | _obj = obj; | |
|
145 | ||||
|
146 | // fetch the class info for object, since we will need to for correct enum resolution in | |||
|
147 | // signals | |||
|
148 | _objClassInfo = PythonQt::priv()->getClassInfo(obj->metaObject()); | |||
|
149 | if (!_objClassInfo || !_objClassInfo->isQObject()) { | |||
|
150 | PythonQt::self()->registerClass(obj->metaObject()); | |||
|
151 | _objClassInfo = PythonQt::priv()->getClassInfo(obj->metaObject()); | |||
|
152 | } | |||
|
153 | // force decorator/enum creation | |||
|
154 | _objClassInfo->decorator(); | |||
|
155 | ||||
145 | _slotCount = staticMetaObject.methodOffset(); |
|
156 | _slotCount = staticMetaObject.methodOffset(); | |
146 | } |
|
157 | } | |
147 |
|
158 | |||
@@ -158,7 +169,7 bool PythonQtSignalReceiver::addSignalHandler(const char* signal, PyObject* call | |||||
158 | if (sigId>=0) { |
|
169 | if (sigId>=0) { | |
159 | // create PythonQtMethodInfo from signal |
|
170 | // create PythonQtMethodInfo from signal | |
160 | QMetaMethod meta = _obj->metaObject()->method(sigId); |
|
171 | QMetaMethod meta = _obj->metaObject()->method(sigId); | |
161 | const PythonQtMethodInfo* signalInfo = PythonQtMethodInfo::getCachedMethodInfo(meta); |
|
172 | const PythonQtMethodInfo* signalInfo = PythonQtMethodInfo::getCachedMethodInfo(meta, _objClassInfo); | |
162 | PythonQtSignalTarget t(sigId, signalInfo, _slotCount, callable); |
|
173 | PythonQtSignalTarget t(sigId, signalInfo, _slotCount, callable); | |
163 | _targets.append(t); |
|
174 | _targets.append(t); | |
164 | // now connect to ourselves with the new slot id |
|
175 | // now connect to ourselves with the new slot id |
@@ -47,6 +47,7 | |||||
47 | #include "PythonQtObjectPtr.h" |
|
47 | #include "PythonQtObjectPtr.h" | |
48 |
|
48 | |||
49 | class PythonQtMethodInfo; |
|
49 | class PythonQtMethodInfo; | |
|
50 | class PythonQtClassInfo; | |||
50 |
|
51 | |||
51 | //! stores information about a signal target |
|
52 | //! stores information about a signal target | |
52 | /*! copy construction and assignment works fine with the C++ standard behaviour and are thus not implemented |
|
53 | /*! copy construction and assignment works fine with the C++ standard behaviour and are thus not implemented | |
@@ -130,6 +131,7 private: | |||||
130 | int getSignalIndex(const char* signal); |
|
131 | int getSignalIndex(const char* signal); | |
131 |
|
132 | |||
132 | QObject* _obj; |
|
133 | QObject* _obj; | |
|
134 | PythonQtClassInfo* _objClassInfo; | |||
133 | int _slotCount; |
|
135 | int _slotCount; | |
134 | // linear list may get slow on multiple targets, but I think typically we have many objects and just a few signals |
|
136 | // linear list may get slow on multiple targets, but I think typically we have many objects and just a few signals | |
135 | QList<PythonQtSignalTarget> _targets; |
|
137 | QList<PythonQtSignalTarget> _targets; |
General Comments 0
You need to be logged in to leave comments.
Login now