[Bugfix] Only UICollection.append maintains the parent link; insert/extend/setitem/slice do not #377
Labels
No labels
Alpha Release Requirement
Bugfix
Demo Target
Documentation
Major Feature
Minor Feature
priority:tier1-active
priority:tier2-foundation
priority:tier3-future
priority:tier4-deferred
Refactoring & Cleanup
system:animation
system:documentation
system:grid
system:input
system:performance
system:procgen
system:python-binding
system:rendering
system:ui-hierarchy
Tiny Feature
workflow:blocked
workflow:needs-benchmark
workflow:needs-documentation
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
john/McRogueFace#377
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Found while implementing #373, which needs a trustworthy "is this drawable in a children collection?" signal.
UIDrawable::parent/parent_scene(#122/#183) are supposed to be the inverse of collection membership. Onlyappend()actually maintains that invariant. Every other mutator gets it wrong, in two distinct ways.1. Scene collections: only
appendsetsparent_sceneappend()branches onself->scene_name:insert(),extend(), andsetitem()skip the branch and callsetParent(self->owner.lock())unconditionally. A scene collection has no owner drawable, soowner.lock()is null — andsetParent(nullptr)also clearsparent_scene. The drawable lands in the scene's UI vector with no parent at all:Reproduced on
fix/bugfix-batch-july:2. Slice ops ignore the parent link entirely
ass_subscript()erases and inserts straight into the vector, never callingsetParent/removeFromParent:So after a slice op,
x.parent.childrenmay not containx, andf.childrenmay hold elements whose.parentis someone else. A staleparentis a liveweak_ptrto a frame the child is no longer in, which is also whatget_global_position()walks.Fix
Factor the append branch into
link_child(self, drawable)/unlink_child(drawable)helpers and route every mutator through them:setitem(both the replace and the delete arm),insert,extend,remove,pop, and both arms ofass_subscript.Why this blocks #373
#373's owner-held strong ref pins the Python wrapper of a subclassed drawable exactly while it is a member of a children collection. The parent link is the natural representation of that membership — but a pin hung off a link that four of six mutators don't maintain would fail to pin on
insert/extend/slice-assign, and fail to release on slice-delete (leaking the wrapper and the C++ object forever).Test
tests/regression/— assert thex in collection<->x.parent is collection_ownerinvariant holds after every mutator, for both a Frame-owned and a Scene-owned collection.