aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cppgenerator.cpp26
-rw-r--r--libshiboken/basewrapper.cpp33
-rw-r--r--libshiboken/basewrapper.h13
3 files changed, 64 insertions, 8 deletions
diff --git a/cppgenerator.cpp b/cppgenerator.cpp
index 21ec65386..777c9659e 100644
--- a/cppgenerator.cpp
+++ b/cppgenerator.cpp
@@ -366,6 +366,7 @@ void CppGenerator::writeConstructorNative(QTextStream& s, const AbstractMetaFunc
writeFunctionCall(s, func);
if (usePySideExtensions() && func->ownerClass()->isQObject())
s << ", m_metaObject(0)";
+
s << " {" << endl;
const AbstractMetaArgument* lastArg = func->arguments().isEmpty() ? 0 : func->arguments().last();
writeCodeSnips(s, func->injectedCodeSnips(), CodeSnip::Beginning, TypeSystem::NativeCode, func, lastArg);
@@ -379,8 +380,6 @@ void CppGenerator::writeDestructorNative(QTextStream &s, const AbstractMetaClass
Indentation indentation(INDENT);
s << wrapperName(metaClass) << "::~" << wrapperName(metaClass) << "()" << endl << '{' << endl;
s << INDENT << "BindingManager::instance().invalidateWrapper(this);" << endl;
- if (usePySideExtensions() && metaClass->isQObject())
- s << INDENT << "delete m_metaObject;\n";
s << '}' << endl;
}
@@ -592,12 +591,25 @@ void CppGenerator::writeMetaObjectMethod(QTextStream& s, const AbstractMetaClass
s << INDENT << "if (!m_metaObject) {\n";
{
Indentation indentation(INDENT);
- s << INDENT << "PyObject *pySelf = BindingManager::instance().retrieveWrapper(this);\n";
- s << INDENT << "QString className(pySelf->ob_type->tp_name);" << endl;
- s << INDENT << "className = className.mid(className.lastIndexOf(\".\")+1);" << endl;
- s << INDENT << "m_metaObject = new PySide::DynamicQMetaObject(className.toAscii(), &" << metaClass->qualifiedCppName() << "::staticMetaObject);\n";
- s << "}\n";
+ s << INDENT << "PyObject *pySelf = BindingManager::instance().retrieveWrapper(this);\n"
+ << INDENT << "void *typeData = Shiboken::getTypeUserData(reinterpret_cast<Shiboken::SbkBaseWrapper*>(pySelf));" << endl
+ << INDENT << "if (!typeData) {" << endl;
+ {
+ Indentation indentation2(INDENT);
+ s << INDENT << "QString className(pySelf->ob_type->tp_name);" << endl
+ << INDENT << "className = className.mid(className.lastIndexOf(\".\")+1);" << endl
+ << INDENT << "m_metaObject = new PySide::DynamicQMetaObject(className.toAscii(), &"
+ << metaClass->qualifiedCppName() << "::staticMetaObject);" << endl
+ << INDENT << "Shiboken::setTypeUserData(reinterpret_cast<Shiboken::SbkBaseWrapper*>(pySelf), m_metaObject, PySide::deleteDynamicQMetaObject);" << endl;
+ }
+ s << INDENT << "} else {" << endl;
+ {
+ Indentation indentation2(INDENT);
+ s << INDENT << "m_metaObject = reinterpret_cast<PySide::DynamicQMetaObject*>(typeData);" << endl;
+ }
+ s << INDENT << "}" << endl;
}
+ s << INDENT << "}" << endl;
s << INDENT << "return m_metaObject;\n";
s << "}\n\n";
diff --git a/libshiboken/basewrapper.cpp b/libshiboken/basewrapper.cpp
index dde7a7151..88ea8225f 100644
--- a/libshiboken/basewrapper.cpp
+++ b/libshiboken/basewrapper.cpp
@@ -220,6 +220,21 @@ bool cppObjectIsInvalid(PyObject* wrapper)
return true;
}
+void setTypeUserData(SbkBaseWrapper* wrapper, void *user_data, DeleteUserDataFunc d_func)
+{
+ SbkBaseWrapperType* ob_type = reinterpret_cast<SbkBaseWrapperType*>(wrapper->ob_type);
+ if (ob_type->user_data)
+ ob_type->d_func(ob_type->user_data);
+
+ ob_type->d_func = d_func;
+ ob_type->user_data = user_data;
+}
+
+void* getTypeUserData(SbkBaseWrapper* wrapper)
+{
+ return reinterpret_cast<SbkBaseWrapperType*>(wrapper->ob_type)->user_data;
+}
+
void deallocWrapperWithPrivateDtor(PyObject* self)
{
if (((SbkBaseWrapper *)self)->weakreflist)
@@ -303,7 +318,9 @@ static void deallocPythonTypes(PyObject* pyObj)
delete[] sbkObj->cptr;
sbkObj->cptr = 0;
+
Py_TYPE(pyObj)->tp_free(pyObj);
+
}
void deallocWrapper(PyObject* pyObj)
@@ -328,6 +345,16 @@ void deallocWrapper(PyObject* pyObj)
Py_TYPE(pyObj)->tp_free(pyObj);
}
+void SbkBaseWrapperType_dealloc(PyObject* pyObj)
+{
+ SbkBaseWrapperType *sbkType = reinterpret_cast<SbkBaseWrapperType*>(pyObj->ob_type);
+
+ if(sbkType->user_data && sbkType->d_func) {
+ sbkType->d_func(sbkType->user_data);
+ sbkType->user_data = 0;
+ }
+}
+
static PyObject*
SbkBaseWrapperType_TpNew(PyTypeObject* metatype, PyObject* args, PyObject* kwds)
{
@@ -362,17 +389,21 @@ SbkBaseWrapperType_TpNew(PyTypeObject* metatype, PyObject* args, PyObject* kwds)
newType->cpp_dtor = 0;
newType->is_multicpp = 1;
}
+ newType->user_data = 0;
+ newType->d_func = 0;
newType->is_user_type = 1;
return reinterpret_cast<PyObject*>(newType);
}
+
+
PyTypeObject SbkBaseWrapperType_Type = {
PyObject_HEAD_INIT(0)
/*ob_size*/ 0,
/*tp_name*/ "Shiboken.BaseWrapperType",
/*tp_basicsize*/ sizeof(SbkBaseWrapperType),
/*tp_itemsize*/ 0,
- /*tp_dealloc*/ 0,
+ /*tp_dealloc*/ SbkBaseWrapperType_dealloc,
/*tp_print*/ 0,
/*tp_getattr*/ 0,
/*tp_setattr*/ 0,
diff --git a/libshiboken/basewrapper.h b/libshiboken/basewrapper.h
index 168d3f43f..b6a9b7950 100644
--- a/libshiboken/basewrapper.h
+++ b/libshiboken/basewrapper.h
@@ -68,6 +68,9 @@ typedef std::list<TypeDiscoveryFunc> TypeDiscoveryFuncList;
typedef void* (*ExtendedToCppFunc)(PyObject*);
typedef bool (*ExtendedIsConvertibleFunc)(PyObject*);
+// Used in userdata dealloc function
+typedef void (*DeleteUserDataFunc)(void*);
+
LIBSHIBOKEN_API PyAPI_DATA(PyTypeObject) SbkBaseWrapperType_Type;
LIBSHIBOKEN_API PyAPI_DATA(SbkBaseWrapperType) SbkBaseWrapper_Type;
@@ -99,6 +102,9 @@ struct LIBSHIBOKEN_API SbkBaseWrapperType
int is_multicpp:1;
/// True if this type was definied by the user.
int is_user_type:1;
+ /// Type user data
+ void *user_data;
+ DeleteUserDataFunc d_func;
};
struct ParentInfo;
@@ -179,6 +185,13 @@ LIBSHIBOKEN_API void* getCppPointer(PyObject* wrapper, PyTypeObject* desiredType
LIBSHIBOKEN_API bool setCppPointer(SbkBaseWrapper* wrapper, PyTypeObject* desiredType, void* cptr);
/**
+ * Get/Set Userdata in type class
+ */
+LIBSHIBOKEN_API void setTypeUserData(SbkBaseWrapper* wrapper, void* user_data, DeleteUserDataFunc d_func);
+LIBSHIBOKEN_API void* getTypeUserData(SbkBaseWrapper* wrapper);
+
+
+/**
* Shiboken_TypeCheck macro performs a type check using the values registered with SbkType<>() template.
*/
#define Shiboken_TypeCheck(pyobj, type) (PyObject_TypeCheck(pyobj, SbkType<type>()))