mirror of
https://github.com/OpenTTD/OpenTTD
synced 2026-01-19 10:22:39 +01:00
Codechange: Speed up industry generation using industry-type checks. (#13094)
Store a list of industries per industry type. This allows industry generation checks which only consider a specific industry type to check a reduced set of industries, leading to a potential performance increase. This also removes the need to track industry type counts as well.
This commit is contained in:
@@ -63,7 +63,7 @@ void BuildOilRig(TileIndex tile);
|
||||
static uint8_t _industry_sound_ctr;
|
||||
static TileIndex _industry_sound_tile;
|
||||
|
||||
uint16_t Industry::counts[NUM_INDUSTRYTYPES];
|
||||
std::array<std::vector<IndustryID>, NUM_INDUSTRYTYPES> Industry::industries;
|
||||
|
||||
IndustrySpec _industry_specs[NUM_INDUSTRYTYPES];
|
||||
IndustryTileSpec _industry_tile_specs[NUM_INDUSTRYTILES];
|
||||
@@ -189,7 +189,9 @@ Industry::~Industry()
|
||||
/* Clear the persistent storage. */
|
||||
delete this->psa;
|
||||
|
||||
DecIndustryTypeCount(this->type);
|
||||
auto &industries = Industry::industries[type];
|
||||
auto it = std::ranges::lower_bound(industries, this->index);
|
||||
industries.erase(it);
|
||||
|
||||
DeleteIndustryNews(this->index);
|
||||
CloseWindowById(WC_INDUSTRY_VIEW, this->index);
|
||||
@@ -1434,8 +1436,8 @@ static CommandCost FindTownForIndustry(TileIndex tile, IndustryType type, Town *
|
||||
|
||||
if (_settings_game.economy.multiple_industry_per_town) return CommandCost();
|
||||
|
||||
for (const Industry *i : Industry::Iterate()) {
|
||||
if (i->type == type && i->town == *t) {
|
||||
for (const IndustryID &industry : Industry::industries[type]) {
|
||||
if (Industry::Get(industry)->town == *t) {
|
||||
*t = nullptr;
|
||||
return_cmd_error(STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN);
|
||||
}
|
||||
@@ -1693,35 +1695,13 @@ static CommandCost CheckIfFarEnoughFromConflictingIndustry(TileIndex tile, Indus
|
||||
{
|
||||
const IndustrySpec *indspec = GetIndustrySpec(type);
|
||||
|
||||
/* On a large map with many industries, it may be faster to check an area. */
|
||||
static const int dmax = 14;
|
||||
if (Industry::GetNumItems() > static_cast<size_t>(dmax * dmax * 2)) {
|
||||
const Industry *i = nullptr;
|
||||
TileArea tile_area = TileArea(tile, 1, 1).Expand(dmax);
|
||||
for (TileIndex atile : tile_area) {
|
||||
if (GetTileType(atile) == MP_INDUSTRY) {
|
||||
const Industry *i2 = Industry::GetByTile(atile);
|
||||
if (i == i2) continue;
|
||||
i = i2;
|
||||
if (DistanceMax(tile, i->location.tile) > (uint)dmax) continue;
|
||||
if (i->type == indspec->conflicting[0] ||
|
||||
i->type == indspec->conflicting[1] ||
|
||||
i->type == indspec->conflicting[2]) {
|
||||
return_cmd_error(STR_ERROR_INDUSTRY_TOO_CLOSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
return CommandCost();
|
||||
}
|
||||
for (IndustryType conflicting_type : indspec->conflicting) {
|
||||
if (conflicting_type == IT_INVALID) continue;
|
||||
|
||||
for (const Industry *i : Industry::Iterate()) {
|
||||
/* Within 14 tiles from another industry is considered close */
|
||||
if (DistanceMax(tile, i->location.tile) > 14) continue;
|
||||
for (const IndustryID &industry : Industry::industries[conflicting_type]) {
|
||||
/* Within 14 tiles from another industry is considered close */
|
||||
if (DistanceMax(tile, Industry::Get(industry)->location.tile) > 14) continue;
|
||||
|
||||
/* check if there are any conflicting industry types around */
|
||||
if (i->type == indspec->conflicting[0] ||
|
||||
i->type == indspec->conflicting[1] ||
|
||||
i->type == indspec->conflicting[2]) {
|
||||
return_cmd_error(STR_ERROR_INDUSTRY_TOO_CLOSE);
|
||||
}
|
||||
}
|
||||
@@ -1787,7 +1767,10 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type,
|
||||
|
||||
i->location = TileArea(tile, 1, 1);
|
||||
i->type = type;
|
||||
Industry::IncIndustryTypeCount(type);
|
||||
|
||||
auto &industries = Industry::industries[type];
|
||||
auto it = std::ranges::lower_bound(industries, i->index);
|
||||
it = industries.emplace(it, i->index);
|
||||
|
||||
for (size_t index = 0; index < std::size(indspec->produced_cargo); ++index) {
|
||||
if (!IsValidCargoID(indspec->produced_cargo[index])) break;
|
||||
@@ -2413,8 +2396,10 @@ static void PlaceInitialIndustry(IndustryType type, bool try_hard)
|
||||
*/
|
||||
static uint GetCurrentTotalNumberOfIndustries()
|
||||
{
|
||||
int total = 0;
|
||||
for (IndustryType it = 0; it < NUM_INDUSTRYTYPES; it++) total += Industry::GetIndustryTypeCount(it);
|
||||
uint total = 0;
|
||||
for (const auto &industries : Industry::industries) {
|
||||
total += static_cast<uint16_t>(std::size(industries));
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
@@ -3090,7 +3075,7 @@ static IntervalTimer<TimerGameEconomy> _economy_industries_monthly({TimerGameEco
|
||||
|
||||
void InitializeIndustries()
|
||||
{
|
||||
Industry::ResetIndustryCounts();
|
||||
Industry::industries = {};
|
||||
_industry_sound_tile = 0;
|
||||
|
||||
_industry_builder.Reset();
|
||||
|
||||
Reference in New Issue
Block a user