summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpeter1138 <peter1138@openttd.org>2006-02-07 19:01:01 +0000
committerpeter1138 <peter1138@openttd.org>2006-02-07 19:01:01 +0000
commitcfdce5213e79a63cd6c66d16d9a7315c6718f7f7 (patch)
tree20fcdb385a32fca87f8b520ef635604d2b76d473
parent6bc6c34b5ac3217e6306b734d58da48634b91f64 (diff)
downloadopenttd-cfdce5213e79a63cd6c66d16d9a7315c6718f7f7.tar.xz
(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.
-rw-r--r--vehicle.c40
1 files changed, 31 insertions, 9 deletions
diff --git a/vehicle.c b/vehicle.c
index 281053e74..44d07f52f 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;
+
+ 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));
-restart:
- unit_num++;
+ // 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;
+ }
+
+ // Find the first unused unit number
+ for (unit = 1; unit <= max; unit++) {
+ if (!cache[unit]) break;
}
- return unit_num;
-}
+ return unit;
+}
// Save and load of vehicles
const SaveLoad _common_veh_desc[] = {