Maintain map of vehicle order destinations refcounts, by type
This commit is contained in:
@@ -314,6 +314,8 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner)
|
|||||||
assert(old_owner != _local_company);
|
assert(old_owner != _local_company);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ClearOrderDestinationRefcountMap();
|
||||||
|
|
||||||
Town *t;
|
Town *t;
|
||||||
|
|
||||||
assert(old_owner != new_owner);
|
assert(old_owner != new_owner);
|
||||||
@@ -589,6 +591,8 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner)
|
|||||||
/* Change owner of deferred cargo payments */
|
/* Change owner of deferred cargo payments */
|
||||||
ChangeOwnershipOfCargoPacketDeferredPayments(old_owner, new_owner);
|
ChangeOwnershipOfCargoPacketDeferredPayments(old_owner, new_owner);
|
||||||
|
|
||||||
|
IntialiseOrderDestinationRefcountMap();
|
||||||
|
|
||||||
cur_company.Restore();
|
cur_company.Restore();
|
||||||
|
|
||||||
MarkWholeScreenDirty();
|
MarkWholeScreenDirty();
|
||||||
|
@@ -102,6 +102,7 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin
|
|||||||
FreeSignalDependencies();
|
FreeSignalDependencies();
|
||||||
|
|
||||||
ClearZoningCaches();
|
ClearZoningCaches();
|
||||||
|
IntialiseOrderDestinationRefcountMap();
|
||||||
|
|
||||||
ResetPersistentNewGRFData();
|
ResetPersistentNewGRFData();
|
||||||
|
|
||||||
|
@@ -362,6 +362,7 @@ static void ShutdownGame()
|
|||||||
FreeSignalDependencies();
|
FreeSignalDependencies();
|
||||||
|
|
||||||
ClearZoningCaches();
|
ClearZoningCaches();
|
||||||
|
ClearOrderDestinationRefcountMap();
|
||||||
|
|
||||||
/* No NewGRFs were loaded when it was still bootstrapping. */
|
/* No NewGRFs were loaded when it was still bootstrapping. */
|
||||||
if (_game_mode != GM_BOOTSTRAP) ResetNewGRFData();
|
if (_game_mode != GM_BOOTSTRAP) ResetNewGRFData();
|
||||||
|
@@ -24,11 +24,32 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "3rdparty/cpp-btree/btree_map.h"
|
||||||
|
|
||||||
typedef Pool<Order, OrderID, 256, 0xFF0000> OrderPool;
|
typedef Pool<Order, OrderID, 256, 0xFF0000> OrderPool;
|
||||||
typedef Pool<OrderList, OrderListID, 128, 64000> OrderListPool;
|
typedef Pool<OrderList, OrderListID, 128, 64000> OrderListPool;
|
||||||
extern OrderPool _order_pool;
|
extern OrderPool _order_pool;
|
||||||
extern OrderListPool _orderlist_pool;
|
extern OrderListPool _orderlist_pool;
|
||||||
|
extern btree::btree_map<uint32, uint32> _order_destination_refcount_map;
|
||||||
|
extern bool _order_destination_refcount_map_valid;
|
||||||
|
|
||||||
|
inline uint32 OrderDestinationRefcountMapKey(DestinationID dest, CompanyID cid, OrderType order_type, VehicleType veh_type)
|
||||||
|
{
|
||||||
|
static_assert(sizeof(dest) == 2);
|
||||||
|
static_assert(OT_END <= 16);
|
||||||
|
return (((uint32) dest) << 16) | (((uint32) cid) << 8) | (((uint32) order_type) << 4) | ((uint32) veh_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename F> void IterateOrderRefcountMapForDestinationID(DestinationID dest, F handler)
|
||||||
|
{
|
||||||
|
for (auto lb = _order_destination_refcount_map.lower_bound(OrderDestinationRefcountMapKey(dest, (CompanyID) 0, (OrderType) 0, (VehicleType) 0)); lb != _order_destination_refcount_map.end(); ++lb) {
|
||||||
|
if (GB(lb->first, 16, 16) != dest) return;
|
||||||
|
if (lb->second && !handler((CompanyID) GB(lb->first, 8, 8), (OrderType) GB(lb->first, 4, 4), (VehicleType) GB(lb->first, 0, 4), lb->second)) return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IntialiseOrderDestinationRefcountMap();
|
||||||
|
void ClearOrderDestinationRefcountMap();
|
||||||
|
|
||||||
struct OrderExtraInfo {
|
struct OrderExtraInfo {
|
||||||
uint8 cargo_type_flags[NUM_CARGO] = {}; ///< Load/unload types for each cargo type.
|
uint8 cargo_type_flags[NUM_CARGO] = {}; ///< Load/unload types for each cargo type.
|
||||||
|
@@ -55,6 +55,47 @@ INSTANTIATE_POOL_METHODS(Order)
|
|||||||
OrderListPool _orderlist_pool("OrderList");
|
OrderListPool _orderlist_pool("OrderList");
|
||||||
INSTANTIATE_POOL_METHODS(OrderList)
|
INSTANTIATE_POOL_METHODS(OrderList)
|
||||||
|
|
||||||
|
btree::btree_map<uint32, uint32> _order_destination_refcount_map;
|
||||||
|
bool _order_destination_refcount_map_valid = false;
|
||||||
|
|
||||||
|
void IntialiseOrderDestinationRefcountMap()
|
||||||
|
{
|
||||||
|
ClearOrderDestinationRefcountMap();
|
||||||
|
const Vehicle *v;
|
||||||
|
FOR_ALL_VEHICLES(v) {
|
||||||
|
const Order *order;
|
||||||
|
FOR_VEHICLE_ORDERS(v, order) {
|
||||||
|
if (order->IsType(OT_GOTO_STATION) || order->IsType(OT_GOTO_WAYPOINT) || order->IsType(OT_IMPLICIT)) {
|
||||||
|
_order_destination_refcount_map[OrderDestinationRefcountMapKey(order->GetDestination(), v->owner, order->GetType(), v->type)]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_order_destination_refcount_map_valid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClearOrderDestinationRefcountMap()
|
||||||
|
{
|
||||||
|
_order_destination_refcount_map.clear();
|
||||||
|
_order_destination_refcount_map_valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UpdateOrderDestinationRefcount(const Order *order, VehicleType type, Owner owner, int delta)
|
||||||
|
{
|
||||||
|
if (order->IsType(OT_GOTO_STATION) || order->IsType(OT_GOTO_WAYPOINT) || order->IsType(OT_IMPLICIT)) {
|
||||||
|
_order_destination_refcount_map[OrderDestinationRefcountMapKey(order->GetDestination(), owner, order->GetType(), type)] += delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void RegisterOrderDestination(const Order *order, VehicleType type, Owner owner)
|
||||||
|
{
|
||||||
|
if (_order_destination_refcount_map_valid) UpdateOrderDestinationRefcount(order, type, owner, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void UnregisterOrderDestination(const Order *order, VehicleType type, Owner owner)
|
||||||
|
{
|
||||||
|
if (_order_destination_refcount_map_valid) UpdateOrderDestinationRefcount(order, type, owner, -1);
|
||||||
|
}
|
||||||
|
|
||||||
/** Clean everything up. */
|
/** Clean everything up. */
|
||||||
Order::~Order()
|
Order::~Order()
|
||||||
{
|
{
|
||||||
@@ -397,6 +438,9 @@ void OrderList::Initialize(Order *chain, Vehicle *v)
|
|||||||
this->total_duration = 0;
|
this->total_duration = 0;
|
||||||
this->order_index.clear();
|
this->order_index.clear();
|
||||||
|
|
||||||
|
VehicleType type = v->type;
|
||||||
|
Owner owner = v->owner;
|
||||||
|
|
||||||
for (Order *o = this->first; o != nullptr; o = o->next) {
|
for (Order *o = this->first; o != nullptr; o = o->next) {
|
||||||
if (!o->IsType(OT_IMPLICIT)) ++this->num_manual_orders;
|
if (!o->IsType(OT_IMPLICIT)) ++this->num_manual_orders;
|
||||||
if (!o->IsType(OT_CONDITIONAL)) {
|
if (!o->IsType(OT_CONDITIONAL)) {
|
||||||
@@ -404,6 +448,7 @@ void OrderList::Initialize(Order *chain, Vehicle *v)
|
|||||||
this->total_duration += o->GetWaitTime() + o->GetTravelTime();
|
this->total_duration += o->GetWaitTime() + o->GetTravelTime();
|
||||||
}
|
}
|
||||||
this->order_index.push_back(o);
|
this->order_index.push_back(o);
|
||||||
|
RegisterOrderDestination(o, type, owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Vehicle *u = this->first_shared->PreviousShared(); u != nullptr; u = u->PreviousShared()) {
|
for (Vehicle *u = this->first_shared->PreviousShared(); u != nullptr; u = u->PreviousShared()) {
|
||||||
@@ -422,7 +467,10 @@ void OrderList::Initialize(Order *chain, Vehicle *v)
|
|||||||
void OrderList::FreeChain(bool keep_orderlist)
|
void OrderList::FreeChain(bool keep_orderlist)
|
||||||
{
|
{
|
||||||
Order *next;
|
Order *next;
|
||||||
|
VehicleType type = this->GetFirstSharedVehicle()->type;
|
||||||
|
Owner owner = this->GetFirstSharedVehicle()->owner;
|
||||||
for (Order *o = this->first; o != nullptr; o = next) {
|
for (Order *o = this->first; o != nullptr; o = next) {
|
||||||
|
UnregisterOrderDestination(o, type, owner);
|
||||||
next = o->next;
|
next = o->next;
|
||||||
delete o;
|
delete o;
|
||||||
}
|
}
|
||||||
@@ -629,6 +677,7 @@ void OrderList::InsertOrderAt(Order *new_order, int index)
|
|||||||
this->timetable_duration += new_order->GetTimetabledWait() + new_order->GetTimetabledTravel();
|
this->timetable_duration += new_order->GetTimetabledWait() + new_order->GetTimetabledTravel();
|
||||||
this->total_duration += new_order->GetWaitTime() + new_order->GetTravelTime();
|
this->total_duration += new_order->GetWaitTime() + new_order->GetTravelTime();
|
||||||
}
|
}
|
||||||
|
RegisterOrderDestination(new_order, this->GetFirstSharedVehicle()->type, this->GetFirstSharedVehicle()->owner);
|
||||||
this->ReindexOrderList();
|
this->ReindexOrderList();
|
||||||
|
|
||||||
/* We can visit oil rigs and buoys that are not our own. They will be shown in
|
/* We can visit oil rigs and buoys that are not our own. They will be shown in
|
||||||
@@ -664,6 +713,7 @@ void OrderList::DeleteOrderAt(int index)
|
|||||||
this->timetable_duration -= (to_remove->GetTimetabledWait() + to_remove->GetTimetabledTravel());
|
this->timetable_duration -= (to_remove->GetTimetabledWait() + to_remove->GetTimetabledTravel());
|
||||||
this->total_duration -= (to_remove->GetWaitTime() + to_remove->GetTravelTime());
|
this->total_duration -= (to_remove->GetWaitTime() + to_remove->GetTravelTime());
|
||||||
}
|
}
|
||||||
|
UnregisterOrderDestination(to_remove, this->GetFirstSharedVehicle()->type, this->GetFirstSharedVehicle()->owner);
|
||||||
delete to_remove;
|
delete to_remove;
|
||||||
this->ReindexOrderList();
|
this->ReindexOrderList();
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user