diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/oldpool.h | 39 | ||||
-rw-r--r-- | src/station.cpp | 15 | ||||
-rw-r--r-- | src/station.h | 10 | ||||
-rw-r--r-- | src/station_cmd.cpp | 35 |
4 files changed, 59 insertions, 40 deletions
diff --git a/src/oldpool.h b/src/oldpool.h index 3813e8f1c..80e121cb6 100644 --- a/src/oldpool.h +++ b/src/oldpool.h @@ -92,6 +92,40 @@ static inline bool AddBlockToPool(OldMemoryPoolBase *array) { return array->AddB static inline bool AddBlockIfNeeded(OldMemoryPoolBase *array, uint index) { return array->AddBlockIfNeeded(index); } +/** + * Generic function to initialize a new block in a pool. + * @param start_item the first item that needs to be initialized + */ +template <typename T, OldMemoryPool<T> *Tpool> +static void PoolNewBlock(uint start_item) +{ + /* 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 (T *t = Tpool->Get(start_item); t != NULL; t = (t->index + 1U < Tpool->GetSize()) ? Tpool->Get(t->index + 1U) : NULL) { + t->index = start_item++; + t->PreInit(); + } +} + +/** + * Generic function to free a new block in a pool. + * This function uses QuickFree that is intended to only free memory that would be lost if the pool is freed. + * @param start_item the first item that needs to be cleaned + * @param end_item the last item that needs to be cleaned + */ +template <typename T, OldMemoryPool<T> *Tpool> +static void PoolCleanBlock(uint start_item, uint end_item) +{ + for (uint i = start_item; i <= end_item; i++) { + T *t = Tpool->Get(i); + if (t->IsValid()) { + t->QuickFree(); + } + } +} + + + #define OLD_POOL_ENUM(name, type, block_size_bits, max_blocks) \ enum { \ name##_POOL_BLOCK_SIZE_BITS = block_size_bits, \ @@ -115,6 +149,11 @@ static inline bool AddBlockIfNeeded(OldMemoryPoolBase *array, uint index) { retu #name, name##_POOL_MAX_BLOCKS, name##_POOL_BLOCK_SIZE_BITS, sizeof(type), \ new_block_proc, clean_block_proc); +#define DEFINE_OLD_POOL_GENERIC(name, type) \ + OldMemoryPool<type> _##name##_pool( \ + #name, name##_POOL_MAX_BLOCKS, name##_POOL_BLOCK_SIZE_BITS, sizeof(type), \ + PoolNewBlock<type, &_##name##_pool>, PoolCleanBlock<type, &_##name##_pool>); + #define STATIC_OLD_POOL(name, type, block_size_bits, max_blocks, new_block_proc, clean_block_proc) \ OLD_POOL_ENUM(name, type, block_size_bits, max_blocks) \ diff --git a/src/station.cpp b/src/station.cpp index 02f165b6f..0f7db16ff 100644 --- a/src/station.cpp +++ b/src/station.cpp @@ -64,7 +64,6 @@ Station::~Station() { DEBUG(station, cDebugCtorLevel, "I-%3d", index); - DeleteName(string_id); MarkDirty(); RebuildStationLists(); InvalidateWindowClasses(WC_STATION_LIST); @@ -77,21 +76,28 @@ Station::~Station() /* Subsidies need removal as well */ DeleteSubsidyWithStation(index); - free(speclist); xy = 0; for (CargoID c = 0; c < NUM_CARGO; c++) { goods[c].cargo.Truncate(0); } + + this->QuickFree(); } -void* Station::operator new(size_t size) +void Station::QuickFree() +{ + DeleteName(this->string_id); + free(this->speclist); +} + +void *Station::operator new(size_t size) { Station *st = AllocateRaw(); return st; } -void* Station::operator new(size_t size, int st_idx) +void *Station::operator new(size_t size, int st_idx) { if (!AddBlockIfNeeded(&_Station_pool, st_idx)) error("Stations: failed loading savegame: too many stations"); @@ -480,7 +486,6 @@ RoadStop::~RoadStop() xy = INVALID_TILE; } - /** Low-level function for allocating a RoadStop on the pool */ RoadStop *RoadStop::AllocateRaw() { diff --git a/src/station.h b/src/station.h index c447f2ab7..e35ce7d3a 100644 --- a/src/station.h +++ b/src/station.h @@ -55,6 +55,9 @@ struct RoadStop { RoadStop(TileIndex tile); ~RoadStop(); + void PreInit() { this->xy = INVALID_TILE; } + void QuickFree() {} + void *operator new (size_t size); void operator delete(void *rs); @@ -164,12 +167,15 @@ struct Station { Station(TileIndex tile = 0); ~Station(); + void PreInit() {} + void QuickFree(); + /* normal new/delete operators. Used when building/removing station */ - void* operator new (size_t size); + void *operator new (size_t size); void operator delete(void *p); /* new/delete operators accepting station index. Used when loading station from savegame. */ - void* operator new (size_t size, int st_idx); + void *operator new (size_t size, int st_idx); void operator delete(void *p, int st_idx); void AddFacility(byte new_facility_bit, TileIndex facil_xy); diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 160435772..b5ca877f1 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -43,39 +43,8 @@ #include "cargotype.h" #include "strings.h" -/** - * Called if a new block is added to the station-pool - */ -static void StationPoolNewBlock(uint start_item) -{ - /* 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 (Station *st = GetStation(start_item); st != NULL; st = (st->index + 1U < GetStationPoolSize()) ? GetStation(st->index + 1U) : NULL) st->index = start_item++; -} - -static void StationPoolCleanBlock(uint start_item, uint end_item) -{ - for (uint i = start_item; i <= end_item; i++) { - Station *st = GetStation(i); - if (st->IsValid()) st->~Station(); - } -} - -/** - * Called if a new block is added to the roadstop-pool - */ -static void RoadStopPoolNewBlock(uint start_item) -{ - /* 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 (RoadStop *rs = GetRoadStop(start_item); rs != NULL; rs = (rs->index + 1U < GetRoadStopPoolSize()) ? GetRoadStop(rs->index + 1U) : NULL) { - rs->xy = INVALID_TILE; - rs->index = start_item++; - } -} - -DEFINE_OLD_POOL(Station, Station, StationPoolNewBlock, StationPoolCleanBlock) -DEFINE_OLD_POOL(RoadStop, RoadStop, RoadStopPoolNewBlock, NULL) +DEFINE_OLD_POOL_GENERIC(Station, Station) +DEFINE_OLD_POOL_GENERIC(RoadStop, RoadStop) /** |