From 4f23b569b3f9ad0f3fbf3cfe2a1b0267a97e1c3e Mon Sep 17 00:00:00 2001 From: wmayer Date: Tue, 14 Feb 2017 13:09:09 +0100 Subject: [PATCH] issue #0002902: replace members of PyObjectBase with a PyDictObject --- src/Base/PyObjectBase.cpp | 74 +++++++++++++++++++-------------------- src/Base/PyObjectBase.h | 13 ++++--- 2 files changed, 45 insertions(+), 42 deletions(-) diff --git a/src/Base/PyObjectBase.cpp b/src/Base/PyObjectBase.cpp index 8ae349253..a3571ba90 100644 --- a/src/Base/PyObjectBase.cpp +++ b/src/Base/PyObjectBase.cpp @@ -37,7 +37,7 @@ PyObject* Base::BaseExceptionFreeCADError = 0; // Constructor PyObjectBase::PyObjectBase(void* p,PyTypeObject *T) - : _pcTwinPointer(p), parent(0), attribute(0) + : _pcTwinPointer(p), attrDict(0) { this->ob_type = T; _Py_NewReference(this); @@ -53,10 +53,7 @@ PyObjectBase::~PyObjectBase() #ifdef FC_LOGPYOBJECTS Base::Console().Log("PyO-: %s (%p)\n",this->ob_type->tp_name, this); #endif - if (this->parent) - this->parent->DecRef(); - if (this->attribute) - free(this->attribute); /* it's a strdup */ + Py_XDECREF(attrDict); } /*------------------------------ @@ -278,48 +275,51 @@ PyObject *PyObjectBase::_repr(void) void PyObjectBase::resetAttribute() { - if (this->attribute) { - free(this->attribute); - this->attribute = 0; - } - if (this->parent) { - Py_DECREF(this->parent); - this->parent = 0; + if (attrDict) { + // This is the attribute name to the parent structure + // which we search for in the dict + PyObject* key = PyString_FromString("__attribute_of_parent__"); + PyObject* attr = PyDict_GetItem(attrDict, key); + if (attr) { + PyObject* parent = PyDict_GetItem(attrDict, attr); + if (parent) { + PyDict_DelItem(attrDict, attr); + } + PyDict_DelItem(attrDict, key); + } + Py_DECREF(key); } } void PyObjectBase::setAttributeOf(const char* attr, const PyObjectBase* par) { - if (this->parent != par) { - Py_XDECREF(this->parent); - this->parent = const_cast(par); - Py_XINCREF(this->parent); + if (!attrDict) { + attrDict = PyDict_New(); } - if (this->attribute) { - if (strcmp(this->attribute, attr) != 0) { - free(this->attribute); -#if defined (__GNUC__) - this->attribute = strdup(attr); -#else - this->attribute = _strdup(attr); -#endif - } - } - else { -#if defined (__GNUC__) - this->attribute = strdup(attr); -#else - this->attribute = _strdup(attr); -#endif - } + PyObject* key = PyString_FromString("__attribute_of_parent__"); + PyObject* attro = PyString_FromString(attr); + PyDict_SetItem(attrDict, key, attro); + PyDict_SetItem(attrDict, attro, const_cast(par)); + Py_DECREF(attro); + Py_DECREF(key); } void PyObjectBase::startNotify() { - if (this->attribute && this->parent) { - __setattr(this->parent, this->attribute, this); - if (PyErr_Occurred()) - PyErr_Clear(); + if (attrDict) { + // This is the attribute name to the parent structure + // which we search for in the dict + PyObject* key = PyString_FromString("__attribute_of_parent__"); + PyObject* attr = PyDict_GetItem(attrDict, key); + if (attr) { + PyObject* parent = PyDict_GetItem(attrDict, attr); + if (parent) { + __setattr(parent, PyString_AsString(attr), this); + if (PyErr_Occurred()) + PyErr_Clear(); + } + } + Py_DECREF(key); } } diff --git a/src/Base/PyObjectBase.h b/src/Base/PyObjectBase.h index 62642e2c7..387c7c6cc 100644 --- a/src/Base/PyObjectBase.h +++ b/src/Base/PyObjectBase.h @@ -196,7 +196,6 @@ class BaseExport PyObjectBase : public PyObject protected: /// destructor virtual ~PyObjectBase(); - void resetAttribute(); public: /** Constructor @@ -292,17 +291,21 @@ public: return StatusBits.test(1); } - void setAttributeOf(const char* attr, const PyObjectBase* par); void startNotify(); - typedef void* PointerType ; + typedef void* PointerType; + +private: + void setAttributeOf(const char* attr, const PyObjectBase* par); + void resetAttribute(); protected: std::bitset<32> StatusBits; /// pointer to the handled class void * _pcTwinPointer; - PyObjectBase* parent; - char* attribute; + +private: + PyObject* attrDict; };