Remove entity self-reference cycle
UIEntity::init() stored self->data->self = (PyObject*)self with Py_INCREF(self), creating a reference cycle that prevented entities from ever being freed. The matching Py_DECREF never existed. Fix: Remove the `self` field from UIEntity entirely. Replace all read sites (iter next, getitem, get_perspective, entities_in_radius) with PythonObjectCache lookups using serial_number, which uses weak references and doesn't prevent garbage collection. Also adds tp_dealloc to PyUIEntityType to properly clean up the shared_ptr and weak references when the Python wrapper is freed. Closes #266, closes #275 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
71eb01c950
commit
a12e035a71
5 changed files with 123 additions and 30 deletions
|
|
@ -41,10 +41,12 @@ PyObject* UIEntityCollectionIter::next(PyUIEntityCollectionIterObject* self)
|
|||
auto target = *self->current;
|
||||
++self->current;
|
||||
|
||||
// Return the stored Python object if it exists (preserves derived types)
|
||||
if (target->self != nullptr) {
|
||||
Py_INCREF(target->self);
|
||||
return target->self;
|
||||
// Check cache first to preserve derived class identity
|
||||
if (target->serial_number != 0) {
|
||||
PyObject* cached = PythonObjectCache::getInstance().lookup(target->serial_number);
|
||||
if (cached) {
|
||||
return cached; // Already INCREF'd by lookup
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise create and return a new Python Entity object
|
||||
|
|
@ -107,13 +109,7 @@ PyObject* UIEntityCollection::getitem(PyUIEntityCollectionObject* self, Py_ssize
|
|||
}
|
||||
}
|
||||
|
||||
// Legacy: If the entity has a stored Python object reference, return that
|
||||
if (target->self != nullptr) {
|
||||
Py_INCREF(target->self);
|
||||
return target->self;
|
||||
}
|
||||
|
||||
// Otherwise, create a new base Entity object
|
||||
// Create a new base Entity object
|
||||
PyTypeObject* entity_type = &mcrfpydef::PyUIEntityType;
|
||||
|
||||
auto o = (PyUIEntityObject*)entity_type->tp_alloc(entity_type, 0);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue