diff --git a/src/ai/default/default.cpp b/src/ai/default/default.cpp --- a/src/ai/default/default.cpp +++ b/src/ai/default/default.cpp @@ -462,7 +462,7 @@ static Town *AiFindRandomTown() static Industry *AiFindRandomIndustry() { int num = RandomRange(GetMaxIndustryIndex()); - if (IsValidIndustry(GetIndustry(num))) return GetIndustry(num); + if (IsValidIndustryID(num)) return GetIndustry(num); return NULL; } diff --git a/src/industry.h b/src/industry.h --- a/src/industry.h +++ b/src/industry.h @@ -86,10 +86,13 @@ enum IndustyBehaviour { DECLARE_ENUM_AS_BIT_SET(IndustyBehaviour); +struct Industry; +DECLARE_OLD_POOL(Industry, Industry, 3, 8000) + /** * Defines the internal data of a functionnal industry */ -struct Industry { +struct Industry : PoolItem { TileIndex xy; ///< coordinates of the primary tile the industry is built one byte width; byte height; @@ -111,12 +114,15 @@ struct Industry { Year last_prod_year; ///< last year of production byte was_cargo_delivered; ///< flag that indicate this has been the closest industry chosen for cargo delivery by a station. see DeliverGoodsToIndustry - IndustryID index; ///< index of the industry in the pool of industries - OwnerByte founder; ///< Founder of the industry Date construction_date; ///< Date of the construction of the industry uint8 construction_type; ///< Way the industry was constructed (@see IndustryConstructionType) Date last_cargo_accepted_at; ///< Last day cargo was accepted by this industry + + Industry(TileIndex tile = 0) : xy(tile) {} + ~Industry(); + + bool IsValid() const { return this->xy != 0; } }; struct IndustryTileTable { @@ -216,18 +222,6 @@ extern IndustryTileSpec _industry_tile_s /* smallmap_gui.cpp */ void BuildIndustriesLegend(); -DECLARE_OLD_POOL(Industry, Industry, 3, 8000) - -/** - * Check if an Industry really exists. - * @param industry to check - * @return true if position is a valid one - */ -static inline bool IsValidIndustry(const Industry *industry) -{ - return industry->xy != 0; -} - /** * Check if an Industry exists whithin the pool of industries * @param index of the desired industry @@ -235,7 +229,7 @@ static inline bool IsValidIndustry(const */ static inline bool IsValidIndustryID(IndustryID index) { - return index < GetIndustryPoolSize() && IsValidIndustry(GetIndustry(index)); + return index < GetIndustryPoolSize() && GetIndustry(index)->IsValid(); } @@ -318,15 +312,7 @@ static inline Industry *GetRandomIndustr return GetIndustry(index); } -void DestroyIndustry(Industry *i); - -static inline void DeleteIndustry(Industry *i) -{ - DestroyIndustry(i); - i->xy = 0; -} - -#define FOR_ALL_INDUSTRIES_FROM(i, start) for (i = GetIndustry(start); i != NULL; i = (i->index + 1U < GetIndustryPoolSize()) ? GetIndustry(i->index + 1U) : NULL) if (IsValidIndustry(i)) +#define FOR_ALL_INDUSTRIES_FROM(i, start) for (i = GetIndustry(start); i != NULL; i = (i->index + 1U < GetIndustryPoolSize()) ? GetIndustry(i->index + 1U) : NULL) if (i->IsValid()) #define FOR_ALL_INDUSTRIES(i) FOR_ALL_INDUSTRIES_FROM(i, 0) extern const Industry **_industry_sort; diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -35,6 +35,7 @@ #include "newgrf_industries.h" #include "newgrf_industrytiles.h" #include "newgrf_callbacks.h" +#include "misc/autoptr.hpp" void ShowIndustryViewWindow(int industry); void BuildOilRig(TileIndex tile); @@ -75,19 +76,7 @@ void ResetIndustryCreationProbility(Indu _industry_specs[type].appear_creation[_opt.landscape] = 0; } -/** - * Called if a new block is added to the industry-pool - */ -static void IndustryPoolNewBlock(uint start_item) -{ - Industry *i; - - /* We don't use FOR_ALL here, because FOR_ALL skips invalid items. - * TODO - This is just a temporary stage, this will be removed. */ - for (i = GetIndustry(start_item); i != NULL; i = (i->index + 1U < GetIndustryPoolSize()) ? GetIndustry(i->index + 1U) : NULL) i->index = start_item++; -} - -DEFINE_OLD_POOL(Industry, Industry, IndustryPoolNewBlock, NULL) +DEFINE_OLD_POOL_GENERIC(Industry, Industry) /** * Retrieve the type for this industry. Although it is accessed by a tile, @@ -102,7 +91,7 @@ IndustryType GetIndustryType(TileIndex t assert(IsTileType(tile, MP_INDUSTRY)); const Industry *ind = GetIndustryByTile(tile); - return IsValidIndustry(ind) ? ind->type : (IndustryType)IT_INVALID; + return ind->IsValid() ? ind->type : (IndustryType)IT_INVALID; } /** @@ -139,35 +128,43 @@ const IndustryTileSpec *GetIndustryTileS return its; } -void DestroyIndustry(Industry *i) +Industry::~Industry() { - BEGIN_TILE_LOOP(tile_cur, i->width, i->height, i->xy); + /* Industry can also be destroyed when not fully initialized. + * This means that we do not have to clear tiles either. */ + if (this->width == 0) { + this->xy = 0; + return; + } + + BEGIN_TILE_LOOP(tile_cur, this->width, this->height, this->xy); if (IsTileType(tile_cur, MP_INDUSTRY)) { - if (GetIndustryIndex(tile_cur) == i->index) { + if (GetIndustryIndex(tile_cur) == this->index) { DoClearSquare(tile_cur); } } else if (IsTileType(tile_cur, MP_STATION) && IsOilRig(tile_cur)) { DeleteOilRig(tile_cur); } - END_TILE_LOOP(tile_cur, i->width, i->height, i->xy); + END_TILE_LOOP(tile_cur, this->width, this->height, this->xy); - if (GetIndustrySpec(i->type)->behaviour & INDUSTRYBEH_PLANT_FIELDS) { + if (GetIndustrySpec(this->type)->behaviour & INDUSTRYBEH_PLANT_FIELDS) { /* Remove the farmland and convert it to regular tiles over time. */ - BEGIN_TILE_LOOP(tile_cur, 42, 42, i->xy - TileDiffXY(21, 21)) { + BEGIN_TILE_LOOP(tile_cur, 42, 42, this->xy - TileDiffXY(21, 21)) { tile_cur = TILE_MASK(tile_cur); if (IsTileType(tile_cur, MP_CLEAR) && IsClearGround(tile_cur, CLEAR_FIELDS) && - GetIndustryIndexOfField(tile_cur) == i->index) { + GetIndustryIndexOfField(tile_cur) == this->index) { SetIndustryIndexOfField(tile_cur, INVALID_INDUSTRY); } - } END_TILE_LOOP(tile_cur, 42, 42, i->xy - TileDiff(21, 21)) + } END_TILE_LOOP(tile_cur, 42, 42, this->xy - TileDiff(21, 21)) } _industry_sort_dirty = true; - DecIndustryTypeCount(i->type); + DecIndustryTypeCount(this->type); - DeleteSubsidyWithIndustry(i->index); - DeleteWindowById(WC_INDUSTRY_VIEW, i->index); + DeleteSubsidyWithIndustry(this->index); + DeleteWindowById(WC_INDUSTRY_VIEW, this->index); InvalidateWindow(WC_INDUSTRY_DIRECTORY, 0); + this->xy = 0; } static void IndustryDrawSugarMine(const TileInfo *ti) @@ -393,7 +390,7 @@ static CommandCost ClearTile_Industry(Ti return_cmd_error(STR_4800_IN_THE_WAY); } - if (flags & DC_EXEC) DeleteIndustry(i); + if (flags & DC_EXEC) delete i; return CommandCost(); } @@ -1397,27 +1394,6 @@ static bool CheckIfTooCloseToIndustry(Ti return true; } -static Industry *AllocateIndustry() -{ - Industry *i; - - /* We don't use FOR_ALL here, because FOR_ALL skips invalid items. - * TODO - This is just a temporary stage, this will be removed. */ - for (i = GetIndustry(0); i != NULL; i = (i->index + 1U < GetIndustryPoolSize()) ? GetIndustry(i->index + 1U) : NULL) { - IndustryID index = i->index; - - if (IsValidIndustry(i)) continue; - - memset(i, 0, sizeof(*i)); - i->index = index; - - return i; - } - - /* Check if we can add a block to the pool */ - return AddBlockToPool(&_Industry_pool) ? AllocateIndustry() : NULL; -} - static void DoCreateNewIndustry(Industry *i, TileIndex tile, int type, const IndustryTileTable *it, const Town *t, Owner owner) { const IndustrySpec *indspec = GetIndustrySpec(type); @@ -1530,12 +1506,14 @@ static Industry *CreateNewIndustryHelper if (!CheckIfIndustryIsAllowed(tile, type, t)) return NULL; if (!CheckSuitableIndustryPos(tile)) return NULL; - Industry *i = AllocateIndustry(); + Industry *i = new Industry(tile); if (i == NULL) return NULL; + AutoPtrT i_auto_delete = i; if (flags & DC_EXEC) { if (!custom_shape_check) CheckIfCanLevelIndustryPlatform(tile, DC_EXEC, it, type); DoCreateNewIndustry(i, tile, type, it, t, OWNER_NONE); + i_auto_delete.Detach(); } return i; @@ -1808,7 +1786,7 @@ static void UpdateIndustryStatistics(Ind InvalidateWindow(WC_INDUSTRY_VIEW, i->index); if (i->prod_level == 0) { - DeleteIndustry(i); + delete i; } else if (_patches.smooth_economy) { ExtChangeIndustryProduction(i); } @@ -2093,12 +2071,7 @@ static void Load_INDY() ResetIndustryCounts(); while ((index = SlIterateArray()) != -1) { - Industry *i; - - if (!AddBlockIfNeeded(&_Industry_pool, index)) - error("Industries: failed loading savegame: too many industries"); - - i = GetIndustry(index); + Industry *i = new (index) Industry(); SlObject(i, _industry_desc); IncIndustryTypeCount(i->type); } diff --git a/src/oldloader.cpp b/src/oldloader.cpp --- a/src/oldloader.cpp +++ b/src/oldloader.cpp @@ -715,7 +715,7 @@ static bool LoadOldIndustry(LoadgameStat i = GetIndustry(num); if (!LoadChunk(ls, i, industry_chunk)) return false; - if (IsValidIndustry(i)) { + if (i->IsValid()) { i->town = GetTown(REMAP_TOWN_IDX(_old_town_index)); } diff --git a/src/strings.cpp b/src/strings.cpp --- a/src/strings.cpp +++ b/src/strings.cpp @@ -656,7 +656,7 @@ static char* FormatString(char* buff, co int64 args[2]; /* industry not valid anymore? */ - if (!IsValidIndustry(i)) break; + if (!i->IsValid()) break; /* First print the town name and the industry type name * The string STR_INDUSTRY_PATTERN controls the formatting */ diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -61,7 +61,7 @@ Town::~Town() _total_towns--; /* Delete all industries belonging to the town */ - FOR_ALL_INDUSTRIES(i) if (i->town == this) DeleteIndustry(i); + FOR_ALL_INDUSTRIES(i) if (i->town == this) delete i; /* Go through all tiles and delete those belonging to the town */ for (TileIndex tile = 0; tile < MapSize(); ++tile) {