From 8b221eea16b864cccd4bc5ed0dfc9e31a067b0b9 Mon Sep 17 00:00:00 2001 From: Reinder Feenstra Date: Wed, 27 Dec 2023 00:04:56 +0100 Subject: [PATCH] keep existing BlockPath objects alive when updating this enables adding state to the BlockPath objects --- server/src/board/map/blockpath.cpp | 23 +++++++++++++++ server/src/board/map/blockpath.hpp | 2 ++ server/src/board/tile/rail/blockrailtile.cpp | 30 +++++++++++++++++++- server/src/board/tile/rail/blockrailtile.hpp | 1 + 4 files changed, 55 insertions(+), 1 deletion(-) diff --git a/server/src/board/map/blockpath.cpp b/server/src/board/map/blockpath.cpp index bad74d7f..1bba6ca6 100644 --- a/server/src/board/map/blockpath.cpp +++ b/server/src/board/map/blockpath.cpp @@ -47,6 +47,12 @@ static bool contains(const std::vector, T2>>& values return it != values.end(); } +template +static inline bool operator ==(const std::weak_ptr& a, const std::weak_ptr& b) +{ + return !a.owner_before(b) && !b.owner_before(a); +} + std::vector> 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 BlockPath::nxButtonFrom() const { return m_nxButtonFrom.lock(); diff --git a/server/src/board/map/blockpath.hpp b/server/src/board/map/blockpath.hpp index c14aea3d..fc72cd33 100644 --- a/server/src/board/map/blockpath.hpp +++ b/server/src/board/map/blockpath.hpp @@ -69,6 +69,8 @@ class BlockPath : public Path, public std::enable_shared_from_this BlockPath(BlockRailTile& block, BlockSide side); + bool operator ==(const BlockPath& other) const noexcept; + bool hasNXButtons() const { return !m_nxButtonFrom.expired() && !m_nxButtonTo.expired(); diff --git a/server/src/board/tile/rail/blockrailtile.cpp b/server/src/board/tile/rail/blockrailtile.cpp index 426cd761..23fd5f9f 100644 --- a/server/src/board/tile/rail/blockrailtile.cpp +++ b/server/src/board/tile/rail/blockrailtile.cpp @@ -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(), + [¤tPath=*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() diff --git a/server/src/board/tile/rail/blockrailtile.hpp b/server/src/board/tile/rail/blockrailtile.hpp index e0b111dc..1cab77b2 100644 --- a/server/src/board/tile/rail/blockrailtile.hpp +++ b/server/src/board/tile/rail/blockrailtile.hpp @@ -50,6 +50,7 @@ class BlockRailTile : public RailTile std::vector> m_paths; std::array, 2> m_reservedPaths; // index is BlockSide + void updatePaths(); void updateHeightWidthMax(); protected: