74 lines
2.4 KiB
GDScript
74 lines
2.4 KiB
GDScript
class_name TerrainQualityMeshCache
|
|
extends RefCounted
|
|
|
|
## Session-memory LRU owner for full-quality terrain Mesh references retained
|
|
## across tile unload/revisit. It owns no tile state, Node, RID, task or file.
|
|
|
|
const EXCLUDED_QUALITY_SOURCES: Array[String] = [
|
|
"control_splat_cache",
|
|
"splat_cache",
|
|
"splat",
|
|
]
|
|
|
|
var _entries_by_tile_key: Dictionary = {}
|
|
var _tile_keys_oldest_to_newest: Array[String] = []
|
|
|
|
|
|
## Stores an admitted Mesh reference, touches it as newest and trims oldest
|
|
## entries to the supplied non-negative capacity. Returns false when rejected.
|
|
func store(tile_key: String, mesh: Mesh, source: String, capacity: int) -> bool:
|
|
if tile_key.is_empty() or mesh == null or EXCLUDED_QUALITY_SOURCES.has(source):
|
|
return false
|
|
_entries_by_tile_key[tile_key] = {"mesh": mesh, "source": source}
|
|
_touch(tile_key)
|
|
_trim(maxi(0, capacity))
|
|
return _entries_by_tile_key.has(tile_key)
|
|
|
|
|
|
## Returns a fresh record containing the retained Mesh/source and touches the key
|
|
## as newest. Missing or invalid records return empty and are removed.
|
|
func restore(tile_key: String) -> Dictionary:
|
|
if not _entries_by_tile_key.has(tile_key):
|
|
return {}
|
|
var entry: Dictionary = _entries_by_tile_key[tile_key]
|
|
var source := String(entry.get("source", "baked_full"))
|
|
var mesh := entry.get("mesh") as Mesh
|
|
if mesh == null or EXCLUDED_QUALITY_SOURCES.has(source):
|
|
_remove(tile_key)
|
|
return {}
|
|
_touch(tile_key)
|
|
return {"mesh": mesh, "source": source}
|
|
|
|
|
|
## Releases every retained Mesh reference and resets LRU order.
|
|
func clear() -> void:
|
|
_entries_by_tile_key.clear()
|
|
_tile_keys_oldest_to_newest.clear()
|
|
|
|
|
|
## Returns detached scalar diagnostics without exposing retained Mesh references.
|
|
func diagnostic_snapshot() -> Dictionary:
|
|
var entries: Array[Dictionary] = []
|
|
for tile_key in _tile_keys_oldest_to_newest:
|
|
var entry: Dictionary = _entries_by_tile_key.get(tile_key, {})
|
|
entries.append({"tile_key": tile_key, "source": String(entry.get("source", ""))})
|
|
return {
|
|
"entry_count": entries.size(),
|
|
"entries_oldest_to_newest": entries,
|
|
}
|
|
|
|
|
|
func _touch(tile_key: String) -> void:
|
|
_tile_keys_oldest_to_newest.erase(tile_key)
|
|
_tile_keys_oldest_to_newest.append(tile_key)
|
|
|
|
|
|
func _trim(capacity: int) -> void:
|
|
while _tile_keys_oldest_to_newest.size() > capacity:
|
|
_remove(_tile_keys_oldest_to_newest.front())
|
|
|
|
|
|
func _remove(tile_key: String) -> void:
|
|
_entries_by_tile_key.erase(tile_key)
|
|
_tile_keys_oldest_to_newest.erase(tile_key)
|