keep existing BlockPath objects alive when updating

this enables adding state to the BlockPath objects
Dieser Commit ist enthalten in:
Reinder Feenstra 2023-12-27 00:04:56 +01:00
Ursprung 26255d368c
Commit 8b221eea16
4 geänderte Dateien mit 55 neuen und 1 gelöschten Zeilen

Datei anzeigen

@ -47,6 +47,12 @@ static bool contains(const std::vector<std::pair<std::weak_ptr<T1>, T2>>& values
return it != values.end();
}
template <typename T>
static inline bool operator ==(const std::weak_ptr<T>& a, const std::weak_ptr<T>& b)
{
return !a.owner_before(b) && !b.owner_before(a);
}
std::vector<std::shared_ptr<BlockPath>> BlockPath::find(BlockRailTile& startBlock)
{
const auto& node = startBlock.node()->get();
@ -293,6 +299,23 @@ BlockPath::BlockPath(BlockRailTile& block, BlockSide side)
{
}
bool BlockPath::operator ==(const BlockPath& other) const noexcept
{
return
(&m_fromBlock == &other.m_fromBlock) &&
(m_fromSide == other.m_fromSide) &&
(m_toBlock == other.m_toBlock) &&
(m_toSide == other.m_toSide) &&
(m_tiles == other.m_tiles) &&
(m_turnouts == other.m_turnouts) &&
(m_directionControls == other.m_directionControls) &&
(m_crossings == other.m_crossings) &&
(m_bridges == other.m_bridges) &&
(m_signals == other.m_signals) &&
(m_nxButtonFrom == other.m_nxButtonFrom) &&
(m_nxButtonTo == other.m_nxButtonTo);
}
std::shared_ptr<NXButtonRailTile> BlockPath::nxButtonFrom() const
{
return m_nxButtonFrom.lock();

Datei anzeigen

@ -69,6 +69,8 @@ class BlockPath : public Path, public std::enable_shared_from_this<BlockPath>
BlockPath(BlockRailTile& block, BlockSide side);
bool operator ==(const BlockPath& other) const noexcept;
bool hasNXButtons() const
{
return !m_nxButtonFrom.expired() && !m_nxButtonTo.expired();

Datei anzeigen

@ -450,7 +450,35 @@ void BlockRailTile::setRotate(TileRotate value)
void BlockRailTile::boardModified()
{
m_paths = BlockPath::find(*this);
updatePaths(); //! \todo improvement: only update if a connected tile is changed
}
void BlockRailTile::updatePaths()
{
auto current = std::move(m_paths);
m_paths.clear(); // make sure it is empty, it problably is after the move
auto found = BlockPath::find(*this);
while(!current.empty())
{
auto it = std::find_if(found.begin(), found.end(),
[&currentPath=*current.front()](const auto& foundPath)
{
return currentPath == *foundPath;
});
if(it != found.end())
{
found.erase(it);
m_paths.emplace_back(std::move(current.front()));
}
current.erase(current.begin());
}
for(auto& path : found)
{
m_paths.emplace_back(std::move(path));
}
}
void BlockRailTile::updateHeightWidthMax()

Datei anzeigen

@ -50,6 +50,7 @@ class BlockRailTile : public RailTile
std::vector<std::shared_ptr<BlockPath>> m_paths;
std::array<std::weak_ptr<BlockPath>, 2> m_reservedPaths; // index is BlockSide
void updatePaths();
void updateHeightWidthMax();
protected: