feat(client): atlas layer-stream codec — encode request / decode response (#960, D-225)
Client half of the layer-stream protocol (codec only; transport wiring next).
- protocol.gd: encode_atlas_layer_request (bare {body_id, up_to} map so the
server demux routes it to the proxy, not the PlayerInput array) and
decode_atlas_layer_response (-> {body_id, status, error, layer1}; returns null
for non-atlas frames, e.g. a snapshot, so receive_bytes can disambiguate).
- gen_fixtures.rs: cross-language fixtures (atlas_response_ready/pending/
not_found) from real rmp_serde output, matching the test_protocol.gd pattern.
- test_protocol.gd: 5 tests decode the fixtures + verify a snapshot is not
mistaken for a response + the request encodes to the right shape. 68/68 pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1 @@
|
||||
ƒ§body_id¥ghost¦status¨NotFound¦layer1À
|
||||
@@ -0,0 +1 @@
|
||||
�body_id二J1c存tatus判ending奸ayer1�
|
||||
Binary file not shown.
@@ -463,3 +463,51 @@ func test_encode_confirm_bookmark_roundtrip() -> void:
|
||||
var data: Dictionary = entry["action_data"]
|
||||
assert_that(data["bookmark_id"]).is_equal("bm_tycoon_arion")
|
||||
assert_that(data["starting_location_id"]).is_equal("loc_arion_prime")
|
||||
|
||||
|
||||
# -- Atlas layer-stream protocol (#969, D-225) ---------------------------------
|
||||
|
||||
func test_decode_atlas_response_ready() -> void:
|
||||
var bytes := _load_fixture("atlas_response_ready")
|
||||
var resp = Protocol.decode_atlas_layer_response(bytes)
|
||||
assert_that(resp).is_not_null()
|
||||
assert_that(resp.body_id).is_equal("GJ1c")
|
||||
assert_that(resp.status).is_equal("Ready")
|
||||
assert_that(resp.layer1).is_not_null()
|
||||
assert_that(resp.layer1.river_network.river_cells.size()).is_equal(2)
|
||||
assert_that(resp.layer1.attractors.size()).is_equal(1)
|
||||
assert_that(resp.layer1.attractors[0].attractor_type).is_equal("CoastalAccess")
|
||||
assert_that(resp.layer1.attractors[0].sub_biome).is_equal("CoastalLowland")
|
||||
|
||||
|
||||
func test_decode_atlas_response_pending() -> void:
|
||||
var bytes := _load_fixture("atlas_response_pending")
|
||||
var resp = Protocol.decode_atlas_layer_response(bytes)
|
||||
assert_that(resp).is_not_null()
|
||||
assert_that(resp.status).is_equal("Pending")
|
||||
assert_that(resp.layer1).is_null()
|
||||
|
||||
|
||||
func test_decode_atlas_response_not_found() -> void:
|
||||
var bytes := _load_fixture("atlas_response_not_found")
|
||||
var resp = Protocol.decode_atlas_layer_response(bytes)
|
||||
assert_that(resp.status).is_equal("NotFound")
|
||||
|
||||
|
||||
func test_snapshot_is_not_decoded_as_atlas_response() -> void:
|
||||
# Disambiguation: an ObserverSnapshot has no "status" key, so the atlas
|
||||
# decoder rejects it. receive_bytes relies on this to route correctly.
|
||||
var bytes := _load_fixture("snapshot_empty")
|
||||
assert_that(Protocol.decode_atlas_layer_response(bytes)).is_null()
|
||||
|
||||
|
||||
func test_encode_atlas_request_shape() -> void:
|
||||
var bytes := Protocol.encode_atlas_layer_request("GJ1c", "Topography")
|
||||
assert_that(bytes.size()).is_greater(0)
|
||||
var raw: Variant = Messagepack.decode(bytes)
|
||||
assert_that(raw.status).is_null()
|
||||
assert_that(raw.value is Dictionary).is_true()
|
||||
assert_that(raw.value["body_id"]).is_equal("GJ1c")
|
||||
assert_that(raw.value["up_to"]).is_equal("Topography")
|
||||
# A request is a map with no "status" — must not be mistaken for a response.
|
||||
assert_that(Protocol.decode_atlas_layer_response(bytes)).is_null()
|
||||
|
||||
Reference in New Issue
Block a user