mirror of https://github.com/OpenTTD/OpenTTD
(svn r3954) - Explicitly update v->first in TrainConsistChanged() if necessary, as this is far faster than brute forcing it later.
- When loading a game, call TrainConsistChanged() for each train head separately before updating images, as v->first is used extensively in GetTrainImage() for custom graphics. This gives a significant speed improvement on loading a game. - Rewrite GetFreeUnitNumber() so that only one loop of vehicles is required. Instead a list of used/unused numbers is created and the first unused number is chosen. This significantly improves performance in large games. - Improve game-load times. Backport of r3570-3572 from trunkrelease/0.4.5
parent
f75365fcf4
commit
7ddae93da8
|
@ -93,6 +93,9 @@ void TrainConsistChanged(Vehicle* v)
|
|||
const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type);
|
||||
uint16 veh_len;
|
||||
|
||||
// Update the v->first cache. This is faster than having to brute force it later.
|
||||
if (u->first == NULL) u->first = v;
|
||||
|
||||
// update the 'first engine'
|
||||
u->u.rail.first_engine = (v == u) ? INVALID_VEHICLE : first_engine;
|
||||
|
||||
|
|
50
vehicle.c
50
vehicle.c
|
@ -218,6 +218,11 @@ void AfterLoadVehicles(void)
|
|||
|
||||
FOR_ALL_VEHICLES(v) {
|
||||
v->first = NULL;
|
||||
if (v->type == VEH_Train && (IsFrontEngine(v) || IsFreeWagon(v)))
|
||||
TrainConsistChanged(v);
|
||||
}
|
||||
|
||||
FOR_ALL_VEHICLES(v) {
|
||||
if (v->type != 0) {
|
||||
switch (v->type) {
|
||||
case VEH_Train: v->cur_image = GetTrainImage(v, v->direction); break;
|
||||
|
@ -234,9 +239,6 @@ void AfterLoadVehicles(void)
|
|||
|
||||
v->left_coord = INVALID_COORD;
|
||||
VehiclePositionChanged(v);
|
||||
|
||||
if (v->type == VEH_Train && (IsFrontEngine(v) || IsFreeWagon(v)))
|
||||
TrainConsistChanged(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1999,19 +2001,41 @@ uint32 VehicleEnterTile(Vehicle *v, TileIndex tile, int x, int y)
|
|||
|
||||
UnitID GetFreeUnitNumber(byte type)
|
||||
{
|
||||
UnitID unit_num = 0;
|
||||
Vehicle *u;
|
||||
UnitID unit, max;
|
||||
const Vehicle *u;
|
||||
static bool *cache = NULL;
|
||||
static UnitID gmax = 0;
|
||||
|
||||
restart:
|
||||
unit_num++;
|
||||
FOR_ALL_VEHICLES(u) {
|
||||
if (u->type == type && u->owner == _current_player &&
|
||||
unit_num == u->unitnumber)
|
||||
goto restart;
|
||||
switch (type) {
|
||||
case VEH_Train: max = _patches.max_trains; break;
|
||||
case VEH_Road: max = _patches.max_roadveh; break;
|
||||
case VEH_Ship: max = _patches.max_ships; break;
|
||||
case VEH_Aircraft: max = _patches.max_aircraft; break;
|
||||
default: assert(0);
|
||||
}
|
||||
return unit_num;
|
||||
}
|
||||
|
||||
if (max > gmax) {
|
||||
gmax = max;
|
||||
free(cache);
|
||||
cache = malloc((max + 1) * sizeof(*cache));
|
||||
}
|
||||
|
||||
// Clear the cache
|
||||
memset(cache, 0, (max + 1) * sizeof(*cache));
|
||||
|
||||
// Fill the cache
|
||||
FOR_ALL_VEHICLES(u) {
|
||||
if (u->type == type && u->owner == _current_player && u->unitnumber != 0 && u->unitnumber <= max)
|
||||
cache[u->unitnumber] = true;
|
||||
}
|
||||
|
||||
// Find the first unused unit number
|
||||
for (unit = 1; unit <= max; unit++) {
|
||||
if (!cache[unit]) break;
|
||||
}
|
||||
|
||||
return unit;
|
||||
}
|
||||
|
||||
// Save and load of vehicles
|
||||
const SaveLoad _common_veh_desc[] = {
|
||||
|
|
Loading…
Reference in New Issue