Codechange: Move ownership of Orders to OrderList. (#13948)

Removes the orders pool, and orders are now stored directly in each OrderList.

Iterating orders now no longer needs to traverse a linked-list, all orders in an OrderList are sequential.
This commit is contained in:
Peter Nelson
2025-05-23 10:36:28 +01:00
committed by GitHub
parent 7344dfe651
commit 0455627d16
30 changed files with 602 additions and 652 deletions

View File

@@ -2144,24 +2144,23 @@ void Vehicle::DeleteUnreachedImplicitOrders()
}
}
const Order *order = this->GetOrder(this->cur_implicit_order_index);
while (order != nullptr) {
auto orders = this->Orders();
VehicleOrderID cur = this->cur_implicit_order_index;
while (cur != INVALID_VEH_ORDER_ID) {
if (this->cur_implicit_order_index == this->cur_real_order_index) break;
if (order->IsType(OT_IMPLICIT)) {
if (orders[cur].IsType(OT_IMPLICIT)) {
DeleteOrder(this, this->cur_implicit_order_index);
/* DeleteOrder does various magic with order_indices, so resync 'order' with 'cur_implicit_order_index' */
order = this->GetOrder(this->cur_implicit_order_index);
} else {
/* Skip non-implicit orders, e.g. service-orders */
order = order->next;
this->cur_implicit_order_index++;
}
/* Wrap around */
if (order == nullptr) {
order = this->GetOrder(0);
this->cur_implicit_order_index = 0;
if (cur < this->orders->GetNext(cur)) {
this->cur_implicit_order_index++;
} else {
/* Wrapped around. */
this->cur_implicit_order_index = 0;
}
cur = this->orders->GetNext(cur);
}
}
}
@@ -2201,7 +2200,7 @@ void Vehicle::BeginLoading()
in_list->GetDestination() != this->last_station_visited)) {
bool suppress_implicit_orders = HasBit(this->GetGroundVehicleFlags(), GVF_SUPPRESS_IMPLICIT_ORDERS);
/* Do not create consecutive duplicates of implicit orders */
Order *prev_order = this->cur_implicit_order_index > 0 ? this->GetOrder(this->cur_implicit_order_index - 1) : (this->GetNumOrders() > 1 ? this->GetLastOrder() : nullptr);
const Order *prev_order = this->cur_implicit_order_index > 0 ? this->GetOrder(this->cur_implicit_order_index - 1) : (this->GetNumOrders() > 1 ? this->GetLastOrder() : nullptr);
if (prev_order == nullptr ||
(!prev_order->IsType(OT_IMPLICIT) && !prev_order->IsType(OT_GOTO_STATION)) ||
prev_order->GetDestination() != this->last_station_visited) {
@@ -2238,33 +2237,30 @@ void Vehicle::BeginLoading()
InvalidateVehicleOrder(this, 0);
} else {
/* Delete all implicit orders up to the station we just reached */
const Order *order = this->GetOrder(this->cur_implicit_order_index);
while (!order->IsType(OT_IMPLICIT) || order->GetDestination() != this->last_station_visited) {
if (order->IsType(OT_IMPLICIT)) {
VehicleOrderID cur = this->cur_implicit_order_index;
auto orders = this->Orders();
while (!orders[cur].IsType(OT_IMPLICIT) || orders[cur].GetDestination() != this->last_station_visited) {
if (orders[cur].IsType(OT_IMPLICIT)) {
DeleteOrder(this, this->cur_implicit_order_index);
/* DeleteOrder does various magic with order_indices, so resync 'order' with 'cur_implicit_order_index' */
order = this->GetOrder(this->cur_implicit_order_index);
} else {
/* Skip non-implicit orders, e.g. service-orders */
order = order->next;
this->cur_implicit_order_index++;
if (cur < this->orders->GetNext(cur)) {
this->cur_implicit_order_index++;
} else {
/* Wrapped around. */
this->cur_implicit_order_index = 0;
}
cur = this->orders->GetNext(cur);
}
/* Wrap around */
if (order == nullptr) {
order = this->GetOrder(0);
this->cur_implicit_order_index = 0;
}
assert(order != nullptr);
}
}
} else if (!suppress_implicit_orders &&
((this->orders == nullptr ? OrderList::CanAllocateItem() : this->orders->GetNumOrders() < MAX_VEH_ORDER_ID)) &&
Order::CanAllocateItem()) {
(this->orders == nullptr ? OrderList::CanAllocateItem() : this->orders->GetNumOrders() < MAX_VEH_ORDER_ID)) {
/* Insert new implicit order */
Order *implicit_order = new Order();
implicit_order->MakeImplicit(this->last_station_visited);
InsertOrder(this, implicit_order, this->cur_implicit_order_index);
Order implicit_order{};
implicit_order.MakeImplicit(this->last_station_visited);
InsertOrder(this, std::move(implicit_order), this->cur_implicit_order_index);
if (this->cur_implicit_order_index > 0) --this->cur_implicit_order_index;
/* InsertOrder disabled creation of implicit orders for all vehicles with the same implicit order.
@@ -2434,10 +2430,9 @@ void Vehicle::HandleLoading(bool mode)
*/
bool Vehicle::HasFullLoadOrder() const
{
for (Order *o : this->Orders()) {
if (o->IsType(OT_GOTO_STATION) && o->GetLoadType() & (OLFB_FULL_LOAD | OLF_FULL_LOAD_ANY)) return true;
}
return false;
return std::ranges::any_of(this->Orders(), [](const Order &o) {
return o.IsType(OT_GOTO_STATION) && o.GetLoadType() & (OLFB_FULL_LOAD | OLF_FULL_LOAD_ANY);
});
}
/**
@@ -2446,10 +2441,7 @@ bool Vehicle::HasFullLoadOrder() const
*/
bool Vehicle::HasConditionalOrder() const
{
for (Order *o : this->Orders()) {
if (o->IsType(OT_CONDITIONAL)) return true;
}
return false;
return std::ranges::any_of(this->Orders(), [](const Order &o) { return o.IsType(OT_CONDITIONAL); });
}
/**
@@ -2458,10 +2450,9 @@ bool Vehicle::HasConditionalOrder() const
*/
bool Vehicle::HasUnbunchingOrder() const
{
for (Order *o : this->Orders()) {
if (o->IsType(OT_GOTO_DEPOT) && o->GetDepotActionType() & ODATFB_UNBUNCH) return true;
}
return false;
return std::ranges::any_of(this->Orders(), [](const Order &o) {
return o.IsType(OT_GOTO_DEPOT) && (o.GetDepotActionType() & ODATFB_UNBUNCH);
});
}
/**
@@ -2472,7 +2463,7 @@ static bool PreviousOrderIsUnbunching(const Vehicle *v)
{
/* If we are headed for the first order, we must wrap around back to the last order. */
bool is_first_order = (v->GetOrder(v->cur_implicit_order_index) == v->GetFirstOrder());
Order *previous_order = (is_first_order) ? v->GetLastOrder() : v->GetOrder(v->cur_implicit_order_index - 1);
const Order *previous_order = (is_first_order) ? v->GetLastOrder() : v->GetOrder(v->cur_implicit_order_index - 1);
if (previous_order == nullptr || !previous_order->IsType(OT_GOTO_DEPOT)) return false;
return (previous_order->GetDepotActionType() & ODATFB_UNBUNCH) != 0;
@@ -2942,7 +2933,7 @@ void Vehicle::AddToShared(Vehicle *shared_chain)
if (shared_chain->orders == nullptr) {
assert(shared_chain->previous_shared == nullptr);
assert(shared_chain->next_shared == nullptr);
this->orders = shared_chain->orders = new OrderList(nullptr, shared_chain);
this->orders = shared_chain->orders = new OrderList(shared_chain);
}
this->next_shared = shared_chain->next_shared;
@@ -3258,13 +3249,5 @@ bool VehiclesHaveSameEngineList(const Vehicle *v1, const Vehicle *v2)
*/
bool VehiclesHaveSameOrderList(const Vehicle *v1, const Vehicle *v2)
{
const Order *o1 = v1->GetFirstOrder();
const Order *o2 = v2->GetFirstOrder();
while (true) {
if (o1 == nullptr && o2 == nullptr) return true;
if (o1 == nullptr || o2 == nullptr) return false;
if (!o1->Equals(*o2)) return false;
o1 = o1->next;
o2 = o2->next;
}
return std::ranges::equal(v1->Orders(), v2->Orders(), [](const Order &o1, const Order &o2) { return o1.Equals(o2); });
}