mirror of https://github.com/OpenTTD/OpenTTD
(svn r15617) -Change [FS#2694]: vehicle variables 40-43 weren't cached (though spec stated they are). Caching these variables can yield a 10+% speed increase when those vehicle variables are queried often.
parent
890c5e3ae4
commit
c0d71b84f9
|
@ -19,6 +19,7 @@
|
|||
#include "company_base.h"
|
||||
#include "company_gui.h"
|
||||
#include "settings_type.h"
|
||||
#include "vehicle_base.h"
|
||||
|
||||
#include "table/strings.h"
|
||||
|
||||
|
@ -118,6 +119,12 @@ CommandCost CmdSetCompanyColour(TileIndex tile, DoCommandFlag flags, uint32 p1,
|
|||
}
|
||||
ResetVehicleColourMap();
|
||||
MarkWholeScreenDirty();
|
||||
|
||||
/* Company colour data is indirectly cached. */
|
||||
Vehicle *v;
|
||||
FOR_ALL_VEHICLES(v) {
|
||||
if (v->owner == _current_company) v->cache_valid = 0;
|
||||
}
|
||||
}
|
||||
return CommandCost();
|
||||
}
|
||||
|
|
|
@ -442,10 +442,35 @@ static uint8 LiveryHelper(EngineID engine, const Vehicle *v)
|
|||
return l->colour1 + l->colour2 * 16;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get the position of a vehicle within a chain of vehicles.
|
||||
* @param v the vehicle to get the position of.
|
||||
* @param consecutive whether to look at the whole chain or the vehicles
|
||||
* with the same 'engine type'.
|
||||
* @return the position in the chain from front and tail and chain length.
|
||||
*/
|
||||
static uint32 PositionHelper(const Vehicle *v, bool consecutive)
|
||||
{
|
||||
const Vehicle *u;
|
||||
byte chain_before = 0;
|
||||
byte chain_after = 0;
|
||||
|
||||
for (u = v->First(); u != v; u = u->Next()) {
|
||||
chain_before++;
|
||||
if (consecutive && u->engine_type != v->engine_type) chain_before = 0;
|
||||
}
|
||||
|
||||
while (u->Next() != NULL && (!consecutive || u->Next()->engine_type == v->engine_type)) {
|
||||
chain_after++;
|
||||
u = u->Next();
|
||||
}
|
||||
|
||||
return chain_before | chain_after << 8 | (chain_before + chain_after + consecutive) << 16;
|
||||
}
|
||||
|
||||
static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, byte parameter, bool *available)
|
||||
{
|
||||
const Vehicle *v = GRV(object);
|
||||
Vehicle *v = const_cast<Vehicle*>(GRV(object));
|
||||
|
||||
if (v == NULL) {
|
||||
/* Vehicle does not exist, so we're in a purchase list */
|
||||
|
@ -476,80 +501,81 @@ static uint32 VehicleGetVariable(const ResolverObject *object, byte variable, by
|
|||
/* Calculated vehicle parameters */
|
||||
switch (variable) {
|
||||
case 0x40: // Get length of consist
|
||||
if (!HasBit(v->cache_valid, 0)) {
|
||||
v->cached_var40 = PositionHelper(v, false);
|
||||
SetBit(v->cache_valid, 0);
|
||||
}
|
||||
return v->cached_var40;
|
||||
|
||||
case 0x41: // Get length of same consecutive wagons
|
||||
{
|
||||
if (!HasBit(v->cache_valid, 1)) {
|
||||
v->cached_var41 = PositionHelper(v, true);
|
||||
SetBit(v->cache_valid, 1);
|
||||
}
|
||||
return v->cached_var41;
|
||||
|
||||
case 0x42: // Consist cargo information
|
||||
if (!HasBit(v->cache_valid, 2)) {
|
||||
const Vehicle *u;
|
||||
byte chain_before = 0;
|
||||
byte chain_after = 0;
|
||||
byte cargo_classes = 0;
|
||||
CargoID common_cargo_best = CT_INVALID;
|
||||
uint8 common_cargos[NUM_CARGO];
|
||||
uint8 common_subtype_best = 0xFF; // Return 0xFF if nothing is carried
|
||||
uint8 common_subtypes[256];
|
||||
byte user_def_data = 0;
|
||||
CargoID common_cargo_type = CT_PASSENGERS;
|
||||
uint8 common_subtype = 0;
|
||||
|
||||
for (u = v->First(); u != v; u = u->Next()) {
|
||||
chain_before++;
|
||||
if (variable == 0x41 && u->engine_type != v->engine_type) chain_before = 0;
|
||||
/* Reset our arrays */
|
||||
memset(common_cargos, 0, sizeof(common_cargos));
|
||||
memset(common_subtypes, 0, sizeof(common_subtypes));
|
||||
|
||||
for (u = v; u != NULL; u = u->Next()) {
|
||||
if (v->type == VEH_TRAIN) user_def_data |= u->u.rail.user_def_data;
|
||||
|
||||
/* Skip empty engines */
|
||||
if (u->cargo_cap == 0) continue;
|
||||
|
||||
cargo_classes |= GetCargo(u->cargo_type)->classes;
|
||||
common_cargos[u->cargo_type]++;
|
||||
}
|
||||
|
||||
while (u->Next() != NULL && (variable == 0x40 || u->Next()->engine_type == v->engine_type)) {
|
||||
chain_after++;
|
||||
u = u->Next();
|
||||
/* Pick the most common cargo type */
|
||||
for (CargoID cargo = 0; cargo < NUM_CARGO; cargo++) {
|
||||
if (common_cargos[cargo] > common_cargo_best) {
|
||||
common_cargo_best = common_cargos[cargo];
|
||||
common_cargo_type = cargo;
|
||||
}
|
||||
}
|
||||
|
||||
return chain_before | chain_after << 8 | (chain_before + chain_after + (variable == 0x41)) << 16;
|
||||
}
|
||||
/* Count subcargo types of common_cargo_type */
|
||||
for (u = v; u != NULL; u = u->Next()) {
|
||||
/* Skip empty engines and engines not carrying common_cargo_type */
|
||||
if (u->cargo_cap == 0 || u->cargo_type != common_cargo_type) continue;
|
||||
|
||||
case 0x42: { // Consist cargo information
|
||||
const Vehicle *u;
|
||||
byte cargo_classes = 0;
|
||||
CargoID common_cargo_best = CT_INVALID;
|
||||
uint8 common_cargos[NUM_CARGO];
|
||||
uint8 common_subtype_best = 0xFF; // Return 0xFF if nothing is carried
|
||||
uint8 common_subtypes[256];
|
||||
byte user_def_data = 0;
|
||||
CargoID common_cargo_type = CT_PASSENGERS;
|
||||
uint8 common_subtype = 0;
|
||||
|
||||
/* Reset our arrays */
|
||||
memset(common_cargos, 0, sizeof(common_cargos));
|
||||
memset(common_subtypes, 0, sizeof(common_subtypes));
|
||||
|
||||
for (u = v; u != NULL; u = u->Next()) {
|
||||
if (v->type == VEH_TRAIN) user_def_data |= u->u.rail.user_def_data;
|
||||
|
||||
/* Skip empty engines */
|
||||
if (u->cargo_cap == 0) continue;
|
||||
|
||||
cargo_classes |= GetCargo(u->cargo_type)->classes;
|
||||
common_cargos[u->cargo_type]++;
|
||||
}
|
||||
|
||||
/* Pick the most common cargo type */
|
||||
for (CargoID cargo = 0; cargo < NUM_CARGO; cargo++) {
|
||||
if (common_cargos[cargo] > common_cargo_best) {
|
||||
common_cargo_best = common_cargos[cargo];
|
||||
common_cargo_type = cargo;
|
||||
common_subtypes[u->cargo_subtype]++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Count subcargo types of common_cargo_type */
|
||||
for (u = v; u != NULL; u = u->Next()) {
|
||||
/* Skip empty engines and engines not carrying common_cargo_type */
|
||||
if (u->cargo_cap == 0 || u->cargo_type != common_cargo_type) continue;
|
||||
|
||||
common_subtypes[u->cargo_subtype]++;
|
||||
}
|
||||
|
||||
/* Pick the most common subcargo type*/
|
||||
for (uint i = 0; i < lengthof(common_subtypes); i++) {
|
||||
if (common_subtypes[i] > common_subtype_best) {
|
||||
common_subtype_best = common_subtypes[i];
|
||||
common_subtype = i;
|
||||
/* Pick the most common subcargo type*/
|
||||
for (uint i = 0; i < lengthof(common_subtypes); i++) {
|
||||
if (common_subtypes[i] > common_subtype_best) {
|
||||
common_subtype_best = common_subtypes[i];
|
||||
common_subtype = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8 common_bitnum = (common_cargo_type == CT_INVALID ? 0xFF : GetCargo(common_cargo_type)->bitnum);
|
||||
return cargo_classes | (common_bitnum << 8) | (common_subtype << 16) | (user_def_data << 24);
|
||||
}
|
||||
uint8 common_bitnum = (common_cargo_type == CT_INVALID ? 0xFF : GetCargo(common_cargo_type)->bitnum);
|
||||
v->cached_var42 = cargo_classes | (common_bitnum << 8) | (common_subtype << 16) | (user_def_data << 24);
|
||||
SetBit(v->cache_valid, 2);
|
||||
}
|
||||
return v->cached_var42;
|
||||
|
||||
case 0x43: // Company information
|
||||
return v->owner | (GetCompany(v->owner)->is_ai ? 0x10000 : 0) | (LiveryHelper(v->engine_type, v) << 24);
|
||||
if (!HasBit(v->cache_valid, 3)) {
|
||||
v->cached_var43 = v->owner | (GetCompany(v->owner)->is_ai ? 0x10000 : 0) | (LiveryHelper(v->engine_type, v) << 24);
|
||||
SetBit(v->cache_valid, 3);
|
||||
}
|
||||
return v->cached_var43;
|
||||
|
||||
case 0x44: // Aircraft information
|
||||
if (v->type != VEH_AIRCRAFT) return UINT_MAX;
|
||||
|
|
|
@ -257,11 +257,13 @@ void TrainConsistChanged(Vehicle *v, bool same_length)
|
|||
|
||||
/* Set user defined data to its default value */
|
||||
u->u.rail.user_def_data = rvi_u->user_def_data;
|
||||
u->cache_valid = 0;
|
||||
}
|
||||
|
||||
for (Vehicle *u = v; u != NULL; u = u->Next()) {
|
||||
/* Update user defined data (must be done before other properties) */
|
||||
u->u.rail.user_def_data = GetVehicleProperty(u, 0x25, u->u.rail.user_def_data);
|
||||
u->cache_valid = 0;
|
||||
}
|
||||
|
||||
for (Vehicle *u = v; u != NULL; u = u->Next()) {
|
||||
|
@ -347,6 +349,7 @@ void TrainConsistChanged(Vehicle *v, bool same_length)
|
|||
if (!same_length) u->u.rail.cached_veh_length = veh_len;
|
||||
|
||||
v->u.rail.cached_total_length += u->u.rail.cached_veh_length;
|
||||
u->cache_valid = 0;
|
||||
}
|
||||
|
||||
/* store consist weight/max speed in cache */
|
||||
|
|
|
@ -323,6 +323,12 @@ public:
|
|||
VehicleShip ship;
|
||||
} u;
|
||||
|
||||
/* cached oftenly queried NewGRF values */
|
||||
uint8 cache_valid; ///< Whether the caches are valid
|
||||
uint32 cached_var40; ///< Cache for NewGRF var 40
|
||||
uint32 cached_var41; ///< Cache for NewGRF var 41
|
||||
uint32 cached_var42; ///< Cache for NewGRF var 42
|
||||
uint32 cached_var43; ///< Cache for NewGRF var 43
|
||||
|
||||
/**
|
||||
* Allocates a lot of vehicles.
|
||||
|
|
Loading…
Reference in New Issue