give tile occupancy its own class, BuildingGrid
Eleven methods maintained m_tileOccupancy by hand — place, deconstruct, removeBuilding, placeImmediate, tickDeconstruction, findRotateInPlaceTarget and tryDirectCoupleDeposit all indexed a raw std::map<std::pair<int,int>, BuildingId> directly, so the invariant "occupancy stays in sync with placement" was re-implemented at every call site. They now ask and tell a small owned index instead: occupy / release / isOccupied / findOwner. BuildingGrid is a member of BuildingSystem, not a peer system: it has no per-tick behaviour and nothing outside BuildingSystem touches it. The internal keying stays std::pair<int,int> rather than moving to QPoint. The checksum folds the entries in map iteration order, so the comparator is part of the determinism contract; changing it is a separate decision, not a side effect of this move. Verified with a golden-checksum capture before and after — all four sample ticks identical. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YHcUerKAZKWNvSKJxYKbnG
This commit is contained in:
46
src/lib/sim/BuildingGrid.h
Normal file
46
src/lib/sim/BuildingGrid.h
Normal file
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <QPoint>
|
||||
|
||||
#include "BuildingId.h"
|
||||
|
||||
class Hasher;
|
||||
|
||||
// The authority on which building owns which world tile.
|
||||
//
|
||||
// Every building and construction site claims its body cells here when it is placed
|
||||
// and releases them when it is removed, so the map is the single place that knows
|
||||
// whether a tile is free. It is a plain index owned by BuildingSystem, not a system:
|
||||
// it has no per-tick behaviour and nothing outside BuildingSystem touches it.
|
||||
//
|
||||
// Keys are deliberately std::pair<int, int> rather than QPoint: the checksum folds the
|
||||
// entries in map iteration order (docs/replay_design.md), so the comparator is part of
|
||||
// the determinism contract and is not changed casually.
|
||||
class BuildingGrid
|
||||
{
|
||||
public:
|
||||
// Records absolute body cells as owned by id. Re-occupying a cell overwrites its
|
||||
// previous owner, matching the placement paths that reserve cells for a site and
|
||||
// then hand them to the building it becomes.
|
||||
void occupy(QPoint cell, BuildingId id);
|
||||
void occupy(const std::vector<QPoint>& cells, BuildingId id);
|
||||
|
||||
// Releases absolute body cells. Cells that are not occupied are ignored.
|
||||
void release(const std::vector<QPoint>& cells);
|
||||
|
||||
bool isOccupied(QPoint tile) const;
|
||||
|
||||
// The building owning the tile, or nullopt when the tile is free.
|
||||
std::optional<BuildingId> findOwner(QPoint tile) const;
|
||||
|
||||
// Folds the occupancy into the hasher in deterministic order.
|
||||
void appendChecksum(Hasher& hasher) const;
|
||||
|
||||
private:
|
||||
std::map<std::pair<int, int>, BuildingId> m_owners;
|
||||
};
|
||||
Reference in New Issue
Block a user