refactor(M03): extract M2 unique placement registry
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
class_name M2UniquePlacementRegistry
|
||||
extends RefCounted
|
||||
|
||||
## Session-memory ownership registry for positive ADT MDDF unique IDs.
|
||||
|
||||
var _owner_tile_by_unique_key: Dictionary = {}
|
||||
|
||||
|
||||
## Reserves unowned positive unique IDs for one tile and returns fresh arrays.
|
||||
## Unkeyed placements pass through without entering registry ownership.
|
||||
func reserve(tile_key: String, m2_placements: Array) -> Dictionary:
|
||||
var filtered_placements: Array = []
|
||||
var unique_keys: Array = []
|
||||
var skipped_unique_keys: Array = []
|
||||
for placement_variant in m2_placements:
|
||||
if not (placement_variant is Dictionary):
|
||||
continue
|
||||
var placement: Dictionary = placement_variant
|
||||
var unique_key := _unique_key_for_placement(placement)
|
||||
if unique_key.is_empty():
|
||||
filtered_placements.append(placement)
|
||||
continue
|
||||
if _owner_tile_by_unique_key.has(unique_key):
|
||||
var owner_tile := String(_owner_tile_by_unique_key[unique_key])
|
||||
if owner_tile == tile_key and unique_keys.has(unique_key):
|
||||
continue
|
||||
if owner_tile != tile_key:
|
||||
if not skipped_unique_keys.has(unique_key):
|
||||
skipped_unique_keys.append(unique_key)
|
||||
continue
|
||||
_owner_tile_by_unique_key[unique_key] = tile_key
|
||||
if not unique_keys.has(unique_key):
|
||||
unique_keys.append(unique_key)
|
||||
filtered_placements.append(placement)
|
||||
return {
|
||||
"placements": filtered_placements,
|
||||
"unique_keys": unique_keys,
|
||||
"skipped_unique_keys": skipped_unique_keys,
|
||||
}
|
||||
|
||||
|
||||
## Releases only keys currently owned by the supplied tile and returns them in
|
||||
## input order so the loader can notify waiting candidate tiles.
|
||||
func release(tile_key: String, unique_keys: Array) -> Array:
|
||||
var released_unique_keys: Array = []
|
||||
for unique_key_variant in unique_keys:
|
||||
var unique_key := String(unique_key_variant)
|
||||
if unique_key.is_empty() or not _owner_tile_by_unique_key.has(unique_key):
|
||||
continue
|
||||
if String(_owner_tile_by_unique_key[unique_key]) != tile_key:
|
||||
continue
|
||||
_owner_tile_by_unique_key.erase(unique_key)
|
||||
released_unique_keys.append(unique_key)
|
||||
return released_unique_keys
|
||||
|
||||
|
||||
## Removes all reservations during world reset or renderer shutdown.
|
||||
func clear() -> void:
|
||||
_owner_tile_by_unique_key.clear()
|
||||
|
||||
|
||||
## Returns the number of currently owned positive unique IDs.
|
||||
func active_count() -> int:
|
||||
return _owner_tile_by_unique_key.size()
|
||||
|
||||
|
||||
## Returns detached, key-sorted scalar diagnostics without registry references.
|
||||
func diagnostic_snapshot() -> Dictionary:
|
||||
var sorted_unique_keys: Array = _owner_tile_by_unique_key.keys()
|
||||
sorted_unique_keys.sort()
|
||||
var owners: Array = []
|
||||
for unique_key_variant in sorted_unique_keys:
|
||||
var unique_key := String(unique_key_variant)
|
||||
owners.append({
|
||||
"unique_key": unique_key,
|
||||
"tile_key": String(_owner_tile_by_unique_key[unique_key]),
|
||||
})
|
||||
return {
|
||||
"active_count": owners.size(),
|
||||
"owners": owners,
|
||||
}
|
||||
|
||||
|
||||
func _unique_key_for_placement(placement: Dictionary) -> String:
|
||||
var unique_id := int(placement.get("unique_id", -1))
|
||||
if unique_id <= 0:
|
||||
return ""
|
||||
return "uid:%d" % unique_id
|
||||
@@ -0,0 +1 @@
|
||||
uid://cqdvx0qnpcte1
|
||||
Reference in New Issue
Block a user