migrate every factory query off BuildingSystem onto the free functions

This commit is contained in:
2026-08-05 06:45:49 +02:00
parent 1fb63cce4e
commit 58b94223f7
20 changed files with 212 additions and 244 deletions

View File

@@ -1,4 +1,5 @@
#include "BuildingConfig.h"
#include "FactoryQueries.h"
#include <algorithm>
#include <climits>
@@ -26,8 +27,8 @@ struct SelectedBuilding
// (the HQ and defence stations, per REQ-UI-BLUEPRINT-CREATE).
std::optional<SelectedBuilding> resolvePlaceable(const Simulation& sim, BuildingId id)
{
const Building* building = sim.getBuildings().findBuilding(id);
const ConstructionSite* site = building ? nullptr : sim.getBuildings().findSite(id);
const Building* building = findBuilding(sim.getFactoryState(), id);
const ConstructionSite* site = building ? nullptr : findSite(sim.getFactoryState(), id);
if (!building && !site)
{
return std::nullopt;
@@ -52,8 +53,8 @@ std::optional<SelectedBuilding> resolvePlaceable(const Simulation& sim, Building
std::optional<BuildingConfig> readBuildingConfig(const Simulation& sim, BuildingId id)
{
const Building* building = sim.getBuildings().findBuilding(id);
const ConstructionSite* site = building ? nullptr : sim.getBuildings().findSite(id);
const Building* building = findBuilding(sim.getFactoryState(), id);
const ConstructionSite* site = building ? nullptr : findSite(sim.getFactoryState(), id);
if (!building && !site)
{
return std::nullopt;

View File

@@ -241,11 +241,11 @@ std::vector<Port> BuildingSystem::computeInputPorts(
std::vector<Port> BuildingSystem::getInputPorts(BuildingId id) const
{
if (const Building* building = findBuilding(id))
if (const Building* building = findBuilding(m_state, id))
{
return building->inputPorts;
}
if (const ConstructionSite* site = findSite(id))
if (const ConstructionSite* site = findSite(m_state, id))
{
// A site stores no ports; derive its output ports from the mask (absolute)
// and run the same input-edge scan (REQ-BLD-BELT-DRAG, REQ-MAT-INPUT-PORTS).
@@ -825,7 +825,7 @@ void BuildingSystem::cancelDeconstruction(BuildingId id)
// Resume operation: clear the flag and re-register belt/tunnel/splitter
// tiles that were unregistered at enqueue (which re-pairs tunnels,
// REQ-BLD-TUNNEL-PAIR). Deconstruction progress is discarded; no refund.
if (Building* building = findBuildingMutable(id))
if (Building* building = findBuilding(m_state, id))
{
building->queuedForDeconstruction = false;
reregisterBeltTile(*building, it->splitterFilterA, it->splitterFilterB);
@@ -838,12 +838,6 @@ void BuildingSystem::cancelDeconstruction(BuildingId id)
}
}
bool BuildingSystem::isQueuedForDeconstruction(BuildingId id) const
{
const Building* building = findBuilding(id);
return building && building->queuedForDeconstruction;
}
void BuildingSystem::tickBeltPull()
{
TRACE();
@@ -941,7 +935,7 @@ bool BuildingSystem::tryDirectCoupleDeposit(BuildingId producerId,
return false;
}
Building* consumer = findBuildingMutable(*ownerId);
Building* consumer = findBuilding(m_state, *ownerId);
if (!consumer)
{
return false; // an unbuilt construction site, or not an operational building
@@ -1263,41 +1257,6 @@ void BuildingSystem::forEachIncomingItem(
// Queries
// ---------------------------------------------------------------------------
const Building* BuildingSystem::findBuilding(BuildingId id) const
{
return ::findBuilding(m_state, id);
}
Building* BuildingSystem::findBuildingMutable(BuildingId id)
{
return ::findBuilding(m_state, id);
}
const ConstructionSite* BuildingSystem::findSite(BuildingId id) const
{
return ::findSite(m_state, id);
}
std::vector<Building> BuildingSystem::getAllBuildings() const
{
return ::getAllBuildings(m_state);
}
std::vector<ConstructionSite> BuildingSystem::getAllSites() const
{
return ::getAllSites(m_state);
}
int BuildingSystem::getProductionBuildingCount() const
{
return ::getProductionBuildingCount(m_state);
}
int BuildingSystem::getActiveProductionBuildingCount() const
{
return ::getActiveProductionBuildingCount(m_state);
}
std::vector<const RecipeDef*>
BuildingSystem::gatherCandidateRecipes(const Building& b) const
{
@@ -1471,11 +1430,6 @@ std::vector<BuildingSystem::BeltTileInfo> BuildingSystem::getAllBeltTiles() cons
return result;
}
bool BuildingSystem::isTileOccupied(QPoint tile) const
{
return ::isTileOccupied(m_state, tile);
}
std::optional<BuildingId> BuildingSystem::findRotateInPlaceTarget(
BuildingType type, QPoint anchor, Rotation rot) const
{
@@ -1591,17 +1545,6 @@ void BuildingSystem::rotateInPlace(BuildingId id, Rotation newRotation)
}
}
const Building* BuildingSystem::findNearestBuilding(QVector2D worldPos,
BuildingType type) const
{
return ::findNearestBuilding(m_state, worldPos, type);
}
bool BuildingSystem::deliverScrapToSalvageBay(BuildingId bayId)
{
return ::deliverScrapToSalvageBay(m_state, bayId);
}
BuildingId BuildingSystem::placeImmediate(BuildingType type,
const std::vector<std::string>& surfaceMask,
QPoint anchor, Rotation rotation)

View File

@@ -94,7 +94,6 @@ public:
void cancelDeconstruction(BuildingId id);
// True if the building is currently in the deconstruction queue.
bool isQueuedForDeconstruction(BuildingId id) const;
// Set the recipe (or schematic id for shipyard) on a building or queued
// construction site. Clears both buffers on an operational building.
@@ -140,18 +139,12 @@ public:
Rotation directionB; // Splitter: second output; Belt: same as directionA
};
const Building* findBuilding(BuildingId id) const;
const ConstructionSite* findSite(BuildingId id) const;
std::vector<Building> getAllBuildings() const;
std::vector<ConstructionSite> getAllSites() const;
// REQ-UI-DEBUG-OVERLAY "Max Factory Production": count of completed
// (operational) Miner/Smelter/Assembler/ReprocessingPlant/Shipyard buildings.
int getProductionBuildingCount() const;
// REQ-UI-DEBUG-OVERLAY "Current Factory Production": subset of the above
// that currently has an active production cycle.
int getActiveProductionBuildingCount() const;
// Production state for the UI status light (REQ-UI-STATUS-LIGHT). Returns
// nullopt for building types that show no light (belts, splitters, tunnels,
@@ -159,7 +152,6 @@ public:
// Producing while its output buffer holds scrap, Starved when empty.
std::optional<ProductionStatus> getProductionStatus(const Building& building) const;
std::vector<BeltTileInfo> getAllBeltTiles() const;
bool isTileOccupied(QPoint tile) const;
// Visits every item currently emerging from a building output port on its
// virtual output belt (REQ-MAT-OUTPUT-EMERGE), passing the item type and its
@@ -186,8 +178,6 @@ public:
// currently on the tile are discarded by BeltSystem::removeTile).
void rotateInPlace(BuildingId id, Rotation newRotation);
// Find nearest operational building of the given type; nullptr if none.
const Building* findNearestBuilding(QVector2D worldPos, BuildingType type) const;
// Input-capable adjacent tiles for a building or construction site
// (REQ-BLD-BELT-DRAG, REQ-MAT-INPUT-PORTS): each returned Port.tile is the
@@ -201,7 +191,6 @@ public:
// Place one "scrap" item into a SalvageBay's output buffer.
// Returns false if bay not found, wrong type, or output buffer is full.
bool deliverScrapToSalvageBay(BuildingId bayId);
// Bypass the construction queue and create a fully-operational Building
// immediately. Used for pre-placed structures (HQ, defence stations).
@@ -234,7 +223,6 @@ private:
const std::vector<ItemType>& splitterFilterA,
const std::vector<ItemType>& splitterFilterB);
Building* findBuildingMutable(BuildingId id);
// True if the consumer would accept `type` at the given input port right now:
// it is a required input (or a building block for the HQ), the reservation-aware
// buffer has room, and the input belt entry is free (REQ-MAT-INPUT-INTAKE).

View File

@@ -77,6 +77,12 @@ bool isTileOccupied(const FactoryState& state, QPoint tile)
return state.grid.isOccupied(tile);
}
bool isQueuedForDeconstruction(const FactoryState& state, BuildingId id)
{
const Building* building = findBuilding(state, id);
return building && building->queuedForDeconstruction;
}
const Building* findNearestBuilding(const FactoryState& state, QVector2D worldPos,
BuildingType type)
{

View File

@@ -39,6 +39,9 @@ int getActiveProductionBuildingCount(const FactoryState& state);
bool isTileOccupied(const FactoryState& state, QPoint tile);
// True while the building is in the deconstruction queue (REQ-BLD-DECON-QUEUE).
bool isQueuedForDeconstruction(const FactoryState& state, BuildingId id);
// The nearest building of the given type to a world position, or nullptr when
// none exists. Distance is measured to the building's footprint centre.
const Building* findNearestBuilding(const FactoryState& state, QVector2D worldPos,

View File

@@ -1,5 +1,7 @@
#include "Simulation.h"
#include "FactoryQueries.h"
#include <algorithm>
#include <cassert>
#include <cmath>
@@ -811,12 +813,12 @@ double Simulation::getThreatAccumulationRate() const
double Simulation::getMaxFactoryProductionThreatRate() const
{
return static_cast<double>(m_buildingSystem->getProductionBuildingCount());
return static_cast<double>(getProductionBuildingCount(m_factoryState));
}
double Simulation::getCurrentFactoryProductionThreatRate() const
{
return static_cast<double>(m_buildingSystem->getActiveProductionBuildingCount());
return static_cast<double>(getActiveProductionBuildingCount(m_factoryState));
}
int Simulation::getBossWaveCounter() const
@@ -895,6 +897,11 @@ BuildingSystem& Simulation::getBuildingsMutable()
return *m_buildingSystem;
}
const FactoryState& Simulation::getFactoryState() const
{
return m_factoryState;
}
const BuildingSystem& Simulation::getBuildings() const
{
return *m_buildingSystem;

View File

@@ -119,6 +119,9 @@ public:
// chokepoint) or, in tests, SimulationTestAccess — so production code cannot
// mutate the factory outside the recorded command path (docs/replay_design.md).
const BuildingSystem& getBuildings() const;
// The factory's world data, for the free queries in FactoryQueries.h.
const FactoryState& getFactoryState() const;
const BeltSystem& getBelts() const;
ShipSystem& getShips();
const ShipSystem& getShips() const;