hand BuildingSystem the belts per call, as its siblings get them
The last system holding a piece of the world as a member. ConstructionSystem and ProductionSystem take the transport layer as a tick argument; BuildingSystem kept a BeltSystem& from construction, so the same object arrived two different ways depending on which system you were reading. Three methods need it -- deconstruct, cancelDeconstruction and rotateInPlace, all of which register or unregister a belt tile -- and they now take it after the state, in the argument order the other systems use. The constructor is down to the config alone. CombatSystemTest's fixture kept a BeltSystem only to pass it here, so that goes too. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Ne3mejABZoLWKLh8fgpM3x
This commit is contained in:
@@ -10,9 +10,8 @@
|
||||
#include "SurfaceMask.h"
|
||||
|
||||
|
||||
BuildingSystem::BuildingSystem(const GameConfig& config, BeltSystem& belts)
|
||||
BuildingSystem::BuildingSystem(const GameConfig& config)
|
||||
: m_config(config)
|
||||
, m_belts(belts)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -75,7 +74,8 @@ std::optional<BuildingId> BuildingSystem::place(FactoryState& state, BuildingTyp
|
||||
// Deconstruct
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void BuildingSystem::deconstruct(FactoryState& state, BuildingId id, Tick currentTick)
|
||||
void BuildingSystem::deconstruct(FactoryState& state, BeltSystem& belts, BuildingId id,
|
||||
Tick currentTick)
|
||||
{
|
||||
// Construction site? Removed instantly with the full refund; never queued
|
||||
// for deconstruction (REQ-BLD-DECONSTRUCT).
|
||||
@@ -116,7 +116,7 @@ void BuildingSystem::deconstruct(FactoryState& state, BuildingId id, Tick curren
|
||||
if (building.type == BuildingType::Splitter)
|
||||
{
|
||||
if (const std::optional<BeltSystem::SplitterInfo> info =
|
||||
m_belts.getSplitterInfo(building.anchor))
|
||||
belts.getSplitterInfo(building.anchor))
|
||||
{
|
||||
entry.splitterFilterA = info->filterA;
|
||||
entry.splitterFilterB = info->filterB;
|
||||
@@ -124,7 +124,7 @@ void BuildingSystem::deconstruct(FactoryState& state, BuildingId id, Tick curren
|
||||
}
|
||||
if (isBeltSubsystemType(building.type))
|
||||
{
|
||||
m_belts.removeTile(building.anchor);
|
||||
belts.removeTile(building.anchor);
|
||||
}
|
||||
|
||||
const bool wasEmpty = state.deconstructionQueue.empty();
|
||||
@@ -274,7 +274,8 @@ void BuildingSystem::setSiteSplitterFilters(FactoryState& state, BuildingId id,
|
||||
// Tick hooks
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
void BuildingSystem::cancelDeconstruction(FactoryState& state, BuildingId id)
|
||||
void BuildingSystem::cancelDeconstruction(FactoryState& state, BeltSystem& belts,
|
||||
BuildingId id)
|
||||
{
|
||||
for (std::deque<DeconstructionEntry>::iterator it = state.deconstructionQueue.begin();
|
||||
it != state.deconstructionQueue.end();
|
||||
@@ -288,7 +289,7 @@ void BuildingSystem::cancelDeconstruction(FactoryState& state, BuildingId id)
|
||||
if (Building* building = findBuilding(state, id))
|
||||
{
|
||||
building->queuedForDeconstruction = false;
|
||||
reregisterBeltTile(m_belts, m_config, *building, it->splitterFilterA, it->splitterFilterB);
|
||||
reregisterBeltTile(belts, m_config, *building, it->splitterFilterA, it->splitterFilterB);
|
||||
}
|
||||
|
||||
state.deconstructionQueue.erase(it);
|
||||
@@ -298,7 +299,8 @@ void BuildingSystem::cancelDeconstruction(FactoryState& state, BuildingId id)
|
||||
}
|
||||
}
|
||||
|
||||
void BuildingSystem::rotateInPlace(FactoryState& state, BuildingId id, Rotation newRotation)
|
||||
void BuildingSystem::rotateInPlace(FactoryState& state, BeltSystem& belts, BuildingId id,
|
||||
Rotation newRotation)
|
||||
{
|
||||
// Construction site path — just update rotation; no ports to recompute.
|
||||
for (ConstructionSite& site : state.constructionQueue)
|
||||
@@ -348,15 +350,15 @@ void BuildingSystem::rotateInPlace(FactoryState& state, BuildingId id, Rotation
|
||||
if (b.type == BuildingType::Splitter)
|
||||
{
|
||||
if (const std::optional<BeltSystem::SplitterInfo> info =
|
||||
m_belts.getSplitterInfo(b.anchor))
|
||||
belts.getSplitterInfo(b.anchor))
|
||||
{
|
||||
splitterFilterA = info->filterA;
|
||||
splitterFilterB = info->filterB;
|
||||
}
|
||||
}
|
||||
|
||||
m_belts.removeTile(b.anchor);
|
||||
reregisterBeltTile(m_belts, m_config, b, splitterFilterA, splitterFilterB);
|
||||
belts.removeTile(b.anchor);
|
||||
reregisterBeltTile(belts, m_config, b, splitterFilterA, splitterFilterB);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
class BuildingSystem
|
||||
{
|
||||
public:
|
||||
BuildingSystem(const GameConfig& config, BeltSystem& belts);
|
||||
explicit BuildingSystem(const GameConfig& config);
|
||||
|
||||
// -- Placement / deconstruct ------------------------------------------------
|
||||
// Returns the new entity id, or nullopt if the placement falls outside the
|
||||
@@ -60,13 +60,14 @@ public:
|
||||
// queue (REQ-BLD-DECON-QUEUE) and stops operating at once; its (partial) refund is
|
||||
// credited later, on completion, by DeconstructionSystem. No-op for unknown ids and
|
||||
// for a building already queued.
|
||||
void deconstruct(FactoryState& state, BuildingId id, Tick currentTick);
|
||||
void deconstruct(FactoryState& state, BeltSystem& belts, BuildingId id,
|
||||
Tick currentTick);
|
||||
|
||||
// Take a building back out of the deconstruction queue before it is removed
|
||||
// (REQ-BLD-DECON-QUEUE). Clears its queued flag and resumes operation
|
||||
// (re-registering belt/tunnel/splitter tiles); discards deconstruction
|
||||
// progress and credits no refund. No-op if the id is not queued.
|
||||
void cancelDeconstruction(FactoryState& state, BuildingId id);
|
||||
void cancelDeconstruction(FactoryState& state, BeltSystem& belts, BuildingId id);
|
||||
|
||||
// Set the recipe (or schematic id for shipyard) on a building or queued
|
||||
// construction site. Clears both buffers on an operational building.
|
||||
@@ -99,7 +100,8 @@ public:
|
||||
// Rotate an existing building or construction site to newRotation in place.
|
||||
// For belt-type operational buildings, re-registers with BeltSystem (items
|
||||
// currently on the tile are discarded by BeltSystem::removeTile).
|
||||
void rotateInPlace(FactoryState& state, BuildingId id, Rotation newRotation);
|
||||
void rotateInPlace(FactoryState& state, BeltSystem& belts, BuildingId id,
|
||||
Rotation newRotation);
|
||||
|
||||
// Register / unregister tile occupancy for ECS station entities.
|
||||
void registerTileOccupancy(FactoryState& state, const std::vector<QPoint>& cells, BuildingId ownerPlaceholder);
|
||||
@@ -116,11 +118,9 @@ public:
|
||||
void forEachBuilding(FactoryState& state, std::function<void(Building&)> fn);
|
||||
|
||||
private:
|
||||
// No world data here: the factory arrives per call (FactoryState.h). The config says
|
||||
// what a building costs, occupies and can run; the belts are what a placed, rotated or
|
||||
// demolished belt tile must be registered with and unregistered from. Nothing else --
|
||||
// no RNG and no callbacks, those having gone to ProductionSystem with the material
|
||||
// flow that needed them.
|
||||
// The config alone: what a building costs, occupies and can run. No world data --
|
||||
// the factory and the transport layer both arrive per call, as they do for
|
||||
// ConstructionSystem and ProductionSystem (FactoryState.h) -- and no RNG or callbacks,
|
||||
// those having gone to ProductionSystem with the material flow that needed them.
|
||||
const GameConfig& m_config;
|
||||
BeltSystem& m_belts;
|
||||
};
|
||||
|
||||
@@ -108,7 +108,7 @@ void Simulation::reset(unsigned int seed)
|
||||
|
||||
void Simulation::initializeSubsystems()
|
||||
{
|
||||
m_buildingSystem = std::make_unique<BuildingSystem>(m_config, m_beltSystem);
|
||||
m_buildingSystem = std::make_unique<BuildingSystem>(m_config);
|
||||
m_productionSystem = std::make_unique<ProductionSystem>(
|
||||
m_config,
|
||||
[this](const std::string& id, QVector2D pos,
|
||||
@@ -174,7 +174,8 @@ void Simulation::apply(const Command& command)
|
||||
case CommandKind::RotateInPlace:
|
||||
{
|
||||
const RotateInPlaceCommand& c = static_cast<const RotateInPlaceCommand&>(command);
|
||||
m_buildingSystem->rotateInPlace(m_factoryState, *c.id, c.newRotation);
|
||||
m_buildingSystem->rotateInPlace(m_factoryState, m_beltSystem, *c.id,
|
||||
c.newRotation);
|
||||
break;
|
||||
}
|
||||
case CommandKind::SetRecipe:
|
||||
@@ -888,12 +889,12 @@ std::optional<BuildingId> Simulation::tryPlaceBuilding(BuildingType type, QPoint
|
||||
|
||||
void Simulation::deconstruct(BuildingId id)
|
||||
{
|
||||
m_buildingSystem->deconstruct(m_factoryState, id, m_currentTick);
|
||||
m_buildingSystem->deconstruct(m_factoryState, m_beltSystem, id, m_currentTick);
|
||||
}
|
||||
|
||||
void Simulation::cancelDeconstruction(BuildingId id)
|
||||
{
|
||||
m_buildingSystem->cancelDeconstruction(m_factoryState, id);
|
||||
m_buildingSystem->cancelDeconstruction(m_factoryState, m_beltSystem, id);
|
||||
}
|
||||
|
||||
BuildingSystem& Simulation::getBuildingsMutable()
|
||||
|
||||
Reference in New Issue
Block a user