Commit graph

5 commits

Author SHA1 Message Date
8af3bf45b6 feat(discretemap): buffer protocol for zero-copy numpy views; closes #334
DiscreteMap now implements tp_as_buffer/bf_getbuffer, exposing its dense uint8
storage as a 2-D (height, width) C-contiguous writable view. memoryview(dmap)
and np.asarray(dmap) share memory with the map -- no copy -- so per-entity FOV
memory (#294 perspective_map) and other DiscreteMaps can be inspected/edited
with numpy at native speed.

The exporter owns the buffer via its shared_ptr<DiscreteMap>; getbuffer INCREFs
it for the view's lifetime (balanced by the default PyBuffer_Release DECREF, so
no bf_releasebuffer). shape/strides are stored on the object -- dimensions are
immutable after construction, so concurrent views safely share them.

Independent of the GridData SoA work (#332): DiscreteMap already owned a dense
contiguous uint8_t* with no libtcod coupling.

Regression test issue_334_discretemap_buffer_test.py: shape/format/strides,
row-major [x,y]->[y,x] mapping, zero-copy writeback both directions, optional
numpy aliasing (skipped when not bundled), and a buffer over a live entity
perspective_map. Suite 309/309.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-11 01:00:53 -04:00
f797120d53 Replace UIEntity gridstate with DiscreteMap perspective_map; closes #294
Per-entity FOV memory moves from std::vector<UIGridPointState> (two-bool
visible/discovered pairs) to a 3-state DiscreteMap (0=UNKNOWN, 1=DISCOVERED,
2=VISIBLE), exposed as entity.perspective_map. The invariant
visible-subset-of-discovered becomes structural (single value per cell), and
the map is a live, serializable, first-class object rather than an implicit
internal array.

Changes:
- New DiscreteMap C++ class with shared ownership; PyDiscreteMapObject now
  holds shared_ptr<DiscreteMap>. UIEntity holds the same shared_ptr.
- New mcrfpy.Perspective IntEnum (UNKNOWN/DISCOVERED/VISIBLE), modelled on
  PyInputState.
- entity.perspective_map: lazy-allocated on first access with a grid;
  setter validates size against grid and raises ValueError on mismatch;
  None clears (next access lazy-reallocates fresh).
- updateVisibility() now demotes 2->1 then promotes visible cells to 2.
- entity.at(x, y) returns grid.at(x, y) when VISIBLE, else None.
- Fog-of-war rendering in UIGridView and UIGrid reads the 3-state map.
- Removed: UIEntity::gridstate, ensureGridstate(), entity.gridstate getter,
  UIGridPointState struct + PyUIGridPointStateType.
- Obsolete tests deleted (test_gridpointstate_point,
  issue_265_gridpointstate_dangle); 4 new tests cover lazy allocation,
  identity, serialization round-trip, size validation, and the
  visible-subset-of-discovered invariant.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 23:04:27 -04:00
e0bcee12a3 Add DiscreteMap to_bytes/from_bytes serialization, closes #293
to_bytes() returns raw uint8 cell data as Python bytes object.
from_bytes(data, size, enum=None) is a classmethod that constructs
a new DiscreteMap from serialized data with dimension validation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 02:06:02 -04:00
71eb01c950 Replace PyObject_GetAttrString with direct type references
Replace ~230 occurrences of PyObject_GetAttrString(McRFPy_API::mcrf_module, "TypeName")
with direct &mcrfpydef::PyXxxType references across 32 source files.

Each PyObject_GetAttrString call returns a new reference. When used inline
in PyObject_IsInstance(), that reference was immediately leaked. When used
for tp_alloc, the reference required careful Py_DECREF management that was
often missing on error paths.

Direct type references are compile-time constants that never need reference
counting, eliminating ~230 potential leak sites and removing ~100 lines of
Py_DECREF/Py_XDECREF cleanup code.

Also adds extractDrawable() helper in UICollection.cpp to replace repeated
8-way type-check-and-extract chains with a single function call.

Closes #267, closes #268

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 23:18:42 -05:00
d8fec5fea0 DiscreteMap class - mask for operations or uint8 tile data 2026-02-03 20:36:42 -05:00