NEO-25: queue last-wins interact POST when HTTP client is busy
parent
06d9104157
commit
ba667f1581
|
|
@ -82,7 +82,7 @@ If the server is **down**, boot **`GET`** fails silently (check Output for warni
|
|||
|
||||
On boot, **`InteractablesCatalogClient`** **`GET`s** **`/game/world/interactables`**; **`interactable_world_builder.gd`** spawns **walkable** prototype props plus **two** small glow markers per row under **`World/InteractionMarkers`**. **`interaction_radius_indicators.gd`** compares the snapped **`CharacterBody3D`** **`global_position`** to each descriptor’s **`anchor`** on **X/Z** with the same **`interactionRadius`** and inclusive **`<=`** rule as the server — **preview only**; **`POST /game/players/{id}/interact`** remains authoritative.
|
||||
|
||||
- **`InteractionRequestClient`**: **`interact`** (**E**) → **`prototype_terminal`**; **`interact_secondary`** (**R**) → **`prototype_resource_node_alpha`** (stable ids; must match `PrototypeInteractableRegistry.cs`). **Output** prints `allowed` / `reasonCode`. In-flight requests are ignored (same busy pattern as **`PositionAuthorityClient`**).
|
||||
- **`InteractionRequestClient`**: **`interact`** (**E**) → **`prototype_terminal`**; **`interact_secondary`** (**R**) → **`prototype_resource_node_alpha`** (stable ids; must match `PrototypeInteractableRegistry.cs`). **Output** prints `allowed` / `reasonCode` per response (lines prefixed with `Interaction [<id>]: …`). Only one HTTP POST runs at a time; if you press **E** then **R** while the first request is still in flight, the **latest** id is remembered and sent **immediately after** the first completes (last-wins coalescing — not a silent drop).
|
||||
- **Inspector:** match **`base_url`** on **`InteractablesCatalogClient`**, **`InteractionRequestClient`**, and **`PositionAuthorityClient`** to the running server.
|
||||
- **No server:** catalog **GET** fails → **Output** errors; props and glow markers do not spawn (expected prototype degradation).
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,10 @@ const ID_RESOURCE_NODE := "prototype_resource_node_alpha"
|
|||
|
||||
var _http: Node
|
||||
var _busy: bool = false
|
||||
## While an HTTP POST is in flight, the latest [code]interactableId[/code] from a new press overwrites
|
||||
## this slot (last wins); [method _try_flush_pending] runs the next POST after [signal HTTPRequest.request_completed].
|
||||
var _pending_interactable_id: String = ""
|
||||
var _current_interactable_id: String = ""
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
|
|
@ -44,7 +48,13 @@ func _base_root() -> String:
|
|||
|
||||
func _post_interact(interactable_id: String) -> void:
|
||||
if _busy:
|
||||
_pending_interactable_id = interactable_id
|
||||
return
|
||||
_start_post(interactable_id)
|
||||
|
||||
|
||||
func _start_post(interactable_id: String) -> void:
|
||||
_current_interactable_id = interactable_id
|
||||
_busy = true
|
||||
var url := "%s/game/players/%s/interact" % [_base_root(), dev_player_id.strip_edges()]
|
||||
var payload := {"schemaVersion": 1, "interactableId": interactable_id}
|
||||
|
|
@ -54,6 +64,14 @@ func _post_interact(interactable_id: String) -> void:
|
|||
if err != OK:
|
||||
push_warning("InteractionRequestClient: POST failed to start (%s)" % err)
|
||||
_busy = false
|
||||
_try_flush_pending()
|
||||
|
||||
|
||||
func _try_flush_pending() -> void:
|
||||
var next: String = _pending_interactable_id
|
||||
_pending_interactable_id = ""
|
||||
if not next.is_empty() and not _busy:
|
||||
_start_post(next)
|
||||
|
||||
|
||||
func _on_request_completed(
|
||||
|
|
@ -61,6 +79,7 @@ func _on_request_completed(
|
|||
) -> void:
|
||||
_busy = false
|
||||
var text := body.get_string_from_utf8()
|
||||
var id_echo: String = _current_interactable_id
|
||||
if response_code == 200:
|
||||
var parsed: Variant = JSON.parse_string(text)
|
||||
if parsed is Dictionary:
|
||||
|
|
@ -68,8 +87,14 @@ func _on_request_completed(
|
|||
var allowed: bool = bool(d.get("allowed", false))
|
||||
var reason: Variant = d.get("reasonCode", null)
|
||||
if allowed:
|
||||
print("Interaction: allowed=true (reasonCode omitted on success)")
|
||||
print(
|
||||
"Interaction [%s]: allowed=true (reasonCode omitted on success)" % id_echo
|
||||
)
|
||||
else:
|
||||
print("Interaction: allowed=false reasonCode=%s" % str(reason))
|
||||
print(
|
||||
"Interaction [%s]: allowed=false reasonCode=%s" % [id_echo, str(reason)]
|
||||
)
|
||||
_try_flush_pending()
|
||||
return
|
||||
print("Interaction: HTTP %s body=%s" % [response_code, text])
|
||||
print("Interaction [%s]: HTTP %s body=%s" % [id_echo, response_code, text])
|
||||
_try_flush_pending()
|
||||
|
|
|
|||
Loading…
Reference in New Issue