Use btree_multimap for pending speed restrictions
Avoid unnecessary iteration when saving VESR chunk
This commit is contained in:
@@ -22,6 +22,7 @@
|
|||||||
#include "../string_func.h"
|
#include "../string_func.h"
|
||||||
#include "../error.h"
|
#include "../error.h"
|
||||||
#include "../strings_func.h"
|
#include "../strings_func.h"
|
||||||
|
#include "../3rdparty/cpp-btree/btree_map.h"
|
||||||
|
|
||||||
#include "saveload.h"
|
#include "saveload.h"
|
||||||
|
|
||||||
@@ -29,6 +30,8 @@
|
|||||||
|
|
||||||
#include "../safeguards.h"
|
#include "../safeguards.h"
|
||||||
|
|
||||||
|
extern btree::btree_multimap<VehicleID, PendingSpeedRestrictionChange> _pending_speed_restriction_change_map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Link front and rear multiheaded engines to each other
|
* Link front and rear multiheaded engines to each other
|
||||||
* This is done when loading a savegame
|
* This is done when loading a savegame
|
||||||
@@ -1134,23 +1137,18 @@ const SaveLoadTable GetVehicleSpeedRestrictionDescription()
|
|||||||
|
|
||||||
void Save_VESR()
|
void Save_VESR()
|
||||||
{
|
{
|
||||||
for (Train *t : Train::Iterate()) {
|
for (auto &it : _pending_speed_restriction_change_map) {
|
||||||
if (HasBit(t->flags, VRF_PENDING_SPEED_RESTRICTION)) {
|
SlSetArrayIndex(it.first);
|
||||||
auto range = pending_speed_restriction_change_map.equal_range(t->index);
|
PendingSpeedRestrictionChange *ptr = &(it.second);
|
||||||
for (auto it = range.first; it != range.second; ++it) {
|
|
||||||
SlSetArrayIndex(t->index);
|
|
||||||
PendingSpeedRestrictionChange *ptr = &(it->second);
|
|
||||||
SlObject(ptr, GetVehicleSpeedRestrictionDescription());
|
SlObject(ptr, GetVehicleSpeedRestrictionDescription());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Load_VESR()
|
void Load_VESR()
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
while ((index = SlIterateArray()) != -1) {
|
while ((index = SlIterateArray()) != -1) {
|
||||||
auto iter = pending_speed_restriction_change_map.insert({ static_cast<VehicleID>(index), {} });
|
auto iter = _pending_speed_restriction_change_map.insert({ static_cast<VehicleID>(index), {} });
|
||||||
PendingSpeedRestrictionChange *ptr = &(iter->second);
|
PendingSpeedRestrictionChange *ptr = &(iter->second);
|
||||||
SlObject(ptr, GetVehicleSpeedRestrictionDescription());
|
SlObject(ptr, GetVehicleSpeedRestrictionDescription());
|
||||||
}
|
}
|
||||||
|
@@ -46,12 +46,15 @@
|
|||||||
#include "debug_settings.h"
|
#include "debug_settings.h"
|
||||||
#include "train_speed_adaptation.h"
|
#include "train_speed_adaptation.h"
|
||||||
#include "event_logs.h"
|
#include "event_logs.h"
|
||||||
|
#include "3rdparty/cpp-btree/btree_map.h"
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
#include "table/train_cmd.h"
|
#include "table/train_cmd.h"
|
||||||
|
|
||||||
#include "safeguards.h"
|
#include "safeguards.h"
|
||||||
|
|
||||||
|
extern btree::btree_multimap<VehicleID, PendingSpeedRestrictionChange> _pending_speed_restriction_change_map;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
REALISTIC_BRAKING_MIN_SPEED = 5,
|
REALISTIC_BRAKING_MIN_SPEED = 5,
|
||||||
};
|
};
|
||||||
@@ -2988,12 +2991,11 @@ void ReverseTrainDirection(Train *v)
|
|||||||
if (crossing != INVALID_TILE) MaybeBarCrossingWithSound(crossing);
|
if (crossing != INVALID_TILE) MaybeBarCrossingWithSound(crossing);
|
||||||
|
|
||||||
if (HasBit(v->flags, VRF_PENDING_SPEED_RESTRICTION)) {
|
if (HasBit(v->flags, VRF_PENDING_SPEED_RESTRICTION)) {
|
||||||
auto range = pending_speed_restriction_change_map.equal_range(v->index);
|
for (auto it = _pending_speed_restriction_change_map.lower_bound(v->index); it != _pending_speed_restriction_change_map.end() && it->first == v->index;) {
|
||||||
for (auto it = range.first; it != range.second;) {
|
|
||||||
it->second.distance = (v->gcache.cached_total_length + (HasBit(it->second.flags, PSRCF_DIAGONAL) ? 8 : 4)) - it->second.distance;
|
it->second.distance = (v->gcache.cached_total_length + (HasBit(it->second.flags, PSRCF_DIAGONAL) ? 8 : 4)) - it->second.distance;
|
||||||
if (it->second.distance == 0) {
|
if (it->second.distance == 0) {
|
||||||
v->speed_restriction = it->second.prev_speed;
|
v->speed_restriction = it->second.prev_speed;
|
||||||
it = pending_speed_restriction_change_map.erase(it);
|
it = _pending_speed_restriction_change_map.erase(it);
|
||||||
} else {
|
} else {
|
||||||
std::swap(it->second.prev_speed, it->second.new_speed);
|
std::swap(it->second.prev_speed, it->second.new_speed);
|
||||||
++it;
|
++it;
|
||||||
@@ -5356,29 +5358,29 @@ int ReversingDistanceTargetSpeed(const Train *v)
|
|||||||
|
|
||||||
void DecrementPendingSpeedRestrictions(Train *v)
|
void DecrementPendingSpeedRestrictions(Train *v)
|
||||||
{
|
{
|
||||||
auto range = pending_speed_restriction_change_map.equal_range(v->index);
|
bool remaining = false;
|
||||||
if (range.first == range.second) ClrBit(v->flags, VRF_PENDING_SPEED_RESTRICTION);
|
for (auto it = _pending_speed_restriction_change_map.lower_bound(v->index); it != _pending_speed_restriction_change_map.end() && it->first == v->index;) {
|
||||||
for (auto it = range.first; it != range.second;) {
|
|
||||||
if (--it->second.distance == 0) {
|
if (--it->second.distance == 0) {
|
||||||
v->speed_restriction = it->second.new_speed;
|
v->speed_restriction = it->second.new_speed;
|
||||||
it = pending_speed_restriction_change_map.erase(it);
|
it = _pending_speed_restriction_change_map.erase(it);
|
||||||
} else {
|
} else {
|
||||||
++it;
|
++it;
|
||||||
|
remaining = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!remaining) ClrBit(v->flags, VRF_PENDING_SPEED_RESTRICTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandleTraceRestrictSpeedRestrictionAction(const TraceRestrictProgramResult &out, Train *v, Trackdir signal_td)
|
void HandleTraceRestrictSpeedRestrictionAction(const TraceRestrictProgramResult &out, Train *v, Trackdir signal_td)
|
||||||
{
|
{
|
||||||
if (out.flags & TRPRF_SPEED_RESTRICTION_SET) {
|
if (out.flags & TRPRF_SPEED_RESTRICTION_SET) {
|
||||||
SetBit(v->flags, VRF_PENDING_SPEED_RESTRICTION);
|
SetBit(v->flags, VRF_PENDING_SPEED_RESTRICTION);
|
||||||
auto range = pending_speed_restriction_change_map.equal_range(v->index);
|
for (auto it = _pending_speed_restriction_change_map.lower_bound(v->index); it != _pending_speed_restriction_change_map.end() && it->first == v->index; ++it) {
|
||||||
for (auto it = range.first; it != range.second; ++it) {
|
|
||||||
if ((uint16) (out.speed_restriction + 0xFFFF) < (uint16) (it->second.new_speed + 0xFFFF)) it->second.new_speed = out.speed_restriction;
|
if ((uint16) (out.speed_restriction + 0xFFFF) < (uint16) (it->second.new_speed + 0xFFFF)) it->second.new_speed = out.speed_restriction;
|
||||||
}
|
}
|
||||||
uint16 flags = 0;
|
uint16 flags = 0;
|
||||||
if (IsDiagonalTrack(TrackdirToTrack(signal_td))) SetBit(flags, PSRCF_DIAGONAL);
|
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 ((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)) {
|
if (out.flags & TRPRF_SPEED_ADAPT_EXEMPT && !HasBit(v->flags, VRF_SPEED_ADAPTATION_EXEMPT)) {
|
||||||
|
@@ -60,6 +60,7 @@
|
|||||||
#include "scope_info.h"
|
#include "scope_info.h"
|
||||||
#include "debug_settings.h"
|
#include "debug_settings.h"
|
||||||
#include "3rdparty/cpp-btree/btree_set.h"
|
#include "3rdparty/cpp-btree/btree_set.h"
|
||||||
|
#include "3rdparty/cpp-btree/btree_map.h"
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
|
|
||||||
@@ -105,7 +106,7 @@ INSTANTIATE_POOL_METHODS(Vehicle)
|
|||||||
static btree::btree_set<VehicleID> _vehicles_to_pay_repair;
|
static btree::btree_set<VehicleID> _vehicles_to_pay_repair;
|
||||||
static btree::btree_set<VehicleID> _vehicles_to_sell;
|
static btree::btree_set<VehicleID> _vehicles_to_sell;
|
||||||
|
|
||||||
std::unordered_multimap<VehicleID, PendingSpeedRestrictionChange> pending_speed_restriction_change_map;
|
btree::btree_multimap<VehicleID, PendingSpeedRestrictionChange> _pending_speed_restriction_change_map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine shared bounds of all sprites.
|
* Determine shared bounds of all sprites.
|
||||||
@@ -1168,7 +1169,7 @@ void Vehicle::PreDestructor()
|
|||||||
ClrBit(this->vehicle_flags, VF_HAVE_SLOT);
|
ClrBit(this->vehicle_flags, VF_HAVE_SLOT);
|
||||||
}
|
}
|
||||||
if (this->type == VEH_TRAIN && HasBit(Train::From(this)->flags, VRF_PENDING_SPEED_RESTRICTION)) {
|
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);
|
ClrBit(Train::From(this)->flags, VRF_PENDING_SPEED_RESTRICTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1240,7 +1241,7 @@ Vehicle::~Vehicle()
|
|||||||
*/
|
*/
|
||||||
void Vehicle::PreCleanPool()
|
void Vehicle::PreCleanPool()
|
||||||
{
|
{
|
||||||
pending_speed_restriction_change_map.clear();
|
_pending_speed_restriction_change_map.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -28,7 +28,6 @@
|
|||||||
#include "saveload/saveload_common.h"
|
#include "saveload/saveload_common.h"
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <unordered_map>
|
|
||||||
|
|
||||||
CommandCost CmdRefitVehicle(TileIndex, DoCommandFlag, uint32, uint32, const char*);
|
CommandCost CmdRefitVehicle(TileIndex, DoCommandFlag, uint32, uint32, const char*);
|
||||||
|
|
||||||
@@ -224,7 +223,6 @@ struct PendingSpeedRestrictionChange {
|
|||||||
uint16 prev_speed;
|
uint16 prev_speed;
|
||||||
uint16 flags;
|
uint16 flags;
|
||||||
};
|
};
|
||||||
extern std::unordered_multimap<VehicleID, PendingSpeedRestrictionChange> pending_speed_restriction_change_map;
|
|
||||||
|
|
||||||
/** A vehicle pool for a little over 1 million vehicles. */
|
/** A vehicle pool for a little over 1 million vehicles. */
|
||||||
typedef Pool<Vehicle, VehicleID, 512, 0xFF000> VehiclePool;
|
typedef Pool<Vehicle, VehicleID, 512, 0xFF000> VehiclePool;
|
||||||
|
Reference in New Issue
Block a user