From 59333131a51aded792d4123b0311a877e5772ff2 Mon Sep 17 00:00:00 2001 From: peter1138 Date: Tue, 7 Feb 2006 19:01:01 +0000 Subject: [PATCH] (svn r3572) - 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. --- vehicle.c | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/vehicle.c b/vehicle.c index 281053e744..44d07f52fe 100644 --- a/vehicle.c +++ b/vehicle.c @@ -2004,19 +2004,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[] = {