89 lines
2.9 KiB
GDScript
89 lines
2.9 KiB
GDScript
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
|