1
0
Fork 0

Codechange: Each town cache the number of each type of industry

This allows for a quick FindTownForIndustry without having to iterate over all industries.
pull/13077/head
SamuXarick 2024-11-12 22:55:26 +00:00
parent 6faf4fa70a
commit ac5dc8ed22
6 changed files with 26 additions and 6 deletions

View File

@ -47,6 +47,7 @@ void CheckCaches()
RebuildTownCaches();
RebuildSubsidisedSourceAndDestinationCache();
RebuildTownIndustryCounts();
uint i = 0;
for (Town *t : Town::Iterate()) {

View File

@ -343,4 +343,6 @@ enum IndustryDirectoryInvalidateWindowData {
void TrimIndustryAcceptedProduced(Industry *ind);
void RebuildTownIndustryCounts();
#endif /* INDUSTRY_H */

View File

@ -201,6 +201,8 @@ Industry::~Industry()
for (Station *st : this->stations_near) {
st->RemoveIndustryToDeliver(this);
}
this->town->cache.industry_counts[this->type]--;
}
/**
@ -1428,17 +1430,15 @@ static CheckNewIndustryProc * const _check_new_industry_procs[CHECK_END] = {
* @pre \c *t != nullptr
* @post \c *t points to a town on success, and \c nullptr on failure.
*/
static CommandCost FindTownForIndustry(TileIndex tile, int type, Town **t)
static CommandCost FindTownForIndustry(TileIndex tile, IndustryType type, Town **t)
{
*t = ClosestTownFromTile(tile, UINT_MAX);
if (_settings_game.economy.multiple_industry_per_town) return CommandCost();
for (const Industry *i : Industry::Iterate()) {
if (i->type == (uint8_t)type && i->town == *t) {
*t = nullptr;
return_cmd_error(STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN);
}
if ((*t)->cache.industry_counts[type] != 0) {
*t = nullptr;
return_cmd_error(STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN);
}
return CommandCost();
@ -1812,6 +1812,7 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type,
}
i->town = t;
t->cache.industry_counts[i->type]++;
i->owner = OWNER_NONE;
uint16_t r = Random();
@ -3235,3 +3236,14 @@ void TrimIndustryAcceptedProduced(Industry *ind)
ind->produced.erase(itp.base(), std::end(ind->produced));
ind->produced.shrink_to_fit();
}
void RebuildTownIndustryCounts()
{
for (Town *t : Town::Iterate()) {
std::ranges::fill(t->cache.industry_counts, 0);
}
for (const Industry *ind : Industry::Iterate()) {
ind->town->cache.industry_counts[ind->type]++;
}
}

View File

@ -311,6 +311,8 @@ static void InitializeWindowsAndCaches()
/* Rebuild the smallmap list of owners. */
BuildOwnerLegend();
RebuildTownIndustryCounts();
}
typedef void (CDECL *SignalHandlerPointer)(int);

View File

@ -16,6 +16,7 @@
#include "subsidy_type.h"
#include "newgrf_storage.h"
#include "cargotype.h"
#include "industry_type.h"
template <typename T>
struct BuildingCounts {
@ -46,6 +47,7 @@ struct TownCache {
PartOfSubsidy part_of_subsidy; ///< Is this town a source/destination of a subsidy?
std::array<uint32_t, HZB_END> squared_town_zone_radius; ///< UpdateTownRadius updates this given the house count
BuildingCounts<uint16_t> building_counts; ///< The number of each type of building in the town
uint16_t industry_counts[NUM_INDUSTRYTYPES]; ///< The number of each type of industry in the town
auto operator<=>(const TownCache &) const = default;
};

View File

@ -2059,6 +2059,7 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32_t townnameparts, TownSi
UpdateTownGrowthRate(t);
UpdateTownMaxPass(t);
UpdateAirportsNoise();
std::ranges::fill(t->cache.industry_counts, 0);
}
/**