perf: cache SimulationDefinitions lookups in memory

Previously get_action(), get_profession(), get_actions(), get_professions(), get_profession_ids(), and validate() reloaded all .tres files from disk on every call. These are called per-tick (action selection, task completion, NPC inspector refresh) producing unnecessary disk I/O. Now definitions are loaded once and stored in static dicts/lists keyed by ID. Add invalidate_cache() for hot-reload scenarios.
This commit is contained in:
2026-07-05 23:54:55 +02:00
parent 58d3573965
commit 734fe12098
+49 -26
View File
@@ -21,54 +21,77 @@ const PROFESSION_PATHS := [
"res://simulation/definitions/professions/wanderer.tres"
]
static var _action_list: Array[ActionDefinition] = []
static var _profession_list: Array[ProfessionDefinition] = []
static var _action_map: Dictionary = {}
static var _profession_map: Dictionary = {}
static var _profession_id_list: Array[StringName] = []
static var _cache_valid := false
static func _ensure_cache() -> void:
if _cache_valid:
return
_action_list = []
_profession_list = []
_action_map = {}
_profession_map = {}
_profession_id_list = []
static func get_actions() -> Array[ActionDefinition]:
var definitions: Array[ActionDefinition] = []
for path in ACTION_PATHS:
var definition := load(path) as ActionDefinition
if definition != null:
definitions.append(definition)
return definitions
_action_list.append(definition)
_action_map[definition.action_id] = definition
static func get_professions() -> Array[ProfessionDefinition]:
var definitions: Array[ProfessionDefinition] = []
for path in PROFESSION_PATHS:
var definition := load(path) as ProfessionDefinition
if definition != null:
definitions.append(definition)
return definitions
_profession_list.append(definition)
_profession_map[definition.profession_id] = definition
_profession_id_list.append(definition.profession_id)
_cache_valid = true
static func invalidate_cache() -> void:
_cache_valid = false
static func get_actions() -> Array[ActionDefinition]:
_ensure_cache()
return _action_list
static func get_professions() -> Array[ProfessionDefinition]:
_ensure_cache()
return _profession_list
static func get_action(action_id: StringName) -> ActionDefinition:
for definition in get_actions():
if definition.action_id == action_id:
return definition
return null
_ensure_cache()
return _action_map.get(action_id)
static func get_profession(profession_id: StringName) -> ProfessionDefinition:
for definition in get_professions():
if definition.profession_id == profession_id:
return definition
return null
_ensure_cache()
return _profession_map.get(profession_id)
static func get_profession_ids() -> Array[StringName]:
var ids: Array[StringName] = []
for definition in get_professions():
ids.append(definition.profession_id)
return ids
_ensure_cache()
return _profession_id_list
static func validate() -> Array[String]:
_ensure_cache()
var errors: Array[String] = []
if get_actions().size() != ACTION_PATHS.size():
if _action_list.size() != ACTION_PATHS.size():
errors.append("One or more ActionDefinition resources failed to load")
if get_professions().size() != PROFESSION_PATHS.size():
if _profession_list.size() != PROFESSION_PATHS.size():
errors.append("One or more ProfessionDefinition resources failed to load")
var action_ids := {}
for definition in get_actions():
for definition in _action_list:
for error in definition.validate():
errors.append("ActionDefinition: " + error)
if action_ids.has(definition.action_id):
@@ -76,14 +99,14 @@ static func validate() -> Array[String]:
action_ids[definition.action_id] = true
var profession_ids := {}
for definition in get_professions():
for definition in _profession_list:
for error in definition.validate():
errors.append("ProfessionDefinition: " + error)
if profession_ids.has(definition.profession_id):
errors.append("Duplicate profession_id '%s'" % definition.profession_id)
profession_ids[definition.profession_id] = true
for definition in get_actions():
for definition in _action_list:
if (
not definition.preferred_profession_id.is_empty()
and not profession_ids.has(definition.preferred_profession_id)