diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index a00fb8ed3d..b775e28ba1 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -22,6 +22,7 @@ #include "../string_func.h" #include "../error.h" #include "../strings_func.h" +#include "../3rdparty/cpp-btree/btree_map.h" #include "saveload.h" @@ -29,6 +30,8 @@ #include "../safeguards.h" +extern btree::btree_multimap _pending_speed_restriction_change_map; + /** * Link front and rear multiheaded engines to each other * This is done when loading a savegame @@ -1134,15 +1137,10 @@ const SaveLoadTable GetVehicleSpeedRestrictionDescription() void Save_VESR() { - for (Train *t : Train::Iterate()) { - if (HasBit(t->flags, VRF_PENDING_SPEED_RESTRICTION)) { - auto range = pending_speed_restriction_change_map.equal_range(t->index); - for (auto it = range.first; it != range.second; ++it) { - SlSetArrayIndex(t->index); - PendingSpeedRestrictionChange *ptr = &(it->second); - SlObject(ptr, GetVehicleSpeedRestrictionDescription()); - } - } + for (auto &it : _pending_speed_restriction_change_map) { + SlSetArrayIndex(it.first); + PendingSpeedRestrictionChange *ptr = &(it.second); + SlObject(ptr, GetVehicleSpeedRestrictionDescription()); } } @@ -1150,7 +1148,7 @@ void Load_VESR() { int index; while ((index = SlIterateArray()) != -1) { - auto iter = pending_speed_restriction_change_map.insert({ static_cast(index), {} }); + auto iter = _pending_speed_restriction_change_map.insert({ static_cast(index), {} }); PendingSpeedRestrictionChange *ptr = &(iter->second); SlObject(ptr, GetVehicleSpeedRestrictionDescription()); } diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 2835db54b0..d1c029f7a1 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -46,12 +46,15 @@ #include "debug_settings.h" #include "train_speed_adaptation.h" #include "event_logs.h" +#include "3rdparty/cpp-btree/btree_map.h" #include "table/strings.h" #include "table/train_cmd.h" #include "safeguards.h" +extern btree::btree_multimap _pending_speed_restriction_change_map; + enum { REALISTIC_BRAKING_MIN_SPEED = 5, }; @@ -2988,12 +2991,11 @@ void ReverseTrainDirection(Train *v) if (crossing != INVALID_TILE) MaybeBarCrossingWithSound(crossing); if (HasBit(v->flags, VRF_PENDING_SPEED_RESTRICTION)) { - auto range = pending_speed_restriction_change_map.equal_range(v->index); - for (auto it = range.first; it != range.second;) { + for (auto it = _pending_speed_restriction_change_map.lower_bound(v->index); it != _pending_speed_restriction_change_map.end() && it->first == v->index;) { it->second.distance = (v->gcache.cached_total_length + (HasBit(it->second.flags, PSRCF_DIAGONAL) ? 8 : 4)) - it->second.distance; if (it->second.distance == 0) { v->speed_restriction = it->second.prev_speed; - it = pending_speed_restriction_change_map.erase(it); + it = _pending_speed_restriction_change_map.erase(it); } else { std::swap(it->second.prev_speed, it->second.new_speed); ++it; @@ -5356,29 +5358,29 @@ int ReversingDistanceTargetSpeed(const Train *v) void DecrementPendingSpeedRestrictions(Train *v) { - auto range = pending_speed_restriction_change_map.equal_range(v->index); - if (range.first == range.second) ClrBit(v->flags, VRF_PENDING_SPEED_RESTRICTION); - for (auto it = range.first; it != range.second;) { + bool remaining = false; + for (auto it = _pending_speed_restriction_change_map.lower_bound(v->index); it != _pending_speed_restriction_change_map.end() && it->first == v->index;) { if (--it->second.distance == 0) { v->speed_restriction = it->second.new_speed; - it = pending_speed_restriction_change_map.erase(it); + it = _pending_speed_restriction_change_map.erase(it); } else { ++it; + remaining = true; } } + if (!remaining) ClrBit(v->flags, VRF_PENDING_SPEED_RESTRICTION); } void HandleTraceRestrictSpeedRestrictionAction(const TraceRestrictProgramResult &out, Train *v, Trackdir signal_td) { if (out.flags & TRPRF_SPEED_RESTRICTION_SET) { SetBit(v->flags, VRF_PENDING_SPEED_RESTRICTION); - auto range = pending_speed_restriction_change_map.equal_range(v->index); - for (auto it = range.first; it != range.second; ++it) { + for (auto it = _pending_speed_restriction_change_map.lower_bound(v->index); it != _pending_speed_restriction_change_map.end() && it->first == v->index; ++it) { if ((uint16) (out.speed_restriction + 0xFFFF) < (uint16) (it->second.new_speed + 0xFFFF)) it->second.new_speed = out.speed_restriction; } uint16 flags = 0; if (IsDiagonalTrack(TrackdirToTrack(signal_td))) SetBit(flags, PSRCF_DIAGONAL); - pending_speed_restriction_change_map.insert({ v->index, { (uint16) (v->gcache.cached_total_length + (HasBit(flags, PSRCF_DIAGONAL) ? 8 : 4)), out.speed_restriction, v->speed_restriction, flags } }); + _pending_speed_restriction_change_map.insert({ v->index, { (uint16) (v->gcache.cached_total_length + (HasBit(flags, PSRCF_DIAGONAL) ? 8 : 4)), out.speed_restriction, v->speed_restriction, flags } }); if ((uint16) (out.speed_restriction + 0xFFFF) < (uint16) (v->speed_restriction + 0xFFFF)) v->speed_restriction = out.speed_restriction; } if (out.flags & TRPRF_SPEED_ADAPT_EXEMPT && !HasBit(v->flags, VRF_SPEED_ADAPTATION_EXEMPT)) { diff --git a/src/vehicle.cpp b/src/vehicle.cpp index b7acf02ea3..0064bd9fb1 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -60,6 +60,7 @@ #include "scope_info.h" #include "debug_settings.h" #include "3rdparty/cpp-btree/btree_set.h" +#include "3rdparty/cpp-btree/btree_map.h" #include "table/strings.h" @@ -105,7 +106,7 @@ INSTANTIATE_POOL_METHODS(Vehicle) static btree::btree_set _vehicles_to_pay_repair; static btree::btree_set _vehicles_to_sell; -std::unordered_multimap pending_speed_restriction_change_map; +btree::btree_multimap _pending_speed_restriction_change_map; /** * Determine shared bounds of all sprites. @@ -1168,7 +1169,7 @@ void Vehicle::PreDestructor() ClrBit(this->vehicle_flags, VF_HAVE_SLOT); } if (this->type == VEH_TRAIN && HasBit(Train::From(this)->flags, VRF_PENDING_SPEED_RESTRICTION)) { - pending_speed_restriction_change_map.erase(this->index); + _pending_speed_restriction_change_map.erase(this->index); ClrBit(Train::From(this)->flags, VRF_PENDING_SPEED_RESTRICTION); } @@ -1240,7 +1241,7 @@ Vehicle::~Vehicle() */ void Vehicle::PreCleanPool() { - pending_speed_restriction_change_map.clear(); + _pending_speed_restriction_change_map.clear(); } /** diff --git a/src/vehicle_base.h b/src/vehicle_base.h index 55fa5b54a3..942c2cdb0b 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -28,7 +28,6 @@ #include "saveload/saveload_common.h" #include #include -#include CommandCost CmdRefitVehicle(TileIndex, DoCommandFlag, uint32, uint32, const char*); @@ -224,7 +223,6 @@ struct PendingSpeedRestrictionChange { uint16 prev_speed; uint16 flags; }; -extern std::unordered_multimap pending_speed_restriction_change_map; /** A vehicle pool for a little over 1 million vehicles. */ typedef Pool VehiclePool;