blockpath: added release()

Dieser Commit ist enthalten in:
Reinder Feenstra 2023-12-26 23:03:17 +01:00
Ursprung c80521104e
Commit 26255d368c
12 geänderte Dateien mit 174 neuen und 16 gelöschten Zeilen

Datei anzeigen

@ -437,3 +437,111 @@ bool BlockPath::reserve(const std::shared_ptr<Train>& train, bool dryRun)
return true;
}
bool BlockPath::release(bool dryRun)
{
if(!dryRun && !release(true)) // dry run first, to make sure it will succeed (else we need rollback support)
{
return false;
}
if(!m_fromBlock.release(m_fromSide, dryRun))
{
assert(dryRun);
return false;
}
if(auto toBlock = m_toBlock.lock()) /*[[likely]]*/
{
if(!toBlock->release(m_toSide, dryRun))
{
assert(dryRun);
return false;
}
}
else
{
return false;
}
for(const auto& item : m_turnouts)
{
if(auto turnout = item.first.lock())
{
if(!turnout->release(dryRun))
{
assert(dryRun);
return false;
}
}
else /*[[unlikely]]*/
{
assert(dryRun);
return false;
}
}
for(const auto& item : m_crossings)
{
if(auto cross = item.first.lock())
{
if(!cross->release(dryRun))
{
assert(dryRun);
return false;
}
}
else /*[[unlikely]]*/
{
assert(dryRun);
return false;
}
}
if(!dryRun)
{
for(const auto& item : m_directionControls)
{
if(auto directionControl = item.first.lock()) /*[[likely]]*/
{
directionControl->release();
}
}
for(const auto& [bridgeWeak, path] : m_bridges)
{
if(auto bridge = bridgeWeak.lock()) /*[[likely]]*/
{
bridge->release(path);
}
}
for(const auto& signalWeak : m_signals)
{
if(auto signal = signalWeak.lock()) /*[[likely]]*/
{
signal->release();
}
}
for(const auto& tileWeak : m_tiles)
{
if(auto tile = tileWeak.lock()) /*[[likely]]*/
{
static_cast<RailTile&>(*tile).release();
}
}
if(auto nxButton = m_nxButtonFrom.lock())
{
nxButton->release();
}
if(auto nxButton = m_nxButtonTo.lock())
{
nxButton->release();
}
}
return true;
}

Datei anzeigen

@ -98,6 +98,7 @@ class BlockPath : public Path, public std::enable_shared_from_this<BlockPath>
std::shared_ptr<NXButtonRailTile> nxButtonTo() const;
bool reserve(const std::shared_ptr<Train>& train, bool dryRun = false);
bool release(bool dryRun = false);
};
#endif

Datei anzeigen

@ -32,6 +32,11 @@
#include "../../../utils/displayname.hpp"
#include "../../map/blockpath.hpp"
constexpr uint8_t toMask(BlockSide side)
{
return 1 << static_cast<uint8_t>(side);
}
CREATE_IMPL(BlockRailTile)
BlockRailTile::BlockRailTile(World& world, std::string_view _id) :
@ -279,7 +284,7 @@ const std::shared_ptr<BlockPath> BlockRailTile::getReservedPath(BlockSide side)
bool BlockRailTile::reserve(const std::shared_ptr<BlockPath>& blockPath, const std::shared_ptr<Train>& train, BlockSide side, bool dryRun)
{
const uint8_t mask = 1 << static_cast<uint8_t>(side);
const uint8_t mask = toMask(side);
if(state == BlockState::Unknown)
{
@ -315,7 +320,7 @@ bool BlockRailTile::reserve(const std::shared_ptr<BlockPath>& blockPath, const s
if(!dryRun)
{
m_reservedPaths[static_cast<uint8_t>(side)] = blockPath;
RailTile::reserve(reservedState() | mask);
RailTile::setReservedState(reservedState() | mask);
if(state == BlockState::Free)
{
const auto direction = side == BlockSide::A ? BlockTrainDirection::TowardsB : BlockTrainDirection::TowardsA;
@ -328,6 +333,16 @@ bool BlockRailTile::reserve(const std::shared_ptr<BlockPath>& blockPath, const s
return true;
}
bool BlockRailTile::release(BlockSide side, bool dryRun)
{
if(!dryRun)
{
m_reservedPaths[static_cast<uint8_t>(side)].reset();
RailTile::setReservedState(reservedState() & ~toMask(side));
}
return true;
}
void BlockRailTile::updateState()
{
if(!inputMap->items.empty())

Datei anzeigen

@ -94,6 +94,7 @@ class BlockRailTile : public RailTile
const std::shared_ptr<BlockPath> getReservedPath(BlockSide side) const;
bool reserve(const std::shared_ptr<BlockPath>& blockPath, const std::shared_ptr<Train>& train, BlockSide side, bool dryRun = false);
bool release(BlockSide side, bool dryRun = false);
};
#endif

Datei anzeigen

@ -22,6 +22,12 @@
#include "bridgerailtile.hpp"
constexpr uint8_t toMask(BridgePath path)
{
return 1 << static_cast<uint8_t>(path);
}
BridgeRailTile::BridgeRailTile(World& world, std::string_view _id, TileId tileId_)
: RailTile(world, _id, tileId_)
, m_node{*this, 4}
@ -31,7 +37,7 @@ BridgeRailTile::BridgeRailTile(World& world, std::string_view _id, TileId tileId
bool BridgeRailTile::reserve(BridgePath path, bool dryRun)
{
const uint8_t mask = 1 << static_cast<uint8_t>(path);
const uint8_t mask = toMask(path);
if((reservedState() & mask))
{
@ -40,8 +46,13 @@ bool BridgeRailTile::reserve(BridgePath path, bool dryRun)
if(!dryRun)
{
RailTile::reserve(reservedState() | mask);
RailTile::setReservedState(reservedState() | mask);
}
return true;
}
void BridgeRailTile::release(BridgePath path)
{
RailTile::setReservedState(reservedState() & ~toMask(path));
}

Datei anzeigen

@ -41,6 +41,7 @@ class BridgeRailTile : public RailTile
std::optional<std::reference_wrapper<Node>> node() final { return m_node; }
bool reserve(BridgePath path, bool dryRun = false);
void release(BridgePath path);
};
#endif

Datei anzeigen

@ -41,8 +41,19 @@ bool CrossRailTile::reserve(CrossState crossState, bool dryRun)
if(!dryRun)
{
m_crossState = crossState;
RailTile::reserve(static_cast<uint8_t>(m_crossState));
RailTile::setReservedState(static_cast<uint8_t>(m_crossState));
}
return true;
}
bool CrossRailTile::release(bool dryRun)
{
//! \todo check occupy sensor, once supported
if(!dryRun)
{
RailTile::release();
}
return true;
}

Datei anzeigen

@ -42,6 +42,7 @@ class CrossRailTile : public RailTile
std::optional<std::reference_wrapper<Node>> node() final { return m_node; }
bool reserve(CrossState crossState, bool dryRun = false);
bool release(bool dryRun = false);
};
#endif

Datei anzeigen

@ -28,12 +28,6 @@ RailTile::RailTile(World& world, std::string_view _id, TileId tileId) :
{
}
void RailTile::reserve(uint8_t state)
{
assert(state != 0);
setReservedState(state);
}
void RailTile::setReservedState(uint8_t value)
{
if(m_reservedState != value)

Datei anzeigen

@ -30,8 +30,6 @@ class RailTile : public Tile
private:
uint8_t m_reservedState = 0;
void setReservedState(uint8_t value);
protected:
RailTile(World& world, std::string_view _id, TileId tileId);
@ -40,12 +38,17 @@ class RailTile : public Tile
return m_reservedState;
}
void reserve(uint8_t state);
void setReservedState(uint8_t value);
public:
inline void reserve()
{
reserve(1);
setReservedState(1);
}
inline void release()
{
setReservedState(0);
}
};

Datei anzeigen

@ -66,7 +66,18 @@ bool TurnoutRailTile::reserve(TurnoutPosition turnoutPosition, bool dryRun)
return false;
}
RailTile::reserve(static_cast<uint8_t>(turnoutPosition));
RailTile::setReservedState(static_cast<uint8_t>(turnoutPosition));
}
return true;
}
bool TurnoutRailTile::release(bool dryRun)
{
//! \todo check occupy sensor, once supported
if(!dryRun)
{
RailTile::release();
}
return true;
}

Datei anzeigen

@ -57,6 +57,7 @@ class TurnoutRailTile : public RailTile
std::optional<std::reference_wrapper<Node>> node() final { return m_node; }
virtual bool reserve(TurnoutPosition turnoutPosition, bool dryRun = false);
bool release(bool dryRun = false);
};
#endif