diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index b8a9583f7d..92e889cf5b 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -3078,9 +3078,9 @@ static std::vector _pco_deferred_slot_releases; static btree::btree_map _pco_deferred_counter_values; static btree::btree_map _pco_deferred_original_percent_cond; -static bool ExecuteVehicleInSlotOrderCondition(VehicleID vehicle, TraceRestrictSlot *slot, ProcessConditionalOrderMode mode, bool acquire) +static bool ExecuteVehicleInSlotOrderCondition(const Vehicle *v, TraceRestrictSlot *slot, ProcessConditionalOrderMode mode, bool acquire) { - bool occupant = slot->IsOccupant(vehicle); + bool occupant = slot->IsOccupant(v->index); if (mode == PCO_DEFERRED) { if (occupant && find_index(_pco_deferred_slot_releases, slot->index) >= 0) { occupant = false; @@ -3090,10 +3090,10 @@ static bool ExecuteVehicleInSlotOrderCondition(VehicleID vehicle, TraceRestrictS } if (acquire) { if (!occupant && mode == PCO_EXEC) { - occupant = slot->Occupy(vehicle); + occupant = slot->Occupy(v); } if (!occupant && mode == PCO_DEFERRED) { - occupant = slot->OccupyDryRun(vehicle); + occupant = slot->OccupyDryRun(v->index); if (occupant) { include(_pco_deferred_slot_acquires, slot->index); container_unordered_remove(_pco_deferred_slot_releases, slot->index); @@ -3180,7 +3180,7 @@ VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v, Pro acquire = true; occ = (occ == OCC_EQUALS) ? OCC_IS_TRUE : OCC_IS_FALSE; } - bool occupant = ExecuteVehicleInSlotOrderCondition(v->index, slot, mode, acquire); + bool occupant = ExecuteVehicleInSlotOrderCondition(v, slot, mode, acquire); skip_order = OrderConditionCompare(occ, occupant, value); } break; @@ -3272,7 +3272,7 @@ VehicleOrderID AdvanceOrderIndexDeferred(const Vehicle *v, VehicleOrderID index) container_unordered_remove(_pco_deferred_slot_acquires, order->GetDestination()); break; case OSST_TRY_ACQUIRE: - ExecuteVehicleInSlotOrderCondition(v->index, TraceRestrictSlot::Get(order->GetDestination()), PCO_DEFERRED, true); + ExecuteVehicleInSlotOrderCondition(v, TraceRestrictSlot::Get(order->GetDestination()), PCO_DEFERRED, true); break; } } @@ -3321,10 +3321,10 @@ void FlushAdvanceOrderIndexDeferred(const Vehicle *v, bool apply) { if (apply) { for (TraceRestrictSlotID slot : _pco_deferred_slot_acquires) { - TraceRestrictSlot::Get(slot)->Occupy(v->index); + TraceRestrictSlot::Get(slot)->Occupy(v); } for (TraceRestrictSlotID slot : _pco_deferred_slot_releases) { - TraceRestrictSlot::Get(slot)->Vacate(v->index); + TraceRestrictSlot::Get(slot)->Vacate(v); } for (auto item : _pco_deferred_counter_values) { TraceRestrictCounter::Get(item.first)->UpdateValue(item.second); @@ -3453,10 +3453,10 @@ bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth, bool if (slot != nullptr) { switch (order->GetSlotSubType()) { case OSST_RELEASE: - slot->Vacate(v->index); + slot->Vacate(v); break; case OSST_TRY_ACQUIRE: - slot->Occupy(v->index); + slot->Occupy(v); break; } } diff --git a/src/pathfinder/yapf/yapf_rail.cpp b/src/pathfinder/yapf/yapf_rail.cpp index 20020a6f35..08153ced59 100644 --- a/src/pathfinder/yapf/yapf_rail.cpp +++ b/src/pathfinder/yapf/yapf_rail.cpp @@ -266,7 +266,7 @@ public: } /* This must be done before calling TraceRestrictExecuteResEndSlot */ - temporary_slot_state.ApplyTemporaryChanges(Yapf().GetVehicle()->index); + temporary_slot_state.ApplyTemporaryChanges(Yapf().GetVehicle()); restricted_signal_state.TraceRestrictExecuteResEndSlot(Yapf().GetVehicle()); diff --git a/src/tracerestrict.cpp b/src/tracerestrict.cpp index 2b8e05100f..4e4302ac83 100644 --- a/src/tracerestrict.cpp +++ b/src/tracerestrict.cpp @@ -730,7 +730,7 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp switch (static_cast(GetTraceRestrictCombinedAuxCondOpField(item))) { case TRSCOF_ACQUIRE_WAIT: if (input.permitted_slot_operations & TRPISP_ACQUIRE) { - if (!slot->Occupy(v->index)) out.flags |= TRPRF_WAIT_AT_PBS; + if (!slot->Occupy(v)) out.flags |= TRPRF_WAIT_AT_PBS; } else if (input.permitted_slot_operations & TRPISP_ACQUIRE_TEMP_STATE) { if (!slot->OccupyUsingTemporaryState(v->index, input.slot_temporary_state)) out.flags |= TRPRF_WAIT_AT_PBS; } @@ -738,7 +738,7 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp case TRSCOF_ACQUIRE_TRY: if (input.permitted_slot_operations & TRPISP_ACQUIRE) { - slot->Occupy(v->index); + slot->Occupy(v); } else if (input.permitted_slot_operations & TRPISP_ACQUIRE_TEMP_STATE) { slot->OccupyUsingTemporaryState(v->index, input.slot_temporary_state); } @@ -746,23 +746,23 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp case TRSCOF_RELEASE_ON_RESERVE: if (input.permitted_slot_operations & TRPISP_ACQUIRE) { - slot->Vacate(v->index); + slot->Vacate(v); } else if (input.permitted_slot_operations & TRPISP_ACQUIRE_TEMP_STATE) { slot->VacateUsingTemporaryState(v->index, input.slot_temporary_state); } break; case TRSCOF_RELEASE_BACK: - if (input.permitted_slot_operations & TRPISP_RELEASE_BACK) slot->Vacate(v->index); + if (input.permitted_slot_operations & TRPISP_RELEASE_BACK) slot->Vacate(v); break; case TRSCOF_RELEASE_FRONT: - if (input.permitted_slot_operations & TRPISP_RELEASE_FRONT) slot->Vacate(v->index); + if (input.permitted_slot_operations & TRPISP_RELEASE_FRONT) slot->Vacate(v); break; case TRSCOF_PBS_RES_END_ACQ_WAIT: if (input.permitted_slot_operations & TRPISP_PBS_RES_END_ACQUIRE) { - if (!slot->Occupy(v->index)) out.flags |= TRPRF_PBS_RES_END_WAIT; + if (!slot->Occupy(v)) out.flags |= TRPRF_PBS_RES_END_WAIT; } else if (input.permitted_slot_operations & TRPISP_PBS_RES_END_ACQ_DRY) { if (this->actions_used_flags & TRPAUF_PBS_RES_END_SIMULATE) { if (!slot->OccupyUsingTemporaryState(v->index, &pbs_res_end_acq_dry_slot_temporary_state)) out.flags |= TRPRF_PBS_RES_END_WAIT; @@ -774,7 +774,7 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp case TRSCOF_PBS_RES_END_ACQ_TRY: if (input.permitted_slot_operations & TRPISP_PBS_RES_END_ACQUIRE) { - slot->Occupy(v->index); + slot->Occupy(v); } else if ((input.permitted_slot_operations & TRPISP_PBS_RES_END_ACQ_DRY) && (this->actions_used_flags & TRPAUF_PBS_RES_END_SIMULATE)) { slot->OccupyUsingTemporaryState(v->index, &pbs_res_end_acq_dry_slot_temporary_state); } @@ -782,7 +782,7 @@ void TraceRestrictProgram::Execute(const Train* v, const TraceRestrictProgramInp case TRSCOF_PBS_RES_END_RELEASE: if (input.permitted_slot_operations & TRPISP_PBS_RES_END_ACQUIRE) { - slot->Vacate(v->index); + slot->Vacate(v); } 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, &pbs_res_end_acq_dry_slot_temporary_state); } @@ -2538,17 +2538,17 @@ void TraceRestrictUpdateCompanyID(CompanyID old_company, CompanyID new_company) static btree::btree_multimap slot_vehicle_index; /** - * Add vehicle ID to occupants if possible and not already an occupant - * @param id Vehicle ID + * Add vehicle to occupants if possible and not already an occupant + * @param v Vehicle * @param force Add the vehicle even if the slot is at/over capacity - * @return whether vehicle ID is now an occupant + * @return whether vehicle is now an occupant */ -bool TraceRestrictSlot::Occupy(VehicleID id, bool force) +bool TraceRestrictSlot::Occupy(const Vehicle *v, bool force) { - if (this->IsOccupant(id)) return true; + if (this->IsOccupant(v->index)) return true; if (this->occupants.size() >= this->max_occupancy && !force) return false; - this->occupants.push_back(id); - this->AddIndex(id); + this->occupants.push_back(v->index); + this->AddIndex(v); this->UpdateSignals(); return true; } @@ -2586,13 +2586,13 @@ bool TraceRestrictSlot::OccupyUsingTemporaryState(VehicleID id, TraceRestrictSlo } /** - * Remove vehicle ID from occupants - * @param id Vehicle ID + * Remove vehicle from occupants + * @param v Vehicle */ -void TraceRestrictSlot::Vacate(VehicleID id) +void TraceRestrictSlot::Vacate(const Vehicle *v) { - if (container_unordered_remove(this->occupants, id)) { - this->DeIndex(id); + if (container_unordered_remove(this->occupants, v->index)) { + this->DeIndex(v->index, v); this->UpdateSignals(); } } @@ -2615,7 +2615,7 @@ void TraceRestrictSlot::VacateUsingTemporaryState(VehicleID id, TraceRestrictSlo void TraceRestrictSlot::Clear() { for (VehicleID id : this->occupants) { - this->DeIndex(id); + this->DeIndex(id, nullptr); } this->occupants.clear(); } @@ -2627,16 +2627,25 @@ void TraceRestrictSlot::UpdateSignals() { } } -void TraceRestrictSlot::AddIndex(VehicleID id) +/** + * Add vehicle to vehicle slot index + * @param v Vehicle pointer + */ +void TraceRestrictSlot::AddIndex(const Vehicle *v) { - slot_vehicle_index.insert({ id, this->index }); - SetBit(Vehicle::Get(id)->vehicle_flags, VF_HAVE_SLOT); - SetWindowDirty(WC_VEHICLE_DETAILS, id); + slot_vehicle_index.insert({ v->index, this->index }); + SetBit(const_cast(v)->vehicle_flags, VF_HAVE_SLOT); + SetWindowDirty(WC_VEHICLE_DETAILS, v->index); InvalidateWindowClassesData(WC_TRACE_RESTRICT_SLOTS); } -void TraceRestrictSlot::DeIndex(VehicleID id) +/** + * Remove vehicle from vehicle slot index + * @param id Vehicle ID + * @param v Vehicle pointer (optional) or nullptr + */ +void TraceRestrictSlot::DeIndex(VehicleID id, const Vehicle *v) { auto start = slot_vehicle_index.lower_bound(id); for (auto it = start; it != slot_vehicle_index.end() && it->first == id; ++it) { @@ -2647,7 +2656,8 @@ void TraceRestrictSlot::DeIndex(VehicleID id) if (is_first_in_range && (next == slot_vehicle_index.end() || next->first != id)) { /* Only one item, which we've just erased, clear the vehicle flag */ - ClrBit(Vehicle::Get(id)->vehicle_flags, VF_HAVE_SLOT); + if (v == nullptr) v = Vehicle::Get(id); + ClrBit(const_cast(v)->vehicle_flags, VF_HAVE_SLOT); } break; } @@ -2722,19 +2732,20 @@ void TraceRestrictSlotTemporaryState::RevertTemporaryChanges(VehicleID veh) } /** Apply any temporary changes */ -void TraceRestrictSlotTemporaryState::ApplyTemporaryChanges(VehicleID veh) +void TraceRestrictSlotTemporaryState::ApplyTemporaryChanges(const Vehicle *v) { + VehicleID veh = v->index; for (TraceRestrictSlotID id : this->veh_temporarily_added) { TraceRestrictSlot *slot = TraceRestrictSlot::Get(id); if (slot->IsOccupant(veh)) { - slot->AddIndex(veh); + slot->AddIndex(v); slot->UpdateSignals(); } } for (TraceRestrictSlotID id : this->veh_temporarily_removed) { TraceRestrictSlot *slot = TraceRestrictSlot::Get(id); if (!slot->IsOccupant(veh)) { - slot->DeIndex(veh); + slot->DeIndex(v->index, v); slot->UpdateSignals(); } } @@ -2982,7 +2993,7 @@ CommandCost CmdAddVehicleTraceRestrictSlot(TileIndex tile, DoCommandFlag flags, if (v->type != slot->vehicle_type || !v->IsPrimaryVehicle()) return CMD_ERROR; if (flags & DC_EXEC) { - slot->Occupy(v->index, true); + slot->Occupy(v, true); } return CommandCost(); @@ -3007,7 +3018,7 @@ CommandCost CmdRemoveVehicleTraceRestrictSlot(TileIndex tile, DoCommandFlag flag if (v == nullptr) return CMD_ERROR; // permit removing vehicles of other owners from your own slot if (flags & DC_EXEC) { - slot->Vacate(v->index); + slot->Vacate(v); } return CommandCost(); diff --git a/src/tracerestrict.h b/src/tracerestrict.h index a080e0ed38..4affb180f0 100644 --- a/src/tracerestrict.h +++ b/src/tracerestrict.h @@ -506,7 +506,7 @@ struct TraceRestrictSlotTemporaryState { std::vector veh_temporarily_removed; void RevertTemporaryChanges(VehicleID veh); - void ApplyTemporaryChanges(VehicleID veh); + void ApplyTemporaryChanges(const Vehicle *v); bool IsEmpty() const { @@ -1185,17 +1185,17 @@ struct TraceRestrictSlot : TraceRestrictSlotPool::PoolItem<&_tracerestrictslot_p return false; } - bool Occupy(VehicleID id, bool force = false); + bool Occupy(const Vehicle *v, bool force = false); bool OccupyDryRun(VehicleID ids); bool OccupyUsingTemporaryState(VehicleID id, TraceRestrictSlotTemporaryState *state); - void Vacate(VehicleID id); + void Vacate(const Vehicle *v); void VacateUsingTemporaryState(VehicleID id, TraceRestrictSlotTemporaryState *state); void Clear(); void UpdateSignals(); private: - void AddIndex(VehicleID id); - void DeIndex(VehicleID id); + void AddIndex(const Vehicle *v); + void DeIndex(VehicleID id, const Vehicle *v); }; /**