feat(simulation): T-1151 window par_iter + T-1150 granularity carrier (five touch points + aliasing tests)

T-1151: build_district_window_layer dispatches one Rayon task per row
(pure derive_window_cell via derive_at_metres), scattered row-major into
the flat arrays; a cfg(test) serial path backs the bit-identical
parallel-vs-serial golden.

T-1150: serde-default window_granularity (1=district, 4=quarter) +
window_min_wl_m on AtlasLayerRequest — additive, no sixth demux shape,
old frames decode unchanged (tested). Quarter mode = full
reclassification at 512m spacing over the same world rect ((4n)x(4n)
cells); WIRE_CAP_CELLS=4096 enforces n*granularity <= cap (quarter
clamps n to 16, the design doc's worked example). Granularity + min_wl
key ALL five touch points: DistrictWindowLayer echo, server FIFO-256
cache key (now a 5-tuple), per-connection coalescing key, client
request codec (omitted-at-default wire fields), client LRU key.

Mandatory aliasing regressions on both ends: identical (body, center, n)
at granularity 1 vs 4 produce distinct cache entries and correct
per-granularity payload shapes (server, 3-thread queue to avoid the
AnalyzeBody thread contention found while writing it) and distinct
client cache keys (gdUnit). Replay fixture regenerated — the layer
struct grew two echoed fields (231->254 bytes, content verified).

Client requests stay district-granularity by default — quarter requests
arrive with T-1153's rung selection.
This commit is contained in:
2026-07-22 00:27:40 +02:00
parent afff859a2c
commit 3e87fd5b4f
14 changed files with 1027 additions and 118 deletions
+14 -2
View File
@@ -432,12 +432,24 @@ func send_named_action(action_name: String, action_data: Variant = null) -> void
## not a specific whole-body layer to be cached first). Omitted by every
## whole-body-layer caller (show_body()'s existing request), so their wire
## traffic is byte-unchanged.
##
## window_granularity/window_min_wl_m (T-1150): struct/key plumbing for the
## zoom-ladder quarter rung — district (0/omitted) stays the default for
## every caller in this codebase today; requesting quarter granularity is
## T-1153's job, not wired here.
func request_atlas_layers(
body_id: String, up_to: String = "Topography", window_center: Variant = null, window_n: int = 0
body_id: String,
up_to: String = "Topography",
window_center: Variant = null,
window_n: int = 0,
window_granularity: int = 0,
window_min_wl_m: int = 0
) -> void:
if test_mode or _bridge == null or state != ConnectionState.CONNECTED:
return
var bytes := Protocol.encode_atlas_layer_request(body_id, up_to, window_center, window_n)
var bytes := Protocol.encode_atlas_layer_request(
body_id, up_to, window_center, window_n, window_granularity, window_min_wl_m
)
if bytes.is_empty():
return
var err: int = _bridge.send_message(bytes)