Skip to content

Commit

Permalink
server: RailVehicle make activeTrain a NoStore property
Browse files Browse the repository at this point in the history
This makes loading more robust against file
corruption or invalid states.
The property is now set in Train::loaded()
or whole Train activation is discarded.
  • Loading branch information
gfgit committed Sep 12, 2024
1 parent 4e8b5a8 commit 7d0c52c
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 3 deletions.
59 changes: 57 additions & 2 deletions server/src/train/train.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,9 +223,9 @@ void Train::addToWorld()
void Train::destroying()
{
auto self = shared_ptr<Train>();
for(const auto& vehicle : *vehicles)
for(const auto& item : *vehicles)
{
vehicle->vehicle->trains.removeInternal(self);
item->vehicle->trains.removeInternal(self);
}
m_world.trains->removeObject(self);
IdObject::destroying();
Expand All @@ -238,7 +238,62 @@ void Train::loaded()
Attributes::setEnabled(lob, overrideLength);
Attributes::setEnabled(weight, overrideWeight);

if(active)
{
// Try activating all vehicles
bool allVehiclesFree = true;

for(const auto& item : *vehicles)
{
if(item->vehicle->activeTrain.value())
{
allVehiclesFree = false;
break;
}
}

if(allVehiclesFree && !vehicles->empty())
{
for(const auto& item : *vehicles)
{
item->vehicle->activeTrain.setValueInternal(shared_ptr<Train>());
}
}
else
{
// Maybe there was a file corruption, deactivate Train
active.setValueInternal(false);
}
}

// Update vehicle list state
vehiclesChanged();

if(active)
{
if(!emergencyStop)
{
// If one vehicle is in Emergency stop, sync all Train
bool atLeastOneEmergencyStop = false;

for(const auto& vehicle : m_poweredVehicles)
{
if(vehicle->decoder && vehicle->decoder->emergencyStop)
{
atLeastOneEmergencyStop = true;
break;
}
}
if(atLeastOneEmergencyStop)
emergencyStop.setValueInternal(atLeastOneEmergencyStop);
}

// Manually sync emergency stop
for(const auto& vehicle : m_poweredVehicles)
{
vehicle->setEmergencyStop(emergencyStop);
}
}
}

void Train::worldEvent(WorldState state, WorldEvent event)
Expand Down
2 changes: 1 addition & 1 deletion server/src/vehicle/rail/railvehicle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ RailVehicle::RailVehicle(World& world, std::string_view _id) :
speedMax{*this, "speed_max", 0, SpeedUnit::KiloMeterPerHour, PropertyFlags::ReadWrite | PropertyFlags::Store},
weight{*this, "weight", 0, WeightUnit::Ton, PropertyFlags::ReadWrite | PropertyFlags::Store, [this](double /*value*/, WeightUnit /*unit*/){ updateTotalWeight(); }},
totalWeight{*this, "total_weight", 0, WeightUnit::Ton, PropertyFlags::ReadOnly | PropertyFlags::NoStore},
activeTrain{this, "active_train", nullptr, PropertyFlags::ReadOnly | PropertyFlags::ScriptReadOnly | PropertyFlags::StoreState}
activeTrain{this, "active_train", nullptr, PropertyFlags::ReadOnly | PropertyFlags::ScriptReadOnly | PropertyFlags::NoStore}
, trains{*this, "trains", {}, PropertyFlags::ReadOnly | PropertyFlags::ScriptReadOnly | PropertyFlags::NoStore}
{
const bool editable = contains(m_world.state.value(), WorldState::Edit);
Expand Down

0 comments on commit 7d0c52c

Please sign in to comment.