summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/oldpool.h39
-rw-r--r--src/station.cpp15
-rw-r--r--src/station.h10
-rw-r--r--src/station_cmd.cpp35
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)
/**