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; 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; std::shared_ptr<NXButtonRailTile> nxButtonTo() const;
bool reserve(const std::shared_ptr<Train>& train, bool dryRun = false); bool reserve(const std::shared_ptr<Train>& train, bool dryRun = false);
bool release(bool dryRun = false);
}; };
#endif #endif

Datei anzeigen

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

Datei anzeigen

@ -94,6 +94,7 @@ class BlockRailTile : public RailTile
const std::shared_ptr<BlockPath> getReservedPath(BlockSide side) const; 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 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 #endif

Datei anzeigen

@ -22,6 +22,12 @@
#include "bridgerailtile.hpp" #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_) BridgeRailTile::BridgeRailTile(World& world, std::string_view _id, TileId tileId_)
: RailTile(world, _id, tileId_) : RailTile(world, _id, tileId_)
, m_node{*this, 4} , 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) 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)) if((reservedState() & mask))
{ {
@ -40,8 +46,13 @@ bool BridgeRailTile::reserve(BridgePath path, bool dryRun)
if(!dryRun) if(!dryRun)
{ {
RailTile::reserve(reservedState() | mask); RailTile::setReservedState(reservedState() | mask);
} }
return true; 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; } std::optional<std::reference_wrapper<Node>> node() final { return m_node; }
bool reserve(BridgePath path, bool dryRun = false); bool reserve(BridgePath path, bool dryRun = false);
void release(BridgePath path);
}; };
#endif #endif

Datei anzeigen

@ -41,8 +41,19 @@ bool CrossRailTile::reserve(CrossState crossState, bool dryRun)
if(!dryRun) if(!dryRun)
{ {
m_crossState = crossState; m_crossState = crossState;
RailTile::reserve(static_cast<uint8_t>(m_crossState)); RailTile::setReservedState(static_cast<uint8_t>(m_crossState));
} }
return true; 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; } std::optional<std::reference_wrapper<Node>> node() final { return m_node; }
bool reserve(CrossState crossState, bool dryRun = false); bool reserve(CrossState crossState, bool dryRun = false);
bool release(bool dryRun = false);
}; };
#endif #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) void RailTile::setReservedState(uint8_t value)
{ {
if(m_reservedState != value) if(m_reservedState != value)

Datei anzeigen

@ -30,8 +30,6 @@ class RailTile : public Tile
private: private:
uint8_t m_reservedState = 0; uint8_t m_reservedState = 0;
void setReservedState(uint8_t value);
protected: protected:
RailTile(World& world, std::string_view _id, TileId tileId); RailTile(World& world, std::string_view _id, TileId tileId);
@ -40,12 +38,17 @@ class RailTile : public Tile
return m_reservedState; return m_reservedState;
} }
void reserve(uint8_t state); void setReservedState(uint8_t value);
public: public:
inline void reserve() 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; 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; return true;
} }

Datei anzeigen

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