De-duplicate cargo masking boilerplate using C++11.
This commit is contained in:
@@ -38,22 +38,14 @@
|
|||||||
for (const Order *o = v->orders.list->GetFirstOrder(); o != NULL; o = o->next) {
|
for (const Order *o = v->orders.list->GetFirstOrder(); o != NULL; o = o->next) {
|
||||||
if (o->IsType(OT_GOTO_STATION) || o->IsType(OT_IMPLICIT)) {
|
if (o->IsType(OT_GOTO_STATION) || o->IsType(OT_IMPLICIT)) {
|
||||||
if (o->GetUnloadType() == OUFB_CARGO_TYPE_UNLOAD) {
|
if (o->GetUnloadType() == OUFB_CARGO_TYPE_UNLOAD) {
|
||||||
OrderUnloadFlags ouf = o->GetCargoUnloadType(first_cargo_id);
|
CargoMaskValueFilter<uint>(cargo_mask, [&](CargoID cargo) -> uint {
|
||||||
uint32 other_cargo_mask = cargo_mask;
|
return o->GetCargoUnloadType(cargo) & (OUFB_TRANSFER | OUFB_UNLOAD | OUFB_NO_UNLOAD);
|
||||||
ClrBit(other_cargo_mask, first_cargo_id);
|
});
|
||||||
CargoID cargo;
|
|
||||||
FOR_EACH_SET_BIT(cargo, other_cargo_mask) {
|
|
||||||
if (((ouf ^ o->GetCargoUnloadType(cargo)) & (OUFB_TRANSFER | OUFB_UNLOAD | OUFB_NO_UNLOAD)) != 0) ClrBit(cargo_mask, cargo);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (o->GetLoadType() == OLFB_CARGO_TYPE_LOAD) {
|
if (o->GetLoadType() == OLFB_CARGO_TYPE_LOAD) {
|
||||||
OrderLoadFlags olf = o->GetCargoLoadType(first_cargo_id);
|
CargoMaskValueFilter<uint>(cargo_mask, [&](CargoID cargo) -> uint {
|
||||||
uint32 other_cargo_mask = cargo_mask;
|
return o->GetCargoLoadType(cargo) & (OLFB_NO_LOAD);
|
||||||
ClrBit(other_cargo_mask, first_cargo_id);
|
});
|
||||||
CargoID cargo;
|
|
||||||
FOR_EACH_SET_BIT(cargo, other_cargo_mask) {
|
|
||||||
if (((olf ^ o->GetCargoLoadType(cargo)) & (OLFB_NO_LOAD)) != 0) ClrBit(cargo_mask, cargo);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -388,6 +388,19 @@ public:
|
|||||||
void FillNextStoppingStation(const Vehicle *v, const OrderList *o, const Order *first = NULL, uint hops = 0);
|
void FillNextStoppingStation(const Vehicle *v, const OrderList *o, const Order *first = NULL, uint hops = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T, typename F> T CargoMaskValueFilter(uint32 &cargo_mask, F filter_func)
|
||||||
|
{
|
||||||
|
CargoID first_cargo_id = FindFirstBit(cargo_mask);
|
||||||
|
T value = filter_func(first_cargo_id);
|
||||||
|
uint32 other_cargo_mask = cargo_mask;
|
||||||
|
ClrBit(other_cargo_mask, first_cargo_id);
|
||||||
|
CargoID cargo;
|
||||||
|
FOR_EACH_SET_BIT(cargo, other_cargo_mask) {
|
||||||
|
if (value != filter_func(cargo)) ClrBit(cargo_mask, cargo);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shared order list linking together the linked list of orders and the list
|
* Shared order list linking together the linked list of orders and the list
|
||||||
* of vehicles sharing this order list.
|
* of vehicles sharing this order list.
|
||||||
|
@@ -439,16 +439,9 @@ const Order *OrderList::GetNextDecisionNode(const Order *next, uint hops, uint32
|
|||||||
/* This is a cargo-specific load/unload order.
|
/* This is a cargo-specific load/unload order.
|
||||||
* If the first cargo is both a no-load and no-unload order, skip it.
|
* If the first cargo is both a no-load and no-unload order, skip it.
|
||||||
* Drop cargoes which don't match the first one. */
|
* Drop cargoes which don't match the first one. */
|
||||||
CargoID first_cargo_id = FindFirstBit(cargo_mask);
|
can_load_or_unload = CargoMaskValueFilter<bool>(cargo_mask, [&](CargoID cargo) {
|
||||||
can_load_or_unload = ((next->GetCargoLoadType(first_cargo_id) & OLFB_NO_LOAD) == 0 || (next->GetCargoUnloadType(first_cargo_id) & OUFB_NO_UNLOAD) == 0);
|
return ((next->GetCargoLoadType(cargo) & OLFB_NO_LOAD) == 0 || (next->GetCargoUnloadType(cargo) & OUFB_NO_UNLOAD) == 0);
|
||||||
uint32 other_cargo_mask = cargo_mask;
|
});
|
||||||
ClrBit(other_cargo_mask, first_cargo_id);
|
|
||||||
CargoID cargo;
|
|
||||||
FOR_EACH_SET_BIT(cargo, other_cargo_mask) {
|
|
||||||
if (can_load_or_unload != ((next->GetCargoLoadType(cargo) & OLFB_NO_LOAD) == 0 || (next->GetCargoUnloadType(cargo) & OUFB_NO_UNLOAD) == 0)) {
|
|
||||||
ClrBit(cargo_mask, cargo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if ((next->GetLoadType() & OLFB_NO_LOAD) == 0 || (next->GetUnloadType() & OUFB_NO_UNLOAD) == 0) {
|
} else if ((next->GetLoadType() & OLFB_NO_LOAD) == 0 || (next->GetUnloadType() & OUFB_NO_UNLOAD) == 0) {
|
||||||
can_load_or_unload = true;
|
can_load_or_unload = true;
|
||||||
}
|
}
|
||||||
@@ -520,21 +513,12 @@ CargoMaskedStationIDStack OrderList::GetNextStoppingStation(const Vehicle *v, ui
|
|||||||
/* Don't return a next stop if the vehicle has to unload everything. */
|
/* Don't return a next stop if the vehicle has to unload everything. */
|
||||||
if ((next->IsType(OT_GOTO_STATION) || next->IsType(OT_IMPLICIT)) &&
|
if ((next->IsType(OT_GOTO_STATION) || next->IsType(OT_IMPLICIT)) &&
|
||||||
next->GetDestination() == v->last_station_visited) {
|
next->GetDestination() == v->last_station_visited) {
|
||||||
CargoID first_cargo_id = FindFirstBit(cargo_mask);
|
/* This is a cargo-specific load/unload order.
|
||||||
bool invalid = ((next->GetCargoUnloadType(first_cargo_id) & (OUFB_TRANSFER | OUFB_UNLOAD)) != 0);
|
* Don't return a next stop if first cargo has transfer or unload set.
|
||||||
if (next->GetUnloadType() == OUFB_CARGO_TYPE_UNLOAD) {
|
* Drop cargoes which don't match the first one. */
|
||||||
/* This is a cargo-specific load/unload order.
|
bool invalid = CargoMaskValueFilter<bool>(cargo_mask, [&](CargoID cargo) {
|
||||||
* Don't return a next stop if first cargo has transfer or unload set.
|
return ((next->GetCargoUnloadType(cargo) & (OUFB_TRANSFER | OUFB_UNLOAD)) != 0);
|
||||||
* Drop cargoes which don't match the first one. */
|
});
|
||||||
uint32 other_cargo_mask = cargo_mask;
|
|
||||||
ClrBit(other_cargo_mask, first_cargo_id);
|
|
||||||
CargoID cargo;
|
|
||||||
FOR_EACH_SET_BIT(cargo, other_cargo_mask) {
|
|
||||||
if (invalid != ((next->GetCargoUnloadType(cargo) & (OUFB_TRANSFER | OUFB_UNLOAD)) != 0)) {
|
|
||||||
ClrBit(cargo_mask, cargo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (invalid) return CargoMaskedStationIDStack(cargo_mask, INVALID_STATION);
|
if (invalid) return CargoMaskedStationIDStack(cargo_mask, INVALID_STATION);
|
||||||
}
|
}
|
||||||
} while (next->IsType(OT_GOTO_DEPOT) || next->GetDestination() == v->last_station_visited);
|
} while (next->IsType(OT_GOTO_DEPOT) || next->GetDestination() == v->last_station_visited);
|
||||||
|
Reference in New Issue
Block a user