Tracerestrict: Move slot temporary state to a separate struct

pull/642/head
Jonathan G Rennison 8 months ago
parent 293b5c9435
commit ffbb30996a

@ -75,9 +75,6 @@ INSTANTIATE_POOL_METHODS(TraceRestrictSlot)
TraceRestrictCounterPool _tracerestrictcounter_pool("TraceRestrictCounter"); TraceRestrictCounterPool _tracerestrictcounter_pool("TraceRestrictCounter");
INSTANTIATE_POOL_METHODS(TraceRestrictCounter) INSTANTIATE_POOL_METHODS(TraceRestrictCounter)
std::vector<TraceRestrictSlotID> TraceRestrictSlot::veh_temporarily_added;
std::vector<TraceRestrictSlotID> TraceRestrictSlot::veh_temporarily_removed;
/** /**
* TraceRestrictRefId --> TraceRestrictProgramID (Pool ID) mapping * TraceRestrictRefId --> TraceRestrictProgramID (Pool ID) mapping
* The indirection is mainly to enable shared programs * The indirection is mainly to enable shared programs
@ -245,10 +242,13 @@ static bool TestStationCondition(StationID station, TraceRestrictItem item)
*/ */
void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInput &input, TraceRestrictProgramResult& out) const void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInput &input, TraceRestrictProgramResult& out) const
{ {
// static to avoid needing to re-alloc/resize on each execution /* static to avoid needing to re-alloc/resize on each execution */
static std::vector<TraceRestrictCondStackFlags> condstack; static std::vector<TraceRestrictCondStackFlags> condstack;
condstack.clear(); condstack.clear();
/* Only for use with TRPISP_PBS_RES_END_ACQ_DRY and TRPAUF_PBS_RES_END_SIMULATE */
static TraceRestrictSlotTemporaryState pbs_res_end_acq_dry_slot_temporary_state;
byte have_previous_signal = 0; byte have_previous_signal = 0;
TileIndex previous_signal_tile[3]; TileIndex previous_signal_tile[3];
@ -751,7 +751,7 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp
if (!slot->Occupy(v->index)) out.flags |= TRPRF_PBS_RES_END_WAIT; if (!slot->Occupy(v->index)) out.flags |= TRPRF_PBS_RES_END_WAIT;
} else if (input.permitted_slot_operations & TRPISP_PBS_RES_END_ACQ_DRY) { } else if (input.permitted_slot_operations & TRPISP_PBS_RES_END_ACQ_DRY) {
if (this->actions_used_flags & TRPAUF_PBS_RES_END_SIMULATE) { if (this->actions_used_flags & TRPAUF_PBS_RES_END_SIMULATE) {
if (!slot->OccupyDryRunUsingTemporaryState(v->index)) out.flags |= TRPRF_PBS_RES_END_WAIT; if (!slot->OccupyUsingTemporaryState(v->index, &pbs_res_end_acq_dry_slot_temporary_state)) out.flags |= TRPRF_PBS_RES_END_WAIT;
} else { } else {
if (!slot->OccupyDryRun(v->index)) out.flags |= TRPRF_PBS_RES_END_WAIT; if (!slot->OccupyDryRun(v->index)) out.flags |= TRPRF_PBS_RES_END_WAIT;
} }
@ -762,7 +762,7 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp
if (input.permitted_slot_operations & TRPISP_PBS_RES_END_ACQUIRE) { if (input.permitted_slot_operations & TRPISP_PBS_RES_END_ACQUIRE) {
slot->Occupy(v->index); slot->Occupy(v->index);
} else if ((input.permitted_slot_operations & TRPISP_PBS_RES_END_ACQ_DRY) && (this->actions_used_flags & TRPAUF_PBS_RES_END_SIMULATE)) { } else if ((input.permitted_slot_operations & TRPISP_PBS_RES_END_ACQ_DRY) && (this->actions_used_flags & TRPAUF_PBS_RES_END_SIMULATE)) {
slot->OccupyDryRunUsingTemporaryState(v->index); slot->OccupyUsingTemporaryState(v->index, &pbs_res_end_acq_dry_slot_temporary_state);
} }
break; break;
@ -770,7 +770,7 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp
if (input.permitted_slot_operations & TRPISP_PBS_RES_END_RELEASE) { if (input.permitted_slot_operations & TRPISP_PBS_RES_END_RELEASE) {
slot->Vacate(v->index); slot->Vacate(v->index);
} else if ((input.permitted_slot_operations & TRPISP_PBS_RES_END_ACQ_DRY) && (this->actions_used_flags & TRPAUF_PBS_RES_END_SIMULATE)) { } else if ((input.permitted_slot_operations & TRPISP_PBS_RES_END_ACQ_DRY) && (this->actions_used_flags & TRPAUF_PBS_RES_END_SIMULATE)) {
slot->VacateUsingTemporaryState(v->index); slot->VacateUsingTemporaryState(v->index, &pbs_res_end_acq_dry_slot_temporary_state);
} }
break; break;
@ -895,7 +895,7 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp
} }
} }
if ((input.permitted_slot_operations & TRPISP_PBS_RES_END_ACQ_DRY) && (this->actions_used_flags & TRPAUF_PBS_RES_END_SIMULATE)) { if ((input.permitted_slot_operations & TRPISP_PBS_RES_END_ACQ_DRY) && (this->actions_used_flags & TRPAUF_PBS_RES_END_SIMULATE)) {
TraceRestrictSlot::RevertTemporaryChanges(v->index); pbs_res_end_acq_dry_slot_temporary_state.RevertTemporaryChanges(v->index);
} }
assert(condstack.empty()); assert(condstack.empty());
} }
@ -2558,19 +2558,20 @@ bool TraceRestrictSlot::OccupyDryRun(VehicleID id)
} }
/** /**
* Dry-run adding vehicle ID to occupants if possible and not already an occupant, record any changes in the temporary state to be reverted later * Add vehicle ID to occupants if possible and not already an occupant, record any changes in the temporary state to be reverted later
* @param id Vehicle ID * @param id Vehicle ID
* @param state Temporary state
* @return whether vehicle ID is now an occupant * @return whether vehicle ID is now an occupant
*/ */
bool TraceRestrictSlot::OccupyDryRunUsingTemporaryState(VehicleID id) bool TraceRestrictSlot::OccupyUsingTemporaryState(VehicleID id, TraceRestrictSlotTemporaryState *state)
{ {
if (this->IsOccupant(id)) return true; if (this->IsOccupant(id)) return true;
if (this->occupants.size() >= this->max_occupancy) return false; if (this->occupants.size() >= this->max_occupancy) return false;
this->occupants.push_back(id); this->occupants.push_back(id);
if (find_index(veh_temporarily_removed, this->index) < 0) { if (find_index(state->veh_temporarily_removed, this->index) < 0) {
include(veh_temporarily_added, this->index); include(state->veh_temporarily_added, this->index);
} }
return true; return true;
@ -2591,12 +2592,13 @@ void TraceRestrictSlot::Vacate(VehicleID id)
/** /**
* Remove vehicle ID from occupants, record any changes in the temporary state to be reverted later * Remove vehicle ID from occupants, record any changes in the temporary state to be reverted later
* @param id Vehicle ID * @param id Vehicle ID
* @param state Temporary state
*/ */
void TraceRestrictSlot::VacateUsingTemporaryState(VehicleID id) void TraceRestrictSlot::VacateUsingTemporaryState(VehicleID id, TraceRestrictSlotTemporaryState *state)
{ {
if (container_unordered_remove(this->occupants, id)) { if (container_unordered_remove(this->occupants, id)) {
if (find_index(veh_temporarily_added, this->index) < 0) { if (find_index(state->veh_temporarily_added, this->index) < 0) {
include(veh_temporarily_removed, this->index); include(state->veh_temporarily_removed, this->index);
} }
} }
} }
@ -2688,18 +2690,18 @@ void TraceRestrictSlot::PreCleanPool()
} }
/** Revert any temporary changes */ /** Revert any temporary changes */
void TraceRestrictSlot::RevertTemporaryChanges(VehicleID veh) void TraceRestrictSlotTemporaryState::RevertTemporaryChanges(VehicleID veh)
{ {
for (TraceRestrictSlotID id : veh_temporarily_added) { for (TraceRestrictSlotID id : this->veh_temporarily_added) {
TraceRestrictSlot *slot = TraceRestrictSlot::Get(id); TraceRestrictSlot *slot = TraceRestrictSlot::Get(id);
container_unordered_remove(slot->occupants, veh); container_unordered_remove(slot->occupants, veh);
} }
for (TraceRestrictSlotID id : veh_temporarily_removed) { for (TraceRestrictSlotID id : this->veh_temporarily_removed) {
TraceRestrictSlot *slot = TraceRestrictSlot::Get(id); TraceRestrictSlot *slot = TraceRestrictSlot::Get(id);
include(slot->occupants, veh); include(slot->occupants, veh);
} }
veh_temporarily_added.clear(); this->veh_temporarily_added.clear();
veh_temporarily_removed.clear(); this->veh_temporarily_removed.clear();
} }
/** Remove vehicle ID from all slot occupants */ /** Remove vehicle ID from all slot occupants */

@ -500,6 +500,13 @@ enum TraceRestrictProgramInputFlags : uint8_t {
}; };
DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramInputFlags) DECLARE_ENUM_AS_BIT_SET(TraceRestrictProgramInputFlags)
struct TraceRestrictSlotTemporaryState {
std::vector<TraceRestrictSlotID> veh_temporarily_added;
std::vector<TraceRestrictSlotID> veh_temporarily_removed;
void RevertTemporaryChanges(VehicleID veh);
};
/** /**
* Execution input of a TraceRestrictProgram * Execution input of a TraceRestrictProgram
*/ */
@ -1144,14 +1151,10 @@ struct TraceRestrictSlot : TraceRestrictSlotPool::PoolItem<&_tracerestrictslot_p
std::vector<SignalReference> progsig_dependants; std::vector<SignalReference> progsig_dependants;
static std::vector<TraceRestrictSlotID> veh_temporarily_added;
static std::vector<TraceRestrictSlotID> veh_temporarily_removed;
static void RebuildVehicleIndex(); static void RebuildVehicleIndex();
static bool ValidateVehicleIndex(); static bool ValidateVehicleIndex();
static void ValidateSlotOccupants(std::function<void(const char *)> log); static void ValidateSlotOccupants(std::function<void(const char *)> log);
static void PreCleanPool(); static void PreCleanPool();
static void RevertTemporaryChanges(VehicleID veh);
TraceRestrictSlot(CompanyID owner = INVALID_COMPANY, VehicleType type = VEH_TRAIN) TraceRestrictSlot(CompanyID owner = INVALID_COMPANY, VehicleType type = VEH_TRAIN)
{ {
@ -1174,9 +1177,9 @@ struct TraceRestrictSlot : TraceRestrictSlotPool::PoolItem<&_tracerestrictslot_p
bool Occupy(VehicleID id, bool force = false); bool Occupy(VehicleID id, bool force = false);
bool OccupyDryRun(VehicleID ids); bool OccupyDryRun(VehicleID ids);
bool OccupyDryRunUsingTemporaryState(VehicleID id); bool OccupyUsingTemporaryState(VehicleID id, TraceRestrictSlotTemporaryState *state);
void Vacate(VehicleID id); void Vacate(VehicleID id);
void VacateUsingTemporaryState(VehicleID id); void VacateUsingTemporaryState(VehicleID id, TraceRestrictSlotTemporaryState *state);
void Clear(); void Clear();
void UpdateSignals(); void UpdateSignals();

Loading…
Cancel
Save