From 7ddae93da818577943885971b39c3a51bfac1b64 Mon Sep 17 00:00:00 2001 From: Darkvater Date: Sat, 18 Mar 2006 15:22:27 +0000 Subject: [PATCH] (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 --- train_cmd.c | 3 +++ vehicle.c | 50 +++++++++++++++++++++++++++++++++++++------------- 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/train_cmd.c b/train_cmd.c index ba350753d5..cfde2d7ea2 100644 --- a/train_cmd.c +++ b/train_cmd.c @@ -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; diff --git a/vehicle.c b/vehicle.c index 5c8a275de3..7dd32be539 100644 --- a/vehicle.c +++ b/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[] = {