##// 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 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 381 if (!info || info->pythonQtClassWrapper()==NULL) {
376 382 // still unknown, register as CPP class
377 383 registerCPPClass(name.constData());
@@ -1066,6 +1072,17 PythonQtClassInfo* PythonQtPrivate::lookupClassInfoAndCreateIfNotPresent(const c
1066 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 1086 bool PythonQt::addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset)
1070 1087 {
1071 1088 return _p->addParentClass(typeName, parentTypeName, upcastingOffset);
@@ -65,8 +65,9 class PythonQtImportFileInterface;
65 65 class PythonQtCppWrapperFactory;
66 66 class PythonQtQFileImporter;
67 67
68 typedef void PythonQtQObjectWrappedCB(QObject* object);
69 typedef void PythonQtQObjectNoLongerWrappedCB(QObject* object);
68 typedef void PythonQtQObjectWrappedCB(QObject* object);
69 typedef void PythonQtQObjectNoLongerWrappedCB(QObject* object);
70 typedef void* PythonQtPolymorphicHandlerCB(const void *ptr, char **class_name);
70 71
71 72 typedef void PythonQtShellSetInstanceWrapperCB(void* object, PythonQtInstanceWrapper* wrapper);
72 73
@@ -154,6 +155,9 public:
154 155 //! Returns false if the typeName was not yet registered.
155 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 161 //! parses the given file and returns the python code object, this can then be used to call evalCode()
158 162 PythonQtObjectPtr parseFile(const QString& filename);
159 163
@@ -399,6 +403,9 public:
399 403 //! add parent class relation
400 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 409 //! lookup existing classinfo and return new if not yet present
403 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 473 const char* PythonQtClassInfo::className()
@@ -669,3 +670,37 bool PythonQtClassInfo::hasOwnerMethodButNoOwner(void* object)
669 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 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 191 private:
186 192 //! clear all cached members
187 193 void clearCachedMembers();
188 194
195 void* recursiveCastDownIfPossible(void* ptr, char** resultClassName);
196
189 197 PythonQtSlotInfo* findDecoratorSlotsFromDecoratorProvider(const char* memberName, PythonQtSlotInfo* inputInfo, bool &found, QHash<QByteArray, PythonQtMemberInfo>& memberCache, int upcastingOffset);
190 198 void listDecoratorSlotsFromDecoratorProvider(QStringList& list, bool metaOnly);
191 199 PythonQtSlotInfo* recursiveFindDecoratorSlotsFromDecoratorProvider(const char* memberName, PythonQtSlotInfo* inputInfo, bool &found, QHash<QByteArray, PythonQtMemberInfo>& memberCache, int upcastingOffset);
@@ -211,6 +219,8 private:
211 219 QByteArray _wrappedClassName;
212 220 QList<ParentClassInfo> _parentClasses;
213 221
222 QList<PythonQtPolymorphicHandlerCB*> _polymorphicHandlers;
223
214 224 QObject* _decoratorProvider;
215 225 PythonQtQObjectCreatorFunctionCB* _decoratorProviderCB;
216 226
General Comments 0
You need to be logged in to leave comments. Login now