1
0
Fork 0

(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 trunk
release/0.4.5
Darkvater 2006-03-18 15:22:27 +00:00
parent f75365fcf4
commit 7ddae93da8
2 changed files with 40 additions and 13 deletions

View File

@ -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;

View File

@ -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[] = {