Continues the ConfigLoader.cpp domain split. parseRotationString and
parsePlacedModules are only used by loadShips, so they move along as
domain-local anonymous-namespace helpers rather than into TomlHelpers.
Pure move; no logic change.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YHcUerKAZKWNvSKJxYKbnG
Continues the ConfigLoader.cpp domain split. parseRecipeOutputs is only
used by loadRecipes, so it moves along as a domain-local anonymous-
namespace helper rather than into TomlHelpers. Pure move; no logic
change.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YHcUerKAZKWNvSKJxYKbnG
ConfigLoader.cpp had grown to 877 lines by mixing generic TOML-parsing
helpers (used by every per-file loader) with per-domain parsing logic.
Splitting the file per config domain first requires pulling out the
helpers shared by two or more domains, so each domain .cpp can include
them without duplication. Pure move: no logic, message, or ordering
changes.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YHcUerKAZKWNvSKJxYKbnG
TickAdvanced, BuildingBlocksChanged, ExpansionCostChanged, BossWaveUpdated and
ArtifactCountChanged all duplicated state the Simulation already owns. With
every subscriber re-reading from the sim, the fields had no readers left, so
the five events become payload-free refresh signals and the emitters keep the
values only as locals for change detection.
This makes the convention uniform: a state-change event backed by the
simulation carries nothing. Events whose state lives in the view (selection,
game speed, deconstruct and debug-draw modes) keep their payloads, since there
is no sim getter behind them.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YHcUerKAZKWNvSKJxYKbnG
BuildingSystem::findBuildingDef was a byte-equivalent re-implementation of
BuildingsConfig::findBuildingDef. Same cleanup as the GameWorldView copy;
this one sits in the sim layer, so it was missed by both earlier passes.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GH8ZMRY3vhxxXcaUxBqxkk
The two executors were line-for-line duplicates: orbit the behavior target,
then hand it to the owner's in-range modules. Both now call a templated
executeOrbitAndAssign<Behavior, ModuleComponent>; the view types, iteration
order, and sequence of component writes are unchanged.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GH8ZMRY3vhxxXcaUxBqxkk
The constructor and reset() held a character-for-character identical
26-line subsystem construction block, including three capturing lambdas.
Both run before the first tick, so the closures can be shared. Order is
unchanged.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GH8ZMRY3vhxxXcaUxBqxkk
Ships/Modules/RecipesConfig now carry lookup helpers mirroring
BuildingsConfig::findBuildingDef. The hand-rolled linear scans in
BuildingSystem, ShipSystem, ShipStatsCalculator, ThreatCostCalculator,
ShipLayoutDialog, SelectedBuildingPanel and SchematicChoiceDialog now
call them instead.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GH8ZMRY3vhxxXcaUxBqxkk
rotateInPlace re-implemented the belt-tile re-registration switch inline
instead of calling reregisterBeltTile, and its splitter branch omitted the
setSplitterFilters call the canonical version has. Since an operational
splitter keeps its filters only in BeltSystem, removeTile discarded them and
rotating a configured splitter silently reset it to "accept all".
Replace the duplicated switch with a call to reregisterBeltTile, capturing
the filters beforehand via getSplitterInfo — the same idiom deconstruct
already uses. This removes the second copy of the switch that allowed the
two to drift apart in the first place.
Add a regression test; the existing [rotate-in-place] cases covered belt
tiles only, which is why this went unnoticed.
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GH8ZMRY3vhxxXcaUxBqxkk