summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHugo Parente Lima <hugo.pl@gmail.com>2010-11-09 16:47:12 -0200
committerHugo Parente Lima <hugo.pl@gmail.com>2010-11-10 15:36:28 -0200
commit6280785f538dc033e85826bf2525848c75327ea8 (patch)
treea24b0d0a9f7357a1357b23e24a4de1230c3e9234
parentc948d05782056d9b12ab0ccf04fa4e1b30478296 (diff)
downloadshiboken-6280785f538dc033e85826bf2525848c75327ea8.tar.gz
shiboken-6280785f538dc033e85826bf2525848c75327ea8.tar.xz
shiboken-6280785f538dc033e85826bf2525848c75327ea8.zip
Moved Shiboken::SbkBaseWrapper outside Shiboken namespace and added a d-pointer to it.
-rw-r--r--generator/cppgenerator.cpp12
-rw-r--r--libshiboken/basewrapper.cpp123
-rw-r--r--libshiboken/basewrapper.h66
-rw-r--r--libshiboken/basewrapper_p.h77
-rw-r--r--libshiboken/bindingmanager.cpp24
-rw-r--r--libshiboken/bindingmanager.h5
-rw-r--r--libshiboken/conversions.h4
7 files changed, 182 insertions, 129 deletions
diff --git a/generator/cppgenerator.cpp b/generator/cppgenerator.cpp
index e7f0e428..fe623953 100644
--- a/generator/cppgenerator.cpp
+++ b/generator/cppgenerator.cpp
@@ -779,13 +779,13 @@ void CppGenerator::writeMetaObjectMethod(QTextStream& s, const AbstractMetaClass
{
Indentation indentation(INDENT);
s << INDENT << "PyObject *pySelf = BindingManager::instance().retrieveWrapper(this);\n"
- << INDENT << "void *typeData = Shiboken::getTypeUserData(reinterpret_cast<Shiboken::SbkBaseWrapper*>(pySelf));" << endl
+ << INDENT << "void *typeData = Shiboken::getTypeUserData(reinterpret_cast<SbkBaseWrapper*>(pySelf));" << endl
<< INDENT << "if (!typeData) {" << endl;
{
Indentation indentation2(INDENT);
s << INDENT << "m_metaObject = PySide::DynamicQMetaObject::createBasedOn(pySelf, pySelf->ob_type, &"
<< metaClass->qualifiedCppName() << "::staticMetaObject);" << endl
- << INDENT << "Shiboken::setTypeUserData(reinterpret_cast<Shiboken::SbkBaseWrapper*>(pySelf), m_metaObject, PySide::deleteDynamicQMetaObject);" << endl;
+ << INDENT << "Shiboken::setTypeUserData(reinterpret_cast<SbkBaseWrapper*>(pySelf), m_metaObject, PySide::deleteDynamicQMetaObject);" << endl;
}
s << INDENT << "} else {" << endl;
{
@@ -927,13 +927,13 @@ void CppGenerator::writeConstructorWrapper(QTextStream& s, const AbstractMetaFun
s << endl;
}
- s << INDENT << "sbkSelf->validCppObject = 1;" << endl;
+ s << INDENT << "Shiboken::Wrapper::setValidCpp(sbkSelf, true);" << endl;
// If the created C++ object has a C++ wrapper the ownership is assigned to Python
// (first "1") and the flag indicating that the Python wrapper holds an C++ wrapper
// is marked as true (the second "1"). Otherwise the default values apply:
// Python owns it and C++ wrapper is false.
if (shouldGenerateCppWrapper(overloads.first()->ownerClass()))
- s << INDENT << "sbkSelf->containsCppWrapper = 1;" << endl;
+ s << INDENT << "Shiboken::Wrapper::setHasCppWrapper(sbkSelf, true);" << endl;
s << INDENT << "BindingManager::instance().registerWrapper(sbkSelf, cptr);" << endl;
// Create metaObject and register signal/slot
@@ -1843,7 +1843,7 @@ void CppGenerator::writeMethodCall(QTextStream& s, const AbstractMetaFunction* f
}
if (func->isAbstract()) {
- s << INDENT << "if (SbkBaseWrapper_containsCppWrapper(self)) {\n";
+ s << INDENT << "if (Shiboken::Wrapper::hasCppWrapper(reinterpret_cast<SbkBaseWrapper*>(self))) {\n";
{
Indentation indent(INDENT);
s << INDENT << "PyErr_SetString(PyExc_NotImplementedError, \"pure virtual method '";
@@ -2429,7 +2429,7 @@ void CppGenerator::writeClassDefinition(QTextStream& s, const AbstractMetaClass*
s << INDENT << "PyObject_HEAD_INIT(&Shiboken::SbkBaseWrapperType_Type)" << endl;
s << INDENT << "/*ob_size*/ 0," << endl;
s << INDENT << "/*tp_name*/ \"" << metaClass->fullName() << "\"," << endl;
- s << INDENT << "/*tp_basicsize*/ sizeof(Shiboken::SbkBaseWrapper)," << endl;
+ s << INDENT << "/*tp_basicsize*/ sizeof(SbkBaseWrapper)," << endl;
s << INDENT << "/*tp_itemsize*/ 0," << endl;
s << INDENT << "/*tp_dealloc*/ " << tp_dealloc << ',' << endl;
s << INDENT << "/*tp_print*/ 0," << endl;
diff --git a/libshiboken/basewrapper.cpp b/libshiboken/basewrapper.cpp
index ae5b6dda..0e2e7871 100644
--- a/libshiboken/basewrapper.cpp
+++ b/libshiboken/basewrapper.cpp
@@ -165,11 +165,11 @@ SbkBaseWrapperType SbkBaseWrapper_Type = { { {
void removeParent(SbkBaseWrapper* child)
{
- ParentInfo* pInfo = child->parentInfo;
+ ParentInfo* pInfo = child->d->parentInfo;
if (!pInfo || !pInfo->parent)
return;
- ChildrenList& oldBrothers = pInfo->parent->parentInfo->children;
+ ChildrenList& oldBrothers = pInfo->parent->d->parentInfo->children;
oldBrothers.remove(child);
pInfo->parent = 0;
@@ -205,15 +205,15 @@ void setParent(PyObject* parent, PyObject* child)
SbkBaseWrapper* child_ = reinterpret_cast<SbkBaseWrapper*>(child);
if (!parentIsNull) {
- if (!parent_->parentInfo)
- parent_->parentInfo = new ParentInfo;
+ if (!parent_->d->parentInfo)
+ parent_->d->parentInfo = new ParentInfo;
// do not re-add a child
- ChildrenList& children = parent_->parentInfo->children;
+ ChildrenList& children = parent_->d->parentInfo->children;
if (std::find(children.begin(), children.end(), child_) != children.end())
return;
}
- ParentInfo* pInfo = child_->parentInfo;
+ ParentInfo* pInfo = child_->d->parentInfo;
bool hasAnotherParent = pInfo && pInfo->parent && pInfo->parent != parent_;
//Avoid destroy child during reparent operation
@@ -224,12 +224,12 @@ void setParent(PyObject* parent, PyObject* child)
removeParent(child_);
// Add the child to the new parent
- pInfo = child_->parentInfo;
+ pInfo = child_->d->parentInfo;
if (!parentIsNull) {
if (!pInfo)
- pInfo = child_->parentInfo = new ParentInfo;
+ pInfo = child_->d->parentInfo = new ParentInfo;
pInfo->parent = parent_;
- parent_->parentInfo->children.push_back(child_);
+ parent_->d->parentInfo->children.push_back(child_);
Py_INCREF(child_);
}
@@ -238,7 +238,7 @@ void setParent(PyObject* parent, PyObject* child)
static void _destroyParentInfo(SbkBaseWrapper* obj, bool removeFromParent)
{
- ParentInfo* pInfo = obj->parentInfo;
+ ParentInfo* pInfo = obj->d->parentInfo;
if (removeFromParent && pInfo && pInfo->parent)
removeParent(obj);
@@ -248,11 +248,9 @@ static void _destroyParentInfo(SbkBaseWrapper* obj, bool removeFromParent)
SbkBaseWrapper*& child = *it;
// keep this, the wrapper still alive
- if (!SbkBaseWrapper_containsCppWrapper(obj) &&
- SbkBaseWrapper_containsCppWrapper(child) &&
- child->parentInfo) {
- child->parentInfo->parent = 0;
- child->parentInfo->hasWrapperRef = true;
+ if (!obj->d->containsCppWrapper && child->d->containsCppWrapper && child->d->parentInfo) {
+ child->d->parentInfo->parent = 0;
+ child->d->parentInfo->hasWrapperRef = true;
SbkBaseWrapper_setOwnership(child, false);
} else {
_destroyParentInfo(child, false);
@@ -260,7 +258,7 @@ static void _destroyParentInfo(SbkBaseWrapper* obj, bool removeFromParent)
}
}
delete pInfo;
- obj->parentInfo = 0;
+ obj->d->parentInfo = 0;
}
}
@@ -288,9 +286,9 @@ PyObject* SbkBaseWrapper_New(SbkBaseWrapperType* instanceType,
}
SbkBaseWrapper* self = reinterpret_cast<SbkBaseWrapper*>(SbkBaseWrapper_TpNew(reinterpret_cast<PyTypeObject*>(instanceType), 0, 0));
- self->cptr[0] = cptr;
- self->hasOwnership = hasOwnership;
- self->validCppObject = 1;
+ self->d->cptr[0] = cptr;
+ self->d->hasOwnership = hasOwnership;
+ self->d->validCppObject = 1;
BindingManager::instance().registerWrapper(self, cptr);
return reinterpret_cast<PyObject*>(self);
}
@@ -319,18 +317,19 @@ void walkThroughClassHierarchy(PyTypeObject* currentType, HierarchyVisitor* visi
PyObject* SbkBaseWrapper_TpNew(PyTypeObject* subtype, PyObject*, PyObject*)
{
SbkBaseWrapper* self = reinterpret_cast<SbkBaseWrapper*>(subtype->tp_alloc(subtype, 0));
+ self->d = new SbkBaseWrapperPrivate;
SbkBaseWrapperType* sbkType = reinterpret_cast<SbkBaseWrapperType*>(subtype);
int numBases = sbkType->is_multicpp ? getNumberOfCppBaseClasses(subtype) : 1;
- self->cptr = new void*[numBases];
- std::memset(self->cptr, 0, sizeof(void*)*numBases);
- self->hasOwnership = 1;
- self->containsCppWrapper = 0;
- self->validCppObject = 0;
- self->parentInfo = 0;
+ self->d->cptr = new void*[numBases];
+ std::memset(self->d->cptr, 0, sizeof(void*)*numBases);
+ self->d->hasOwnership = 1;
+ self->d->containsCppWrapper = 0;
+ self->d->validCppObject = 0;
+ self->d->parentInfo = 0;
self->ob_dict = 0;
self->weakreflist = 0;
- self->referredObjects = 0;
+ self->d->referredObjects = 0;
return reinterpret_cast<PyObject*>(self);
}
@@ -340,7 +339,7 @@ void* getCppPointer(PyObject* wrapper, PyTypeObject* desiredType)
int idx = 0;
if (reinterpret_cast<SbkBaseWrapperType*>(type)->is_multicpp)
idx = getTypeIndexOnHierarchy(type, desiredType);
- return reinterpret_cast<Shiboken::SbkBaseWrapper*>(wrapper)->cptr[idx];
+ return reinterpret_cast<SbkBaseWrapper*>(wrapper)->d->cptr[idx];
}
bool setCppPointer(SbkBaseWrapper* wrapper, PyTypeObject* desiredType, void* cptr)
@@ -349,11 +348,11 @@ bool setCppPointer(SbkBaseWrapper* wrapper, PyTypeObject* desiredType, void* cpt
if (reinterpret_cast<SbkBaseWrapperType*>(wrapper->ob_type)->is_multicpp)
idx = getTypeIndexOnHierarchy(wrapper->ob_type, desiredType);
- bool alreadyInitialized = wrapper->cptr[idx];
+ bool alreadyInitialized = wrapper->d->cptr[idx];
if (alreadyInitialized)
PyErr_SetString(PyExc_RuntimeError, "You can't initialize an object twice!");
else
- wrapper->cptr[idx] = cptr;
+ wrapper->d->cptr[idx] = cptr;
return !alreadyInitialized;
}
@@ -362,7 +361,7 @@ bool cppObjectIsInvalid(PyObject* wrapper)
{
if (!wrapper || wrapper == Py_None
|| wrapper->ob_type->ob_type != &Shiboken::SbkBaseWrapperType_Type
- || ((Shiboken::SbkBaseWrapper*)wrapper)->validCppObject) {
+ || ((SbkBaseWrapper*)wrapper)->d->validCppObject) {
return false;
}
PyErr_SetString(PyExc_RuntimeError, "Internal C++ object already deleted.");
@@ -399,10 +398,10 @@ void keepReference(SbkBaseWrapper* self, const char* key, PyObject* referredObje
bool isNone = (!referredObject || (referredObject == Py_None));
- if (!self->referredObjects)
- self->referredObjects = new Shiboken::RefCountMap;
+ if (!self->d->referredObjects)
+ self->d->referredObjects = new Shiboken::RefCountMap;
- RefCountMap& refCountMap = *(self->referredObjects);
+ RefCountMap& refCountMap = *(self->d->referredObjects);
if (!isNone)
incRefPyObject(referredObject);
@@ -423,15 +422,15 @@ void keepReference(SbkBaseWrapper* self, const char* key, PyObject* referredObje
void clearReferences(SbkBaseWrapper* self)
{
- if (!self->referredObjects)
+ if (!self->d->referredObjects)
return;
- RefCountMap& refCountMap = *(self->referredObjects);
+ RefCountMap& refCountMap = *(self->d->referredObjects);
RefCountMap::iterator iter;
for (iter = refCountMap.begin(); iter != refCountMap.end(); ++iter)
decRefPyObjectlist(iter->second);
- delete self->referredObjects;
- self->referredObjects = 0;
+ delete self->d->referredObjects;
+ self->d->referredObjects = 0;
}
bool importModule(const char* moduleName, PyTypeObject*** cppApiPtr)
@@ -458,7 +457,7 @@ public:
DtorCallerVisitor(SbkBaseWrapper* pyObj) : m_count(0), m_pyObj(pyObj) {}
virtual void visit(SbkBaseWrapperType* node)
{
- node->cpp_dtor(m_pyObj->cptr[m_count]);
+ node->cpp_dtor(m_pyObj->d->cptr[m_count]);
m_count++;
}
private:
@@ -473,24 +472,25 @@ void deallocWrapper(PyObject* pyObj)
PyObject_ClearWeakRefs(pyObj);
BindingManager::instance().releaseWrapper(pyObj);
- if (SbkBaseWrapper_hasOwnership(pyObj)) {
+ if (sbkObj->d->hasOwnership) {
SbkBaseWrapperType* sbkType = reinterpret_cast<SbkBaseWrapperType*>(pyObj->ob_type);
if (sbkType->is_multicpp) {
DtorCallerVisitor visitor(sbkObj);
walkThroughClassHierarchy(pyObj->ob_type, &visitor);
} else {
- sbkType->cpp_dtor(sbkObj->cptr[0]);
+ sbkType->cpp_dtor(sbkObj->d->cptr[0]);
}
}
- if (SbkBaseWrapper_hasParentInfo(pyObj))
+ if (sbkObj->d->parentInfo)
destroyParentInfo(sbkObj);
clearReferences(sbkObj);
Py_XDECREF(sbkObj->ob_dict);
- delete[] sbkObj->cptr;
- sbkObj->cptr = 0;
+ delete[] sbkObj->d->cptr;
+ sbkObj->d->cptr = 0;
+ delete sbkObj->d;
Py_TYPE(pyObj)->tp_free(pyObj);
}
@@ -645,7 +645,9 @@ std::list<PyObject*> splitPyObject(PyObject* pyObj)
if (PySequence_Check(pyObj)) {
AutoDecRef lst(PySequence_Fast(pyObj, "Invalid keep reference object."));
for(int i = 0, i_max = PySequence_Fast_GET_SIZE(lst.object()); i < i_max; i++) {
- result.push_back(PySequence_Fast_GET_ITEM(lst.object(), i));
+ PyObject* item = PySequence_Fast_GET_ITEM(lst.object(), i);
+ if (isShibokenType(item))
+ result.push_back(item);
}
} else {
result.push_back(pyObj);
@@ -675,17 +677,40 @@ static void decRefPyObjectlist(const std::list<PyObject*> &lst)
void SbkBaseWrapper_setOwnership(SbkBaseWrapper* pyobj, bool owner)
{
- pyobj->hasOwnership = owner;
+ pyobj->d->hasOwnership = owner;
}
void SbkBaseWrapper_setOwnership(PyObject* pyobj, bool owner)
{
- std::list<PyObject*> objs = splitPyObject(pyobj);
- std::list<PyObject*>::const_iterator it;
- for(it=objs.begin(); it != objs.end(); it++)
- SbkBaseWrapper_setOwnership(reinterpret_cast<SbkBaseWrapper*>(*it), owner);
+ if (PySequence_Check(pyobj)) {
+ std::list<PyObject*> objs = splitPyObject(pyobj);
+ std::list<PyObject*>::const_iterator it;
+ for(it=objs.begin(); it != objs.end(); it++)
+ SbkBaseWrapper_setOwnership(reinterpret_cast<SbkBaseWrapper*>(*it), owner);
+ } else if (isShibokenType(pyobj)) {
+ SbkBaseWrapper_setOwnership(reinterpret_cast<SbkBaseWrapper*>(pyobj), owner);
+ }
+}
+
+namespace Wrapper
+{
+
+void setValidCpp(SbkBaseWrapper* pyObj, bool value)
+{
+ pyObj->d->validCppObject = value;
+}
+
+void setHasCppWrapper(SbkBaseWrapper* pyObj, bool value)
+{
+ pyObj->d->containsCppWrapper = value;
+}
+
+bool hasCppWrapper(SbkBaseWrapper* pyObj)
+{
+ return pyObj->d->containsCppWrapper;
}
+} // namespace Wrapper
} // namespace Shiboken
diff --git a/libshiboken/basewrapper.h b/libshiboken/basewrapper.h
index 2440a98c..75fa9040 100644
--- a/libshiboken/basewrapper.h
+++ b/libshiboken/basewrapper.h
@@ -30,14 +30,26 @@
#include <map>
#include <string>
-namespace Shiboken
+extern "C"
{
-/**
- * This mapping associates a method and argument of an wrapper object with the wrapper of
- * said argument when it needs the binding to help manage its reference counting.
- */
-typedef std::map<std::string, std::list<PyObject*> > RefCountMap;
+struct SbkBaseWrapperPrivate;
+
+/// Base Python object for all the wrapped C++ classes.
+struct LIBSHIBOKEN_API SbkBaseWrapper
+{
+ PyObject_HEAD
+ /// Instance dictionary.
+ PyObject* ob_dict;
+ /// List of weak references
+ PyObject* weakreflist;
+ SbkBaseWrapperPrivate* d;
+};
+
+}
+
+namespace Shiboken
+{
extern "C"
{
@@ -90,30 +102,6 @@ struct LIBSHIBOKEN_API SbkBaseWrapperType
DeleteUserDataFunc d_func;
};
-struct ParentInfo;
-
-/// Base Python object for all the wrapped C++ classes.
-struct LIBSHIBOKEN_API SbkBaseWrapper
-{
- PyObject_HEAD
- /// Pointer to the C++ class.
- void** cptr;
- /// Instance dictionary.
- PyObject* ob_dict;
- /// True when Python is responsible for freeing the used memory.
- unsigned int hasOwnership : 1;
- /// Is true when the C++ class of the wrapped object has a virtual destructor AND was created by Python.
- unsigned int containsCppWrapper : 1;
- /// Marked as false when the object is lost to C++ and the binding can not know if it was deleted or not.
- unsigned int validCppObject : 1;
- /// Information about the object parents and children, can be null.
- ParentInfo* parentInfo;
- /// List of weak references
- PyObject* weakreflist;
- /// Manage reference counting of objects that are referred but not owned.
- RefCountMap* referredObjects;
-};
-
} // extern "C"
/**
@@ -187,14 +175,8 @@ LIBSHIBOKEN_API bool canCallConstructor(PyTypeObject* myType, PyTypeObject* ctor
#define SbkBaseWrapper_Check(op) PyObject_TypeCheck(op, (PyTypeObject*)&Shiboken::SbkBaseWrapper_Type)
#define SbkBaseWrapper_CheckExact(op) ((op)->ob_type == &Shiboken::SbkBaseWrapper_Type)
-#define SbkBaseWrapper_instanceDict(pyobj) (((Shiboken::SbkBaseWrapper*)pyobj)->ob_dict)
-#define SbkBaseWrapper_setInstanceDict(pyobj,d) (((Shiboken::SbkBaseWrapper*)pyobj)->ob_dict = d)
-#define SbkBaseWrapper_hasOwnership(pyobj) (((Shiboken::SbkBaseWrapper*)pyobj)->hasOwnership)
-#define SbkBaseWrapper_hasParentInfo(pyobj) (((Shiboken::SbkBaseWrapper*)pyobj)->parentInfo)
-#define SbkBaseWrapper_containsCppWrapper(pyobj) (((Shiboken::SbkBaseWrapper*)pyobj)->containsCppWrapper)
-#define SbkBaseWrapper_setContainsCppWrapper(pyobj,o)(((Shiboken::SbkBaseWrapper*)pyobj)->containsCppWrapper = o)
-#define SbkBaseWrapper_validCppObject(pyobj) (((Shiboken::SbkBaseWrapper*)pyobj)->validCppObject)
-#define SbkBaseWrapper_setValidCppObject(pyobj,v) (((Shiboken::SbkBaseWrapper*)pyobj)->validCppObject = v)
+#define SbkBaseWrapper_instanceDict(pyobj) (((SbkBaseWrapper*)pyobj)->ob_dict)
+#define SbkBaseWrapper_setInstanceDict(pyobj,d) (((SbkBaseWrapper*)pyobj)->ob_dict = d)
LIBSHIBOKEN_API PyObject*
SbkBaseWrapper_New(SbkBaseWrapperType* instanceType,
@@ -241,6 +223,14 @@ LIBSHIBOKEN_API void setErrorAboutWrongArguments(PyObject* args, const char* fun
LIBSHIBOKEN_API void SbkBaseWrapper_setOwnership(PyObject* pyobj, bool owner);
LIBSHIBOKEN_API void SbkBaseWrapper_setOwnership(SbkBaseWrapper* pyobj, bool owner);
+namespace Wrapper {
+
+LIBSHIBOKEN_API void setValidCpp(SbkBaseWrapper* pyObj, bool value);
+LIBSHIBOKEN_API void setHasCppWrapper(SbkBaseWrapper* pyObj, bool value);
+LIBSHIBOKEN_API bool hasCppWrapper(SbkBaseWrapper* pyObj);
+
+} // namespace Wrapper
+
} // namespace Shiboken
#endif // BASEWRAPPER_H
diff --git a/libshiboken/basewrapper_p.h b/libshiboken/basewrapper_p.h
index 20476d3a..a07f5482 100644
--- a/libshiboken/basewrapper_p.h
+++ b/libshiboken/basewrapper_p.h
@@ -25,11 +25,66 @@
#include <Python.h>
#include <list>
+#include <map>
+
+struct SbkBaseWrapper;
+
+namespace Shiboken
+{
+/**
+ * This mapping associates a method and argument of an wrapper object with the wrapper of
+ * said argument when it needs the binding to help manage its reference counting.
+ */
+typedef std::map<std::string, std::list<PyObject*> > RefCountMap;
+
+
+/// Linked list of SbkBaseWrapper pointers
+typedef std::list<SbkBaseWrapper*> ChildrenList;
+
+/// Struct used to store information about object parent and children.
+struct ParentInfo
+{
+ /// Default ctor.
+ ParentInfo() : parent(0), hasWrapperRef(false) {}
+ /// Pointer to parent object.
+ SbkBaseWrapper* parent;
+ /// List of object children.
+ ChildrenList children;
+ /// has internal ref
+ bool hasWrapperRef;
+};
+
+} // namespace Shiboken
+
+extern "C"
+{
+
+/**
+ * \internal
+ * Private data for SbkBaseWrapper
+ */
+struct SbkBaseWrapperPrivate
+{
+ /// Pointer to the C++ class.
+ void** cptr;
+ /// True when Python is responsible for freeing the used memory.
+ unsigned int hasOwnership : 1;
+ /// Is true when the C++ class of the wrapped object has a virtual destructor AND was created by Python.
+ unsigned int containsCppWrapper : 1;
+ /// Marked as false when the object is lost to C++ and the binding can not know if it was deleted or not.
+ unsigned int validCppObject : 1;
+ /// Information about the object parents and children, can be null.
+ Shiboken::ParentInfo* parentInfo;
+ /// Manage reference counting of objects that are referred but not owned.
+ Shiboken::RefCountMap* referredObjects;
+};
+
+} // extern "C"
namespace Shiboken
{
/**
- * Utility function uset to transform PyObject which suppot sequence protocol in a std::list
+ * Utility function uset to transform PyObject which suppot sequence protocol in a std::list
**/
std::list<PyObject*> splitPyObject(PyObject* pyObj);
@@ -126,30 +181,12 @@ inline std::list<SbkBaseWrapperType*> getCppBaseClasses(PyTypeObject* baseType)
return visitor.bases();
}
-struct SbkBaseWrapper;
-
-/// Linked list of SbkBaseWrapper pointers
-typedef std::list<SbkBaseWrapper*> ChildrenList;
-
-/// Struct used to store information about object parent and children.
-struct ParentInfo
-{
- /// Default ctor.
- ParentInfo() : parent(0), hasWrapperRef(false) {}
- /// Pointer to parent object.
- SbkBaseWrapper* parent;
- /// List of object children.
- ChildrenList children;
- /// has internal ref
- bool hasWrapperRef;
-};
-
/**
* Decrements the reference counters of every object referred by self.
* \param self the wrapper instance that keeps references to other objects.
*/
void clearReferences(SbkBaseWrapper* self);
-}
+} // namespace Shiboken
#endif
diff --git a/libshiboken/bindingmanager.cpp b/libshiboken/bindingmanager.cpp
index 38dc4eb8..22bfde74 100644
--- a/libshiboken/bindingmanager.cpp
+++ b/libshiboken/bindingmanager.cpp
@@ -184,7 +184,7 @@ void BindingManager::releaseWrapper(PyObject* wrapper)
SbkBaseWrapperType* sbkType = reinterpret_cast<SbkBaseWrapperType*>(wrapper->ob_type);
int numBases = sbkType->is_multicpp ? getNumberOfCppBaseClasses(wrapper->ob_type) : 1;
- void** cptrs = reinterpret_cast<SbkBaseWrapper*>(wrapper)->cptr;
+ void** cptrs = reinterpret_cast<SbkBaseWrapper*>(wrapper)->d->cptr;
for (int i = 0; i < numBases; ++i) {
void* cptr = cptrs[i];
m_d->releaseWrapper(cptr);
@@ -258,32 +258,32 @@ void BindingManager::invalidateWrapper(PyObject* pyobj)
void BindingManager::invalidateWrapper(SbkBaseWrapper* wrapper)
{
- if (!wrapper || ((PyObject*)wrapper == Py_None) || !SbkBaseWrapper_validCppObject(wrapper))
+ if (!wrapper || ((PyObject*)wrapper == Py_None) || !wrapper->d->validCppObject)
return;
GilState gil; // lock the gil to assure no one is changing the value of m_d->destroying
// skip this if the object is a wrapper class and this is not a destructor call
- if (SbkBaseWrapper_containsCppWrapper(wrapper) && !m_d->destroying) {
- ParentInfo* pInfo = wrapper->parentInfo;
+ if (wrapper->d->containsCppWrapper && !m_d->destroying) {
+ ParentInfo* pInfo = wrapper->d->parentInfo;
// this meaning the object has a extra ref and we will remove this now
if (pInfo && pInfo->hasWrapperRef) {
delete pInfo;
- wrapper->parentInfo = 0;
+ wrapper->d->parentInfo = 0;
Py_XDECREF((PyObject*) wrapper);
}
return;
}
- SbkBaseWrapper_setValidCppObject(wrapper, false);
- SbkBaseWrapper_setOwnership(wrapper, false);
+ wrapper->d->validCppObject = false;
+ wrapper->d->hasOwnership = false;
// If it is a parent invalidate all children.
- if (SbkBaseWrapper_hasParentInfo(wrapper)) {
- ChildrenList::iterator it = wrapper->parentInfo->children.begin();
+ if (wrapper->d->parentInfo) {
+ ChildrenList::iterator it = wrapper->d->parentInfo->children.begin();
bool parentDestroying = m_d->destroying;
m_d->destroying = false;
- for (; it != wrapper->parentInfo->children.end(); ++it)
+ for (; it != wrapper->d->parentInfo->children.end(); ++it)
invalidateWrapper(*it);
m_d->destroying = parentDestroying;
}
@@ -323,10 +323,10 @@ void BindingManager::transferOwnershipToCpp(PyObject* wrapper)
void BindingManager::transferOwnershipToCpp(SbkBaseWrapper* wrapper)
{
- if (wrapper->parentInfo)
+ if (wrapper->d->parentInfo)
Shiboken::removeParent(wrapper);
- if (SbkBaseWrapper_containsCppWrapper(wrapper))
+ if (wrapper->d->containsCppWrapper)
SbkBaseWrapper_setOwnership(wrapper, false);
else
invalidateWrapper(wrapper);
diff --git a/libshiboken/bindingmanager.h b/libshiboken/bindingmanager.h
index d7cec27b..b5bf43b6 100644
--- a/libshiboken/bindingmanager.h
+++ b/libshiboken/bindingmanager.h
@@ -27,10 +27,11 @@
#include <set>
#include "shibokenmacros.h"
+struct SbkBaseWrapper;
+
namespace Shiboken
{
-struct SbkBaseWrapper;
struct SbkBaseWrapperType;
class LIBSHIBOKEN_API BindingManager
@@ -40,7 +41,7 @@ public:
bool hasWrapper(const void *cptr);
- void registerWrapper( Shiboken::SbkBaseWrapper* pyobj, void* cptr);
+ void registerWrapper(SbkBaseWrapper* pyobj, void* cptr);
void releaseWrapper(PyObject* wrapper);
PyObject* retrieveWrapper(const void* cptr);
PyObject* getOverride(const void* cptr, const char* methodName);
diff --git a/libshiboken/conversions.h b/libshiboken/conversions.h
index 67e62792..b077e2f2 100644
--- a/libshiboken/conversions.h
+++ b/libshiboken/conversions.h
@@ -223,8 +223,8 @@ struct ValueTypeConverter
static inline PyObject* toPython(void* cppobj) { return toPython(*reinterpret_cast<T*>(cppobj)); }
static inline PyObject* toPython(const T& cppobj)
{
- PyObject* obj = createWrapper<T>(CppObjectCopier<T>::copy(cppobj), true, true);
- SbkBaseWrapper_setContainsCppWrapper(obj, SbkTypeInfo<T>::isCppWrapper);
+ PyObject* obj = createWrapper<T>(new T(cppobj), true, true);
+// SbkBaseWrapper_setContainsCppWrapper(obj, SbkTypeInfo<T>::isCppWrapper);
return obj;
}
// Classes with implicit conversions are expected to reimplement 'toCpp' to build T from