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