Add new tests and implement frame budget management
- Introduced `civilization_benchmark.gd` and `legacy_quantity_math.gd` for benchmarking and legacy quantity calculations. - Created `test_dynamic_math.gd`, `test_frame_evolution.gd`, and `test_sparse_batches.gd` to validate mathematical operations and frame evolution logic. - Implemented `frame_budget.gd` to manage cooperative work on the main thread, ensuring no partially calculated state is published. - Added UID files for all new scripts to maintain unique identifiers.
This commit is contained in:
@@ -2,6 +2,7 @@ extends SceneTree
|
||||
const E = preload("res://world/owniverse/math/exact.gd")
|
||||
|
||||
const Math = preload("res://world/owniverse/quantity_math.gd")
|
||||
const Legacy = preload("res://tests/fixtures/legacy_quantity_math.gd")
|
||||
var checks: int = 0
|
||||
var failures: int = 0
|
||||
|
||||
@@ -15,6 +16,24 @@ func check(condition: bool, message: String) -> void:
|
||||
push_error(message)
|
||||
|
||||
func run() -> void:
|
||||
var rng = RandomNumberGenerator.new()
|
||||
rng.seed = 65432
|
||||
var old_remainders: Dictionary = {}
|
||||
var new_remainders: Dictionary = {}
|
||||
for sample in 300:
|
||||
var requests: Dictionary = {}
|
||||
var weights: Dictionary = {}
|
||||
for id in ["w", "m", "b", "c", "d", "l"]:
|
||||
requests[id] = E.of(str(rng.randi_range(-10, 100)) + "." + str(rng.randi_range(0, 9)))
|
||||
weights[id] = rng.randi_range(0, 100)
|
||||
if sample % 3 == 0:
|
||||
for id in requests: requests[id] = E.multiply(requests[id], E.of("1e40"))
|
||||
var limit: Variant = E.multiply(rng.randi_range(0, 600), E.of("1e40")) if sample % 3 == 0 else rng.randi_range(0, 600)
|
||||
check(E.eq(Math.allocate_whole(requests, limit), Legacy.allocate_whole(requests, limit)), "Allocation matches legacy with limits, ties and big integers")
|
||||
var count: Variant = limit
|
||||
check(E.eq(Math.split(new_remainders, "population", count, weights), Legacy.split(old_remainders, "population", count, weights)), "Split matches legacy rounding")
|
||||
check(E.eq(new_remainders, old_remainders), "Signed remainder debt matches legacy")
|
||||
check_ledger_cache()
|
||||
var Catalog = load("res://world/owniverse/entity_catalog.gd")
|
||||
check(E.eq(Math.allocate_whole({}, 10), {}), "Empty allocation")
|
||||
check(E.eq(Math.allocate_whole({"b": 1, "a": 1}, 1), {"a": 1, "b": 0}), "Stable lexical tie")
|
||||
@@ -62,3 +81,32 @@ func run() -> void:
|
||||
for entity in catalog.entities.values(): entity.free()
|
||||
print(("Quantity and catalog: %d checks, %d failures" % [checks, failures]))
|
||||
quit((1 if failures else 0))
|
||||
|
||||
func check_ledger_cache() -> void:
|
||||
var world = load("res://world/owniverse/owniverse.gd").new()
|
||||
world.catalog.load_definitions(root.get_node("Global").OwniverseEntities)
|
||||
world.state.amount.RD = E.of("1e40")
|
||||
world.state.binds.GEM = {"RD": 7}
|
||||
check(E.eq(world.ledger.physical_amounts(world.state).RD, E.add(E.of("1e40"), 7)), "Initial cached physical amount")
|
||||
var returned: Dictionary = world.ledger.physical_amounts(world.state)
|
||||
returned.RD = 0
|
||||
check(E.gt(world.ledger.physical_amounts(world.state).RD, 0), "Caller cannot mutate cached physical totals")
|
||||
world.state.binds.GEM.RD = 11
|
||||
check(E.eq(world.ledger.physical_amounts(world.state).RD, E.add(E.of("1e40"), 11)), "Nested binding change invalidates physical cache")
|
||||
world.state.amount.RD = 2
|
||||
check(E.eq(world.ledger.physical_amounts(world.state).RD, 13), "Direct count change invalidates physical cache")
|
||||
var other: Dictionary = world.state.duplicate(true)
|
||||
other.binds.clear()
|
||||
check(E.eq(world.ledger.physical_amounts(other).RD, 2), "Alternate state has independent physical totals")
|
||||
check(E.eq(world.ledger.physical_amounts(world.state).RD, 13), "Returning to original state refreshes cache")
|
||||
var revision: int = world.catalog.index_revision
|
||||
world.catalog.rebuild_group_index()
|
||||
check(world.catalog.index_revision > revision, "Catalog rebuild invalidates cached membership")
|
||||
check(E.eq(world.ledger.physical_amounts(world.state).RD, 13), "Rebuild retains correct physical totals")
|
||||
var rules: Dictionary = root.get_node("Global").CivilizationRules.duplicate(true)
|
||||
var original_stages: int = world.catalog.civilization_layout(rules).stages.size()
|
||||
rules["C2.0"].home = ""
|
||||
world.catalog.invalidate_civilization_layout()
|
||||
check(world.catalog.civilization_layout(rules).stages.size() == original_stages - 1, "Explicit rules change rebuilds civilization layout")
|
||||
for entity in world.catalog.entities.values(): entity.free()
|
||||
world.free()
|
||||
|
||||
Reference in New Issue
Block a user