##// END OF EJS Templates
added support for downcasting via polymorphic handlers...
florianlink -
r26:dcd28715f924
parent child
Show More
@@ -372,6 +372,12 PyObject* PythonQtPrivate::wrapPtr(void* ptr, const QByteArray& name)
372 break;
372 break;
373 }
373 }
374 }
374 }
375
376 if (info) {
377 // try to downcast in the class hierarchy, which will modify info and ptr if it is successfull
378 ptr = info->castDownIfPossible(ptr, &info);
379 }
380
375 if (!info || info->pythonQtClassWrapper()==NULL) {
381 if (!info || info->pythonQtClassWrapper()==NULL) {
376 // still unknown, register as CPP class
382 // still unknown, register as CPP class
377 registerCPPClass(name.constData());
383 registerCPPClass(name.constData());
@@ -1066,6 +1072,17 PythonQtClassInfo* PythonQtPrivate::lookupClassInfoAndCreateIfNotPresent(const c
1066 return info;
1072 return info;
1067 }
1073 }
1068
1074
1075 void PythonQt::addPolymorphicHandler(const char* typeName, PythonQtPolymorphicHandlerCB* cb)
1076 {
1077 _p->addPolymorphicHandler(typeName, cb);
1078 }
1079
1080 void PythonQtPrivate::addPolymorphicHandler(const char* typeName, PythonQtPolymorphicHandlerCB* cb)
1081 {
1082 PythonQtClassInfo* info = lookupClassInfoAndCreateIfNotPresent(typeName);
1083 info->addPolymorphicHandler(cb);
1084 }
1085
1069 bool PythonQt::addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset)
1086 bool PythonQt::addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset)
1070 {
1087 {
1071 return _p->addParentClass(typeName, parentTypeName, upcastingOffset);
1088 return _p->addParentClass(typeName, parentTypeName, upcastingOffset);
@@ -67,6 +67,7 class PythonQtQFileImporter;
67
67
68 typedef void PythonQtQObjectWrappedCB(QObject* object);
68 typedef void PythonQtQObjectWrappedCB(QObject* object);
69 typedef void PythonQtQObjectNoLongerWrappedCB(QObject* object);
69 typedef void PythonQtQObjectNoLongerWrappedCB(QObject* object);
70 typedef void* PythonQtPolymorphicHandlerCB(const void *ptr, char **class_name);
70
71
71 typedef void PythonQtShellSetInstanceWrapperCB(void* object, PythonQtInstanceWrapper* wrapper);
72 typedef void PythonQtShellSetInstanceWrapperCB(void* object, PythonQtInstanceWrapper* wrapper);
72
73
@@ -154,6 +155,9 public:
154 //! Returns false if the typeName was not yet registered.
155 //! Returns false if the typeName was not yet registered.
155 bool addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset=0);
156 bool addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset=0);
156
157
158 //! add a handler for polymorphic downcasting
159 void addPolymorphicHandler(const char* typeName, PythonQtPolymorphicHandlerCB* cb);
160
157 //! parses the given file and returns the python code object, this can then be used to call evalCode()
161 //! parses the given file and returns the python code object, this can then be used to call evalCode()
158 PythonQtObjectPtr parseFile(const QString& filename);
162 PythonQtObjectPtr parseFile(const QString& filename);
159
163
@@ -399,6 +403,9 public:
399 //! add parent class relation
403 //! add parent class relation
400 bool addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset);
404 bool addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset);
401
405
406 //! add a handler for polymorphic downcasting
407 void addPolymorphicHandler(const char* typeName, PythonQtPolymorphicHandlerCB* cb);
408
402 //! lookup existing classinfo and return new if not yet present
409 //! lookup existing classinfo and return new if not yet present
403 PythonQtClassInfo* lookupClassInfoAndCreateIfNotPresent(const char* typeName);
410 PythonQtClassInfo* lookupClassInfoAndCreateIfNotPresent(const char* typeName);
404
411
@@ -466,7 +466,8 QStringList PythonQtClassInfo::memberList(bool metaOnly)
466 }
466 }
467 }
467 }
468 }
468 }
469 return l;
469
470 return QSet<QString>::fromList(l).toList();
470 }
471 }
471
472
472 const char* PythonQtClassInfo::className()
473 const char* PythonQtClassInfo::className()
@@ -669,3 +670,37 bool PythonQtClassInfo::hasOwnerMethodButNoOwner(void* object)
669 return false;
670 return false;
670 }
671 }
671 }
672 }
673
674 void* PythonQtClassInfo::recursiveCastDownIfPossible(void* ptr, char** resultClassName)
675 {
676 if (!_polymorphicHandlers.isEmpty()) {
677 foreach(PythonQtPolymorphicHandlerCB* cb, _polymorphicHandlers) {
678 void* resultPtr = (*cb)(ptr, resultClassName);
679 if (resultPtr) {
680 return resultPtr;
681 }
682 }
683 }
684 foreach(const ParentClassInfo& info, _parentClasses) {
685 if (!info._parent->isQObject()) {
686 void* resultPtr = info._parent->recursiveCastDownIfPossible((char*)ptr + info._upcastingOffset, resultClassName);
687 if (resultPtr) {
688 return resultPtr;
689 }
690 }
691 }
692 return NULL;
693 }
694
695 void* PythonQtClassInfo::castDownIfPossible(void* ptr, PythonQtClassInfo** resultClassInfo)
696 {
697 char* className;
698 void* resultPtr = recursiveCastDownIfPossible(ptr, &className);
699 if (resultPtr) {
700 *resultClassInfo = PythonQt::priv()->getClassInfo(className);
701 } else {
702 *resultClassInfo = this;
703 resultPtr = ptr;
704 }
705 return resultPtr;
706 }
@@ -182,10 +182,18 public:
182 return _shellSetInstanceWrapperCB;
182 return _shellSetInstanceWrapperCB;
183 }
183 }
184
184
185 //! add a handler for polymorphic downcasting
186 void addPolymorphicHandler(PythonQtPolymorphicHandlerCB* cb) { _polymorphicHandlers.append(cb); }
187
188 //! cast the pointer down in the class hierarchy if a polymorphic handler allows to do that
189 void* castDownIfPossible(void* ptr, PythonQtClassInfo** resultClassInfo);
190
185 private:
191 private:
186 //! clear all cached members
192 //! clear all cached members
187 void clearCachedMembers();
193 void clearCachedMembers();
188
194
195 void* recursiveCastDownIfPossible(void* ptr, char** resultClassName);
196
189 PythonQtSlotInfo* findDecoratorSlotsFromDecoratorProvider(const char* memberName, PythonQtSlotInfo* inputInfo, bool &found, QHash<QByteArray, PythonQtMemberInfo>& memberCache, int upcastingOffset);
197 PythonQtSlotInfo* findDecoratorSlotsFromDecoratorProvider(const char* memberName, PythonQtSlotInfo* inputInfo, bool &found, QHash<QByteArray, PythonQtMemberInfo>& memberCache, int upcastingOffset);
190 void listDecoratorSlotsFromDecoratorProvider(QStringList& list, bool metaOnly);
198 void listDecoratorSlotsFromDecoratorProvider(QStringList& list, bool metaOnly);
191 PythonQtSlotInfo* recursiveFindDecoratorSlotsFromDecoratorProvider(const char* memberName, PythonQtSlotInfo* inputInfo, bool &found, QHash<QByteArray, PythonQtMemberInfo>& memberCache, int upcastingOffset);
199 PythonQtSlotInfo* recursiveFindDecoratorSlotsFromDecoratorProvider(const char* memberName, PythonQtSlotInfo* inputInfo, bool &found, QHash<QByteArray, PythonQtMemberInfo>& memberCache, int upcastingOffset);
@@ -211,6 +219,8 private:
211 QByteArray _wrappedClassName;
219 QByteArray _wrappedClassName;
212 QList<ParentClassInfo> _parentClasses;
220 QList<ParentClassInfo> _parentClasses;
213
221
222 QList<PythonQtPolymorphicHandlerCB*> _polymorphicHandlers;
223
214 QObject* _decoratorProvider;
224 QObject* _decoratorProvider;
215 PythonQtQObjectCreatorFunctionCB* _decoratorProviderCB;
225 PythonQtQObjectCreatorFunctionCB* _decoratorProviderCB;
216
226
General Comments 0
You need to be logged in to leave comments. Login now