(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
--- a/train_cmd.c Sat Mar 18 15:19:30 2006 +0000
+++ b/train_cmd.c Sat Mar 18 15:22:27 2006 +0000
@@ -93,6 +93,9 @@
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;
--- a/vehicle.c Sat Mar 18 15:19:30 2006 +0000
+++ b/vehicle.c Sat Mar 18 15:22:27 2006 +0000
@@ -218,6 +218,11 @@
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 @@
v->left_coord = INVALID_COORD;
VehiclePositionChanged(v);
-
- if (v->type == VEH_Train && (IsFrontEngine(v) || IsFreeWagon(v)))
- TrainConsistChanged(v);
}
}
}
@@ -1999,20 +2001,42 @@
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++;
+ 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);
+ }
+
+ 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 &&
- unit_num == u->unitnumber)
- goto restart;
+ if (u->type == type && u->owner == _current_player && u->unitnumber != 0 && u->unitnumber <= max)
+ cache[u->unitnumber] = true;
}
- return unit_num;
+
+ // 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[] = {
SLE_VAR(Vehicle,subtype, SLE_UINT8),