Replace PyObject_GetAttrString with direct type references
Replace ~230 occurrences of PyObject_GetAttrString(McRFPy_API::mcrf_module, "TypeName") with direct &mcrfpydef::PyXxxType references across 32 source files. Each PyObject_GetAttrString call returns a new reference. When used inline in PyObject_IsInstance(), that reference was immediately leaked. When used for tp_alloc, the reference required careful Py_DECREF management that was often missing on error paths. Direct type references are compile-time constants that never need reference counting, eliminating ~230 potential leak sites and removing ~100 lines of Py_DECREF/Py_XDECREF cleanup code. Also adds extractDrawable() helper in UICollection.cpp to replace repeated 8-way type-check-and-extract chains with a single function call. Closes #267, closes #268 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
348826a0f5
commit
71eb01c950
32 changed files with 249 additions and 944 deletions
|
|
@ -514,8 +514,7 @@ static PyObject* convertDrawableToPython(std::shared_ptr<UIDrawable> drawable) {
|
|||
switch (drawable->derived_type()) {
|
||||
case PyObjectsEnum::UIFRAME:
|
||||
{
|
||||
type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "Frame");
|
||||
if (!type) return nullptr;
|
||||
type = &mcrfpydef::PyUIFrameType;
|
||||
auto pyObj = (PyUIFrameObject*)type->tp_alloc(type, 0);
|
||||
if (pyObj) {
|
||||
pyObj->data = std::static_pointer_cast<UIFrame>(drawable);
|
||||
|
|
@ -526,8 +525,7 @@ static PyObject* convertDrawableToPython(std::shared_ptr<UIDrawable> drawable) {
|
|||
}
|
||||
case PyObjectsEnum::UICAPTION:
|
||||
{
|
||||
type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "Caption");
|
||||
if (!type) return nullptr;
|
||||
type = &mcrfpydef::PyUICaptionType;
|
||||
auto pyObj = (PyUICaptionObject*)type->tp_alloc(type, 0);
|
||||
if (pyObj) {
|
||||
pyObj->data = std::static_pointer_cast<UICaption>(drawable);
|
||||
|
|
@ -539,8 +537,7 @@ static PyObject* convertDrawableToPython(std::shared_ptr<UIDrawable> drawable) {
|
|||
}
|
||||
case PyObjectsEnum::UISPRITE:
|
||||
{
|
||||
type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "Sprite");
|
||||
if (!type) return nullptr;
|
||||
type = &mcrfpydef::PyUISpriteType;
|
||||
auto pyObj = (PyUISpriteObject*)type->tp_alloc(type, 0);
|
||||
if (pyObj) {
|
||||
pyObj->data = std::static_pointer_cast<UISprite>(drawable);
|
||||
|
|
@ -551,8 +548,7 @@ static PyObject* convertDrawableToPython(std::shared_ptr<UIDrawable> drawable) {
|
|||
}
|
||||
case PyObjectsEnum::UIGRID:
|
||||
{
|
||||
type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "Grid");
|
||||
if (!type) return nullptr;
|
||||
type = &mcrfpydef::PyUIGridType;
|
||||
auto pyObj = (PyUIGridObject*)type->tp_alloc(type, 0);
|
||||
if (pyObj) {
|
||||
pyObj->data = std::static_pointer_cast<UIGrid>(drawable);
|
||||
|
|
@ -563,8 +559,7 @@ static PyObject* convertDrawableToPython(std::shared_ptr<UIDrawable> drawable) {
|
|||
}
|
||||
case PyObjectsEnum::UILINE:
|
||||
{
|
||||
type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "Line");
|
||||
if (!type) return nullptr;
|
||||
type = &mcrfpydef::PyUILineType;
|
||||
auto pyObj = (PyUILineObject*)type->tp_alloc(type, 0);
|
||||
if (pyObj) {
|
||||
pyObj->data = std::static_pointer_cast<UILine>(drawable);
|
||||
|
|
@ -575,8 +570,7 @@ static PyObject* convertDrawableToPython(std::shared_ptr<UIDrawable> drawable) {
|
|||
}
|
||||
case PyObjectsEnum::UICIRCLE:
|
||||
{
|
||||
type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "Circle");
|
||||
if (!type) return nullptr;
|
||||
type = &mcrfpydef::PyUICircleType;
|
||||
auto pyObj = (PyUICircleObject*)type->tp_alloc(type, 0);
|
||||
if (pyObj) {
|
||||
pyObj->data = std::static_pointer_cast<UICircle>(drawable);
|
||||
|
|
@ -587,8 +581,7 @@ static PyObject* convertDrawableToPython(std::shared_ptr<UIDrawable> drawable) {
|
|||
}
|
||||
case PyObjectsEnum::UIARC:
|
||||
{
|
||||
type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "Arc");
|
||||
if (!type) return nullptr;
|
||||
type = &mcrfpydef::PyUIArcType;
|
||||
auto pyObj = (PyUIArcObject*)type->tp_alloc(type, 0);
|
||||
if (pyObj) {
|
||||
pyObj->data = std::static_pointer_cast<UIArc>(drawable);
|
||||
|
|
@ -601,10 +594,6 @@ static PyObject* convertDrawableToPython(std::shared_ptr<UIDrawable> drawable) {
|
|||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
if (type) {
|
||||
Py_DECREF(type);
|
||||
}
|
||||
|
||||
return obj ? obj : Py_None;
|
||||
}
|
||||
|
||||
|
|
@ -622,13 +611,9 @@ static PyObject* convertEntityToPython(std::shared_ptr<UIEntity> entity) {
|
|||
}
|
||||
}
|
||||
|
||||
PyTypeObject* type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "Entity");
|
||||
if (!type) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
PyTypeObject* type = &mcrfpydef::PyUIEntityType;
|
||||
|
||||
auto pyObj = (PyUIEntityObject*)type->tp_alloc(type, 0);
|
||||
Py_DECREF(type);
|
||||
|
||||
if (!pyObj) {
|
||||
Py_RETURN_NONE;
|
||||
|
|
@ -653,13 +638,9 @@ static PyObject* convertEntity3DToPython(std::shared_ptr<mcrf::Entity3D> entity)
|
|||
}
|
||||
|
||||
// Create a new wrapper
|
||||
PyTypeObject* type = (PyTypeObject*)PyObject_GetAttrString(McRFPy_API::mcrf_module, "Entity3D");
|
||||
if (!type) {
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
PyTypeObject* type = &mcrfpydef::PyEntity3DType;
|
||||
|
||||
auto pyObj = (PyEntity3DObject*)type->tp_alloc(type, 0);
|
||||
Py_DECREF(type);
|
||||
|
||||
if (!pyObj) {
|
||||
Py_RETURN_NONE;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue