make BuildingSystem stateless: FactoryState becomes a parameter

The member reference is gone. All 23 methods that read or write the factory now
take FactoryState& (const for the two item walks and the checksum fold), so a
BuildingSystem is no longer bound to one state and its signatures say which data
each call touches. It holds only config, belts, rng and the callbacks — the same
shape as AiSystem and CombatSystem.

This completes what phase 2 set out to do; the ownership move landed earlier, but
the systems kept reaching the data through a member until the queries were off
them.

Seeding the asteroid bound moved with the state, and that broke four tests: the
fixtures build their own FactoryState, which defaulted the bound to 0 and refused
every placement on the asteroid. Rather than fix the four call sites, makeFactoryState()
now creates a run's state from the config, and Simulation, ArenaSimulation and the
test fixtures all use it — there is one place that knows what a fresh factory
looks like.

Verified with a golden-checksum capture before and after — all four sample ticks
identical — and by re-running the declaration/definition check over the header.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YHcUerKAZKWNvSKJxYKbnG
This commit is contained in:
2026-08-04 23:00:09 +02:00
parent 7ce0751c60
commit a90218f5c0
15 changed files with 401 additions and 395 deletions

View File

@@ -56,7 +56,7 @@
struct Fixture
{
GameConfig cfg;
FactoryState state;
FactoryState state = makeFactoryState(cfg);
BeltSystem belts;
BuildingId nextBuildingId;
int stock;
@@ -79,7 +79,7 @@ struct Fixture
, nextBuildingId(1)
, stock(0)
, rng(42)
, buildings(cfg, state, belts,
, buildings(cfg, belts,
[this]() { return nextBuildingId++; },
[this](int n) { stock += n; },
[](const std::string&, QVector2D, const std::optional<ShipLayoutConfig>&) {},
@@ -952,12 +952,12 @@ TEST_CASE("BehaviorSystem: full-cargo salvage ship moves toward SalvageBay", "[b
{
Fixture f;
const BuildingId bayId = f.buildings.place(BuildingType::SalvageBay,
const BuildingId bayId = f.buildings.place(f.state, BuildingType::SalvageBay,
QPoint(-4, 0), Rotation::East, 0).value();
Tick t = 0;
for (int i = 0; i < 500; ++i)
{
f.buildings.tickConstruction(t++);
f.buildings.tickConstruction(f.state, t++);
if (findBuilding(f.state, bayId) != nullptr)
{
break;
@@ -987,12 +987,12 @@ TEST_CASE("SalvagerSystem: full-cargo ship at its SalvageBay hands over cargo",
{
Fixture f;
const BuildingId bayId = f.buildings.place(BuildingType::SalvageBay,
const BuildingId bayId = f.buildings.place(f.state, BuildingType::SalvageBay,
QPoint(-4, 0), Rotation::East, 0).value();
Tick t = 0;
for (int i = 0; i < 500; ++i)
{
f.buildings.tickConstruction(t++);
f.buildings.tickConstruction(f.state, t++);
if (findBuilding(f.state, bayId) != nullptr) { break; }
}
const Building* bay = findBuilding(f.state, bayId);