##// 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 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