[Bugfix] Shared-data grid path is unwired: Grid(grid=...) never sets owning_view, and _GridData.view is always None #359
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#359
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?
(Original report below, retained for the analysis.)
Summary
The
Grid(grid=existing)shared-data path — the whole point of the #252 split (split-screen, minimap, multiple cameras on one dataset) — has two back-references that are never assigned. Strong evidence this path has never been exercised.1.
init_explicit_viewnever setsowning_viewsrc/UIGridView.cpp:475-552(init_explicit_view, theGrid(grid=other)/GridView(grid=other)path) sharesgrid_datafrom an existing_GridDataorGridView, but never setsgrid_data->owning_view.Contrast the default path,
init_with_data,src/UIGridView.cpp:609:GridData::owning_view(src/GridData.h:152) is whatmarkDirty()/markCompositeDirty()(GridData.h:169-170) use to notify the view. It drives the #313 data-layer dirty notifications and the #351 render early-out cache (last_content_gen). With it unset, a second view onto shared data is likely to serve a stale cached texture and never repaint when the data changes.Design question this exposes:
owning_viewis a singleweak_ptr, but N views can share one GridData. Fixing this properly means either a list of views, or inverting the notification (views pollcontent_generation, which they already cache aslast_content_gen— the simpler fix, and it makesowning_viewdeletable). Prefer the latter. — This is what was chosen; see the resolution above.2.
_GridData.viewis never assignedPyUIGridObjectcarries astd::shared_ptr<UIGridView> viewmember, placement-new'd intp_new(src/UIGrid.h:311-314) and exposed as read-only_GridData.view(src/UIGridPyProperties.cpp:371-380, getset at :605-609).Nothing in the codebase ever assigns it.
Grid()goes throughUIGridView::init, which builds a_GridDatawrapper, steals itsGridDatasub-object, andPy_DECREFs the wrapper (src/UIGridView.cpp:566-613) — so the wrapper that could have held aviewis discarded._GridData.viewis alwaysNone.Either wire it up or delete the member and the getset. Given
_GridDatais internal and not module-exported, deleting is likely correct. — Deleting was chosen.Test
tests/regression/issue_XXX_shared_grid_data_test.py: twoGridviews over one GridData with differentcenter/zoom; mutate a cell; render both; assert both reflect the change (this currently should fail on the second view). — Still wanted; moved to #361.Related: #355 (same #252 fallout), #352 (render cache dirty-source tracking), #361 (carries the resolution).
Resolution decided 2026-07-12:
owning_viewis deleted, not wired up. See #361, which now carries this.The recommendation in the issue body was right, and the audit confirms it.
owning_viewhas exactly two consumers in the tree:UIEntity::get_grid(src/UIEntity.cpp:827) — returns the owningGridViewwhen one exists, falling back to a bare_GridDatawrapper otherwise.GridData::markDirty/markCompositeDirty(src/GridData.cpp:15, 23) — notifying the view's render cache.Consumer (2) is already redundant with
content_generation, which views poll vialast_content_gen(#351).Consumer (1) is removed by an accepted pre-1.0 API break:
entity.gridwill return theGridData, not the view. Rationale from the repo owner:There may be zero views over an entity's grid, or several. A single
weak_ptrback-pointer was never going to model that — which is exactly why it is structurally wrong, not merely unset. With both consumers gone the back-pointer has no readers.So the two defects reported here (
init_explicit_viewnever settingowning_view;PyUIGridObject::viewnever assigned) are not fixed — the fields are deleted. Doing this work as a "wire it up" fix would cement the one-view-per-GridData assumption that #252 exists to remove.Sequencing: #355 first (input moves to
GridView), then #361 does the removal along with the rest of the data/drawable split, keeping the API break in one reviewable commit.