##// END OF EJS Templates
added initial version of foreign wrappers, needs testing...
florianlink -
r167:2184742f9ca8
parent child
Show More
@@ -391,6 +391,15 PyObject* PythonQtPrivate::wrapPtr(void* ptr, const QByteArray& name)
391 return (PyObject*)wrap;
391 return (PyObject*)wrap;
392 }
392 }
393
393
394 // not a known QObject, try to wrap via foreign wrapper factories
395 PyObject* foreignWrapper = NULL;
396 for (int i=0; i<_foreignWrapperFactories.size(); i++) {
397 foreignWrapper = _foreignWrapperFactories.at(i)->wrap(name, ptr);
398 if (foreignWrapper) {
399 return foreignWrapper;
400 }
401 }
402
394 // not a known QObject, so try our wrapper factory:
403 // not a known QObject, so try our wrapper factory:
395 QObject* wrapper = NULL;
404 QObject* wrapper = NULL;
396 for (int i=0; i<_cppWrapperFactories.size(); i++) {
405 for (int i=0; i<_cppWrapperFactories.size(); i++) {
@@ -415,8 +424,6 PyObject* PythonQtPrivate::wrapPtr(void* ptr, const QByteArray& name)
415 info->setMetaObject(wrapper->metaObject());
424 info->setMetaObject(wrapper->metaObject());
416 }
425 }
417
426
418 // TODO XXX: delegate wrapping via CB here (pass name and ptr)
419
420 wrap = createNewPythonQtInstanceWrapper(wrapper, info, ptr);
427 wrap = createNewPythonQtInstanceWrapper(wrapper, info, ptr);
421 // mlabDebugConst("MLABPython","new c++ wrapper added " << wrap->_wrappedPtr << " " << wrap->_obj->className() << " " << wrap->classInfo()->wrappedClassName().latin1());
428 // mlabDebugConst("MLABPython","new c++ wrapper added " << wrap->_wrappedPtr << " " << wrap->_obj->className() << " " << wrap->classInfo()->wrappedClassName().latin1());
422 } else {
429 } else {
@@ -965,6 +972,11 void PythonQt::addWrapperFactory(PythonQtCppWrapperFactory* factory)
965 _p->_cppWrapperFactories.append(factory);
972 _p->_cppWrapperFactories.append(factory);
966 }
973 }
967
974
975 void PythonQt::addWrapperFactory( PythonQtForeignWrapperFactory* factory )
976 {
977 _p->_foreignWrapperFactories.append(factory);
978 }
979
968 //---------------------------------------------------------------------------------------------------
980 //---------------------------------------------------------------------------------------------------
969 PythonQtPrivate::PythonQtPrivate()
981 PythonQtPrivate::PythonQtPrivate()
970 {
982 {
@@ -1316,3 +1328,15 PythonQtObjectPtr PythonQtPrivate::createModule(const QString& name, PyObject* p
1316 }
1328 }
1317 return result;
1329 return result;
1318 }
1330 }
1331
1332 void* PythonQtPrivate::unwrapForeignWrapper( const QByteArray& classname, PyObject* obj )
1333 {
1334 void* foreignObject = NULL;
1335 for (int i=0; i<_foreignWrapperFactories.size(); i++) {
1336 foreignObject = _foreignWrapperFactories.at(i)->unwrap(classname, obj);
1337 if (foreignObject) {
1338 return foreignObject;
1339 }
1340 }
1341 return NULL;
1342 } No newline at end of file
@@ -64,6 +64,7 class PythonQtMethodInfo;
64 class PythonQtSignalReceiver;
64 class PythonQtSignalReceiver;
65 class PythonQtImportFileInterface;
65 class PythonQtImportFileInterface;
66 class PythonQtCppWrapperFactory;
66 class PythonQtCppWrapperFactory;
67 class PythonQtForeignWrapperFactory;
67 class PythonQtQFileImporter;
68 class PythonQtQFileImporter;
68
69
69 typedef void PythonQtQObjectWrappedCB(QObject* object);
70 typedef void PythonQtQObjectWrappedCB(QObject* object);
@@ -409,6 +410,9 public:
409 //! add the given factory to PythonQt (ownership stays with caller)
410 //! add the given factory to PythonQt (ownership stays with caller)
410 void addWrapperFactory(PythonQtCppWrapperFactory* factory);
411 void addWrapperFactory(PythonQtCppWrapperFactory* factory);
411
412
413 //! add the given factory to PythonQt (ownership stays with caller)
414 void addWrapperFactory(PythonQtForeignWrapperFactory* factory);
415
412 //@}
416 //@}
413
417
414 //---------------------------------------------------------------------------
418 //---------------------------------------------------------------------------
@@ -538,6 +542,9 public:
538 //! remove the wrapper ptr again
542 //! remove the wrapper ptr again
539 void removeWrapperPointer(void* obj);
543 void removeWrapperPointer(void* obj);
540
544
545 //! try to unwrap the given object to a C++ pointer using the foreign wrapper factories
546 void* unwrapForeignWrapper(const QByteArray& classname, PyObject* obj);
547
541 //! add parent class relation
548 //! add parent class relation
542 bool addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset);
549 bool addParentClass(const char* typeName, const char* parentTypeName, int upcastingOffset);
543
550
@@ -660,6 +667,8 private:
660 //! the cpp object wrapper factories
667 //! the cpp object wrapper factories
661 QList<PythonQtCppWrapperFactory*> _cppWrapperFactories;
668 QList<PythonQtCppWrapperFactory*> _cppWrapperFactories;
662
669
670 QList<PythonQtForeignWrapperFactory*> _foreignWrapperFactories;
671
663 QHash<QByteArray, PyObject*> _packages;
672 QHash<QByteArray, PyObject*> _packages;
664
673
665 PythonQtClassInfo* _currentClassInfoForClassWrapperCreation;
674 PythonQtClassInfo* _currentClassInfoForClassWrapperCreation;
@@ -386,12 +386,14 void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
386 } else if (info.name == "PyObject") {
386 } else if (info.name == "PyObject") {
387 // handle low level PyObject directly
387 // handle low level PyObject directly
388 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, obj, ptr);
388 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, obj, ptr);
389 }
389 } else if (obj == Py_None) {
390 // TODO XXX: pass obj and name and add when it returns a pointer
391 else if (obj == Py_None) {
392 // None is treated as a NULL ptr
390 // None is treated as a NULL ptr
393 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, NULL, ptr);
391 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, NULL, ptr);
394 } else {
392 } else {
393 void* foreignWrapper = PythonQt::priv()->unwrapForeignWrapper(info.name, obj);
394 if (foreignWrapper) {
395 PythonQtValueStorage_ADD_VALUE_IF_NEEDED(alreadyAllocatedCPPObject,global_ptrStorage, void*, foreignWrapper, ptr);
396 } else {
395 // if we are not strict, we try if we are passed a 0 integer
397 // if we are not strict, we try if we are passed a 0 integer
396 if (!strict) {
398 if (!strict) {
397 bool ok;
399 bool ok;
@@ -402,6 +404,7 void* PythonQtConv::ConvertPythonToQt(const PythonQtMethodInfo::ParameterInfo& i
402 }
404 }
403 }
405 }
404 }
406 }
407 }
405 } else if (info.pointerCount == 0) {
408 } else if (info.pointerCount == 0) {
406 // not a pointer
409 // not a pointer
407 switch (info.typeId) {
410 switch (info.typeId) {
@@ -54,7 +54,25 public:
54 virtual ~PythonQtCppWrapperFactory() {};
54 virtual ~PythonQtCppWrapperFactory() {};
55
55
56 //! create a wrapper for the given object
56 //! create a wrapper for the given object
57 virtual QObject* create(const QByteArray& name, void *ptr) = 0;
57 virtual QObject* create(const QByteArray& classname, void *ptr) = 0;
58
59 };
60
61 //! Factory interface for C++ classes that can be mapped directly from/to
62 //! Python with other means than PythonQt/QObjects.
63 class PYTHONQT_EXPORT PythonQtForeignWrapperFactory
64 {
65 public:
66 PythonQtForeignWrapperFactory() {};
67 virtual ~PythonQtForeignWrapperFactory() {};
68
69 //! create a Python object (with new reference count), wrapping the given \p ptr as class of type \p classname
70 //! Return NULL (and not Py_None) if the object could not be wrapped.
71 virtual PyObject* wrap(const QByteArray& classname, void *ptr) = 0;
72
73 //! unwrap the given object to a C++ object of type \p classname if possible
74 //! Return NULL otherwise.
75 virtual void* unwrap(const QByteArray& classname, PyObject* object) = 0;
58
76
59 };
77 };
60
78
General Comments 0
You need to be logged in to leave comments. Login now