e48d4bbe88
- Introduced a new benchmark save script to create a stress test scenario with extreme values for simulation performance. - Added a full UI benchmark script to measure frame rates and performance metrics during UI interactions. - Implemented tests for coarse generations to ensure population transitions are handled correctly. - Created tests for extra parameters to validate the loading and application of configuration settings. - Developed simulation optimization tests to verify the efficiency of population drift and rounding mechanisms. - Added split optimization tests to ensure accurate allocation and rounding behavior in population management. - Included startup parameter tests to confirm the correct initialization of global parameters before scene readiness. - Enhanced the audit rounding ledger to compare selective and full rounding results for consistency.
79 lines
3.3 KiB
GDScript
79 lines
3.3 KiB
GDScript
extends RefCounted
|
|
const E = preload("res://world/owniverse/math/exact.gd")
|
|
## Read-only projections of simulation state. No controls or simulation mutations.
|
|
|
|
var pending_amounts: Dictionary [ String , Variant ] = {}
|
|
var deferred_updates: bool = false
|
|
var dirty: bool = true
|
|
var revision: int = 0
|
|
|
|
func refresh(state: Dictionary, catalog, force: bool = false) -> void:
|
|
dirty = true
|
|
if (deferred_updates and (not force)):
|
|
return
|
|
revision += 1
|
|
pending_amounts = amounts(state, catalog)
|
|
dirty = false
|
|
|
|
## Aliases are presentation-only; group counters are not counted twice.
|
|
static func amounts(state: Dictionary, catalog, total_produced: bool = false) -> Dictionary [ String, Variant ]:
|
|
var source: Dictionary = (state.stats.total_amount if total_produced else state.amount)
|
|
if (not total_produced):
|
|
source = source.duplicate()
|
|
var physical: Dictionary = {}
|
|
for id in catalog.entities:
|
|
if (not catalog.is_group(id)):
|
|
physical[id] = E.maximum(0, state.amount.get(id, 0))
|
|
for bindings : Dictionary in state.binds.values():
|
|
for id in bindings:
|
|
if physical.has(id):
|
|
physical[id] = E.add(physical[id], E.maximum(0, bindings[id]))
|
|
var planets: Variant = 0
|
|
for id in physical:
|
|
if E.eq(catalog.entities[id].group_as, "Planet"):
|
|
source[id] = physical[id]
|
|
planets = E.add(planets, physical[id])
|
|
source["Planet"] = planets
|
|
var result: Dictionary [ String , Variant ] = {}
|
|
for id in source:
|
|
result[id] = 0
|
|
for id in source:
|
|
# group_as counters are already sums and must not be counted a second time.
|
|
if catalog.is_group(id):
|
|
continue
|
|
var item_id: String = id
|
|
if (catalog.entities.has(id) and E.ne(catalog.entities[id].count_as, "")):
|
|
item_id = catalog.entities[id].count_as
|
|
# Detailed icons need their own count as well as the summary alias.
|
|
# Aggregate only from source, never from these presentation entries.
|
|
if E.ne(item_id, id):
|
|
result[id] = E.add(result.get(id, 0), E.of(source[id]))
|
|
result[item_id] = E.add(result.get(item_id, 0), E.of(source[id]))
|
|
for id in source:
|
|
if catalog.is_group(id):
|
|
result[id] = E.of(source[id])
|
|
return result
|
|
|
|
|
|
## Evaluate pending icons against historical counts, returning UI decisions only.
|
|
static func unlocks(state: Dictionary, catalog, locked: Array) -> Dictionary:
|
|
var remaining: Array = []
|
|
var visible: Array = []
|
|
if locked.is_empty():
|
|
return {"remaining": remaining, "visible": visible}
|
|
var display_totals: Dictionary = amounts(state, catalog, true)
|
|
for id in locked:
|
|
var entity = catalog.entities[id]
|
|
var eligible: bool = true
|
|
for requirement in entity.unlock:
|
|
if E.lt(E.maximum(state.stats.total_amount.get(requirement, 0), display_totals.get(requirement, 0)), entity.unlock[requirement]):
|
|
eligible = false
|
|
break
|
|
if eligible:
|
|
for item_id in [id, entity.count_as]:
|
|
if (E.ne(item_id, "") and (not visible.has(item_id))):
|
|
visible.append(item_id)
|
|
else:
|
|
remaining.append(id)
|
|
return {"remaining": remaining, "visible": visible}
|