Commit graph

1 commit

Author SHA1 Message Date
ad223b1ac0 feat(grid): numpy buffer views for ColorLayer/TileLayer via layer.edit(); closes #335
Implements the #328 bulk-edit convention for grid layers. Writable zero-copy
views of layer data are exposed ONLY through a context manager:

    with layer.edit() as view:        # ColorLayer -> (h, w, 4) uint8
        np.asarray(view)[...] = ...    # TileLayer  -> (h, w) int32 (-1 = no tile)
    # on __exit__ the whole layer is conservatively invalidated (markDirty),
    # so the edit re-renders.

Both layers already stored dense, contiguous, row-major data (std::vector<
sf::Color> / std::vector<int>; render caches chunk separately), so the views are
true zero-copy aliases. A new internal _LayerEdit type is the buffer exporter
(bf_getbuffer) and the context manager (__enter__ returns memoryview(self),
__exit__ calls GridLayer::markDirty()); it is not directly instantiable. The
conservative whole-layer invalidation on exit means no change-tracking is
needed, and it composes with the #351 render early-out (markDirty bumps
content_generation).

Independent of GridData SoA (#332): these are the render layers, not the logic
grid. A contiguous walkable/transparent view now has its storage prerequisite
from #332 but remains a separate follow-up.

Regression test issue_335_layer_edit_test.py: buffer shape/format/readonly,
zero-copy writeback both directions, the -1 tile sentinel, optional numpy
aliasing, and a screenshot check that __exit__ actually re-renders. API-surface
golden re-baselined (two new edit methods); docs/stubs regenerated; frozen
docstring gate 100%. Suite 312/312.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 02:04:42 -04:00