1
0
Fork 0

Codechange: Iterate group vehicle lists for RemoveOrderFromAllVehicles

Additionally make the function receive one parameter more with the owner of the destination, to help it perform faster.
pull/10548/head
SamuXarick 2023-12-31 22:47:02 +00:00
parent 17c6259f5c
commit 444a90dda8
6 changed files with 54 additions and 45 deletions

View File

@ -2163,5 +2163,5 @@ void UpdateAirplanesOnNewStation(const Station *st)
} }
/* Heliports don't have a hangar. Invalidate all go to hangar orders from all aircraft. */ /* Heliports don't have a hangar. Invalidate all go to hangar orders from all aircraft. */
if (!st->airport.HasHangar()) RemoveOrderFromAllVehicles(OT_GOTO_DEPOT, st->index, true); if (!st->airport.HasHangar()) RemoveOrderFromAllVehicles(OT_GOTO_DEPOT, st->index, st->owner, true);
} }

View File

@ -38,7 +38,7 @@ Depot::~Depot()
OrderBackup::Reset(this->xy, false); OrderBackup::Reset(this->xy, false);
/* Clear the depot from all order-lists */ /* Clear the depot from all order-lists */
RemoveOrderFromAllVehicles(OT_GOTO_DEPOT, this->index); RemoveOrderFromAllVehicles(OT_GOTO_DEPOT, this->index, GetTileOwner(this->xy));
/* Delete the depot-window */ /* Delete the depot-window */
CloseWindowById(WC_VEHICLE_DEPOT, this->xy); CloseWindowById(WC_VEHICLE_DEPOT, this->xy);

View File

@ -1735,62 +1735,71 @@ void CheckOrders(const Vehicle *v)
* Removes an order from all vehicles. Triggers when, say, a station is removed. * Removes an order from all vehicles. Triggers when, say, a station is removed.
* @param type The type of the order (OT_GOTO_[STATION|DEPOT|WAYPOINT]). * @param type The type of the order (OT_GOTO_[STATION|DEPOT|WAYPOINT]).
* @param destination The destination. Can be a StationID, DepotID or WaypointID. * @param destination The destination. Can be a StationID, DepotID or WaypointID.
* @param owner The owner of the destination object.
* @param hangar Only used for airports in the destination. * @param hangar Only used for airports in the destination.
* When false, remove airport and hangar orders. * When false, remove airport and hangar orders.
* When true, remove either airport or hangar order. * When true, remove either airport or hangar order.
*/ */
void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination, bool hangar) void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination, Owner owner, bool hangar)
{ {
/* Aircraft have StationIDs for depot orders and never use DepotIDs /* Aircraft have StationIDs for depot orders and never use DepotIDs
* This fact is handled specially below * This fact is handled specially below
*/ */
/* Go through all vehicles */ /* Go through all vehicles */
for (Vehicle *v : Vehicle::Iterate()) { for (const Company *c : Company::Iterate()) {
if ((v->type == VEH_AIRCRAFT && v->current_order.IsType(OT_GOTO_DEPOT) && !hangar ? OT_GOTO_STATION : v->current_order.GetType()) == type && /* Only iterate over all companies in the case of neutral owners */
(!hangar || v->type == VEH_AIRCRAFT) && v->current_order.GetDestination() == destination) { if (owner != c->index && owner != OWNER_NONE) continue;
v->current_order.MakeDummy(); for (VehicleType vtype = VEH_BEGIN; vtype < VEH_COMPANY_END; vtype++) {
SetWindowDirty(WC_VEHICLE_VIEW, v->index); const VehicleList &vehicle_list = c->group_all[vtype].vehicle_list;
} for (const Vehicle *u : vehicle_list) {
Vehicle *v = Vehicle::Get(u->index);
if ((v->type == VEH_AIRCRAFT && v->current_order.IsType(OT_GOTO_DEPOT) && !hangar ? OT_GOTO_STATION : v->current_order.GetType()) == type &&
(!hangar || v->type == VEH_AIRCRAFT) && v->current_order.GetDestination() == destination) {
v->current_order.MakeDummy();
SetWindowDirty(WC_VEHICLE_VIEW, v->index);
}
/* Clear the order from the order-list */ /* Clear the order from the order-list */
int id = -1; int id = -1;
for (Order *order : v->Orders()) { for (Order *order : v->Orders()) {
id++; id++;
restart: restart:
OrderType ot = order->GetType(); OrderType ot = order->GetType();
if (ot == OT_GOTO_DEPOT && (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0) continue; if (ot == OT_GOTO_DEPOT && (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0) continue;
if (ot == OT_GOTO_DEPOT && hangar && v->type != VEH_AIRCRAFT) continue; // Not an aircraft? Can't have a hangar order. if (ot == OT_GOTO_DEPOT && hangar && v->type != VEH_AIRCRAFT) continue; // Not an aircraft? Can't have a hangar order.
if (ot == OT_IMPLICIT || (v->type == VEH_AIRCRAFT && ot == OT_GOTO_DEPOT && !hangar)) ot = OT_GOTO_STATION; if (ot == OT_IMPLICIT || (v->type == VEH_AIRCRAFT && ot == OT_GOTO_DEPOT && !hangar)) ot = OT_GOTO_STATION;
if (ot == type && order->GetDestination() == destination) { if (ot == type && order->GetDestination() == destination) {
/* We want to clear implicit orders, but we don't want to make them /* We want to clear implicit orders, but we don't want to make them
* dummy orders. They should just vanish. Also check the actual order * dummy orders. They should just vanish. Also check the actual order
* type as ot is currently OT_GOTO_STATION. */ * type as ot is currently OT_GOTO_STATION. */
if (order->IsType(OT_IMPLICIT)) { if (order->IsType(OT_IMPLICIT)) {
order = order->next; // DeleteOrder() invalidates current order order = order->next; // DeleteOrder() invalidates current order
DeleteOrder(v, id); DeleteOrder(v, id);
if (order != nullptr) goto restart; if (order != nullptr) goto restart;
break; break;
} }
/* Clear wait time */ /* Clear wait time */
v->orders->UpdateTotalDuration(-order->GetWaitTime()); v->orders->UpdateTotalDuration(-order->GetWaitTime());
if (order->IsWaitTimetabled()) { if (order->IsWaitTimetabled()) {
v->orders->UpdateTimetableDuration(-order->GetTimetabledWait()); v->orders->UpdateTimetableDuration(-order->GetTimetabledWait());
order->SetWaitTimetabled(false); order->SetWaitTimetabled(false);
} }
order->SetWaitTime(0); order->SetWaitTime(0);
/* Clear order, preserving travel time */ /* Clear order, preserving travel time */
bool travel_timetabled = order->IsTravelTimetabled(); bool travel_timetabled = order->IsTravelTimetabled();
order->MakeDummy(); order->MakeDummy();
order->SetTravelTimetabled(travel_timetabled); order->SetTravelTimetabled(travel_timetabled);
for (const Vehicle *w = v->FirstShared(); w != nullptr; w = w->NextShared()) { for (const Vehicle *w = v->FirstShared(); w != nullptr; w = w->NextShared()) {
/* In GUI, simulate by removing the order and adding it back */ /* In GUI, simulate by removing the order and adding it back */
InvalidateVehicleOrder(w, id | (INVALID_VEH_ORDER_ID << 8)); InvalidateVehicleOrder(w, id | (INVALID_VEH_ORDER_ID << 8));
InvalidateVehicleOrder(w, (INVALID_VEH_ORDER_ID << 8) | id); InvalidateVehicleOrder(w, (INVALID_VEH_ORDER_ID << 8) | id);
}
}
} }
} }
} }

View File

@ -15,7 +15,7 @@
#include "company_type.h" #include "company_type.h"
/* Functions */ /* Functions */
void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination, bool hangar = false); void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination, Owner owner, bool hangar = false);
void InvalidateVehicleOrder(const Vehicle *v, int data); void InvalidateVehicleOrder(const Vehicle *v, int data);
void CheckOrders(const Vehicle*); void CheckOrders(const Vehicle*);
void DeleteVehicleOrders(Vehicle *v, bool keep_orderlist = false, bool reset_order_indices = true); void DeleteVehicleOrders(Vehicle *v, bool keep_orderlist = false, bool reset_order_indices = true);

View File

@ -143,7 +143,7 @@ Station::~Station()
CloseWindowById(WC_STATION_VIEW, index); CloseWindowById(WC_STATION_VIEW, index);
/* Now delete all orders that go to the station */ /* Now delete all orders that go to the station */
RemoveOrderFromAllVehicles(OT_GOTO_STATION, this->index); RemoveOrderFromAllVehicles(OT_GOTO_STATION, this->index, this->owner);
/* Remove all news items */ /* Remove all news items */
DeleteStationNews(this->index); DeleteStationNews(this->index);

View File

@ -52,6 +52,6 @@ Waypoint::~Waypoint()
{ {
if (CleaningPool()) return; if (CleaningPool()) return;
CloseWindowById(WC_WAYPOINT_VIEW, this->index); CloseWindowById(WC_WAYPOINT_VIEW, this->index);
RemoveOrderFromAllVehicles(OT_GOTO_WAYPOINT, this->index); RemoveOrderFromAllVehicles(OT_GOTO_WAYPOINT, this->index, this->owner);
if (this->sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeWaypoint(this->index)); if (this->sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeWaypoint(this->index));
} }