From e16b982b6abf128a1c9e6dbce9cd6a3adc611236 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Tue, 12 Mar 2024 17:28:45 +0000 Subject: [PATCH] Codechange: Use iteration when dealing with all HouseSpecs. --- src/industry_gui.cpp | 18 ++++++++---------- src/newgrf.cpp | 20 +++++++++----------- src/newgrf_house.cpp | 9 +++++++++ src/town_cmd.cpp | 38 +++++++++++++++++--------------------- 4 files changed, 43 insertions(+), 42 deletions(-) diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index fcb3b247e3..d4bbf88497 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.cpp @@ -2504,12 +2504,11 @@ struct CargoesRow { } else { /* Houses only display what is demanded. */ for (uint i = 0; i < cargo_fld->u.cargo.num_cargoes; i++) { - for (uint h = 0; h < NUM_HOUSES; h++) { - HouseSpec *hs = HouseSpec::Get(h); - if (!hs->enabled) continue; + for (const auto &hs : HouseSpec::Specs()) { + if (!hs.enabled) continue; - for (uint j = 0; j < lengthof(hs->accepts_cargo); j++) { - if (hs->cargo_acceptance[j] > 0 && cargo_fld->u.cargo.vertical_cargoes[i] == hs->accepts_cargo[j]) { + for (uint j = 0; j < lengthof(hs.accepts_cargo); j++) { + if (hs.cargo_acceptance[j] > 0 && cargo_fld->u.cargo.vertical_cargoes[i] == hs.accepts_cargo[j]) { cargo_fld->ConnectCargo(cargo_fld->u.cargo.vertical_cargoes[i], false); goto next_cargo; } @@ -2724,12 +2723,11 @@ struct IndustryCargoesWindow : public Window { for (uint i = 0; i < length; i++) { if (!IsValidCargoID(cargoes[i])) continue; - for (uint h = 0; h < NUM_HOUSES; h++) { - HouseSpec *hs = HouseSpec::Get(h); - if (!hs->enabled || !(hs->building_availability & climate_mask)) continue; + for (const auto &hs : HouseSpec::Specs()) { + if (!hs.enabled || !(hs.building_availability & climate_mask)) continue; - for (uint j = 0; j < lengthof(hs->accepts_cargo); j++) { - if (hs->cargo_acceptance[j] > 0 && cargoes[i] == hs->accepts_cargo[j]) return true; + for (uint j = 0; j < lengthof(hs.accepts_cargo); j++) { + if (hs.cargo_acceptance[j] > 0 && cargoes[i] == hs.accepts_cargo[j]) return true; } } } diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 20ac05431a..021608b843 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -9337,20 +9337,18 @@ static void EnsureEarlyHouse(HouseZones bitmask) { TimerGameCalendar::Year min_year = CalendarTime::MAX_YEAR; - for (int i = 0; i < NUM_HOUSES; i++) { - HouseSpec *hs = HouseSpec::Get(i); - if (hs == nullptr || !hs->enabled) continue; - if ((hs->building_availability & bitmask) != bitmask) continue; - if (hs->min_year < min_year) min_year = hs->min_year; + for (const auto &hs : HouseSpec::Specs()) { + if (!hs.enabled) continue; + if ((hs.building_availability & bitmask) != bitmask) continue; + if (hs.min_year < min_year) min_year = hs.min_year; } if (min_year == 0) return; - for (int i = 0; i < NUM_HOUSES; i++) { - HouseSpec *hs = HouseSpec::Get(i); - if (hs == nullptr || !hs->enabled) continue; - if ((hs->building_availability & bitmask) != bitmask) continue; - if (hs->min_year == min_year) hs->min_year = 0; + for (auto &hs : HouseSpec::Specs()) { + if (!hs.enabled) continue; + if ((hs.building_availability & bitmask) != bitmask) continue; + if (hs.min_year == min_year) hs.min_year = 0; } } @@ -9390,7 +9388,7 @@ static void FinaliseHouseArray() } } - for (size_t i = 0; i < NUM_HOUSES; i++) { + for (size_t i = 0; i < HouseSpec::Specs().size(); i++) { HouseSpec *hs = HouseSpec::Get(i); const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : nullptr); const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : nullptr); diff --git a/src/newgrf_house.cpp b/src/newgrf_house.cpp index ac18c4fbe2..e31c49964a 100644 --- a/src/newgrf_house.cpp +++ b/src/newgrf_house.cpp @@ -52,6 +52,15 @@ std::vector &HouseSpec::Specs() return _house_specs; } +/** + * Gets the index of this spec. + * @return The index. + */ +HouseID HouseSpec::Index() const +{ + return static_cast(this - _house_specs.data()); +} + /** * Get the spec for a house ID. * @param house_id The ID of the house. diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index b85d077d92..c44cf48b04 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -2658,31 +2658,28 @@ static bool BuildTownHouse(Town *t, TileIndex tile) /* bits 0-4 are used * bits 11-15 are used * bits 5-10 are not used. */ - HouseID houses[NUM_HOUSES]; - uint num = 0; - uint probs[NUM_HOUSES]; + static std::vector> probs; + probs.clear(); + uint probability_max = 0; /* Generate a list of all possible houses that can be built. */ - for (uint i = 0; i < NUM_HOUSES; i++) { - const HouseSpec *hs = HouseSpec::Get(i); - + for (const auto &hs : HouseSpec::Specs()) { /* Verify that the candidate house spec matches the current tile status */ - if ((~hs->building_availability & bitmask) != 0 || !hs->enabled || hs->grf_prop.override != INVALID_HOUSE_ID) continue; + if ((~hs.building_availability & bitmask) != 0 || !hs.enabled || hs.grf_prop.override != INVALID_HOUSE_ID) continue; /* Don't let these counters overflow. Global counters are 32bit, there will never be that many houses. */ - if (hs->class_id != HOUSE_NO_CLASS) { + if (hs.class_id != HOUSE_NO_CLASS) { /* id_count is always <= class_count, so it doesn't need to be checked */ - if (t->cache.building_counts.class_count[hs->class_id] == UINT16_MAX) continue; + if (t->cache.building_counts.class_count[hs.class_id] == UINT16_MAX) continue; } else { /* If the house has no class, check id_count instead */ - if (t->cache.building_counts.id_count[i] == UINT16_MAX) continue; + if (t->cache.building_counts.id_count[hs.Index()] == UINT16_MAX) continue; } - uint cur_prob = hs->probability; + uint cur_prob = hs.probability; probability_max += cur_prob; - probs[num] = cur_prob; - houses[num++] = (HouseID)i; + probs.emplace_back(std::make_pair(hs.Index(), cur_prob)); } TileIndex baseTile = tile; @@ -2697,18 +2694,17 @@ static bool BuildTownHouse(Town *t, TileIndex tile) uint r = RandomRange(probability_max); uint i; - for (i = 0; i < num; i++) { - if (probs[i] > r) break; - r -= probs[i]; + for (i = 0; i < probs.size(); i++) { + if (probs[i].second > r) break; + r -= probs[i].second; } - HouseID house = houses[i]; - probability_max -= probs[i]; + HouseID house = probs[i].first; + probability_max -= probs[i].second; /* remove tested house from the set */ - num--; - houses[i] = houses[num]; - probs[i] = probs[num]; + probs[i] = probs.back(); + probs.pop_back(); const HouseSpec *hs = HouseSpec::Get(house);