feat: Change EntityCollection.remove() to accept Entity objects
Previously, EntityCollection.remove() required an integer index, which was inconsistent with Python's list.remove(item) behavior and the broader Python ecosystem conventions. Changes: - remove() now accepts Entity object directly instead of index - Searches collection by comparing C++ shared_ptr identity - Raises ValueError if entity not found in collection - More Pythonic API matching Python's list.remove() semantics This aligns with Issue #73 and improves API consistency across the collection system. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
1149111f2d
commit
327da3622a
|
|
@ -1772,34 +1772,47 @@ PyObject* UIEntityCollection::append(PyUIEntityCollectionObject* self, PyObject*
|
||||||
|
|
||||||
PyObject* UIEntityCollection::remove(PyUIEntityCollectionObject* self, PyObject* o)
|
PyObject* UIEntityCollection::remove(PyUIEntityCollectionObject* self, PyObject* o)
|
||||||
{
|
{
|
||||||
if (!PyLong_Check(o))
|
// Type checking - must be an Entity
|
||||||
|
if (!PyObject_IsInstance(o, PyObject_GetAttrString(McRFPy_API::mcrf_module, "Entity")))
|
||||||
{
|
{
|
||||||
PyErr_SetString(PyExc_TypeError, "EntityCollection.remove requires an integer index to remove");
|
PyErr_SetString(PyExc_TypeError, "EntityCollection.remove requires an Entity object");
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
long index = PyLong_AsLong(o);
|
|
||||||
|
|
||||||
// Handle negative indexing
|
|
||||||
while (index < 0) index += self->data->size();
|
|
||||||
|
|
||||||
if (index >= self->data->size())
|
|
||||||
{
|
|
||||||
PyErr_SetString(PyExc_ValueError, "Index out of range");
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get iterator to the entity to remove
|
// Get the C++ object from the Python object
|
||||||
auto it = self->data->begin();
|
PyUIEntityObject* entity = (PyUIEntityObject*)o;
|
||||||
std::advance(it, index);
|
if (!entity->data) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, "Invalid Entity object");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// Clear grid reference before removing
|
// Get the underlying list
|
||||||
|
auto list = self->data.get();
|
||||||
|
if (!list) {
|
||||||
|
PyErr_SetString(PyExc_RuntimeError, "The collection store returned a null pointer");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Search for the entity by comparing C++ pointers
|
||||||
|
auto it = list->begin();
|
||||||
|
while (it != list->end()) {
|
||||||
|
if (it->get() == entity->data.get()) {
|
||||||
|
// Found it - clear grid reference before removing
|
||||||
(*it)->grid = nullptr;
|
(*it)->grid = nullptr;
|
||||||
|
|
||||||
// release the shared pointer at correct part of the list
|
// Remove from the list
|
||||||
self->data->erase(it);
|
self->data->erase(it);
|
||||||
|
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return Py_None;
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Entity not found - raise ValueError
|
||||||
|
PyErr_SetString(PyExc_ValueError, "Entity not in EntityCollection");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
PyObject* UIEntityCollection::extend(PyUIEntityCollectionObject* self, PyObject* o)
|
PyObject* UIEntityCollection::extend(PyUIEntityCollectionObject* self, PyObject* o)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue