(svn r10745) -Codechange: generalize the pool cleanup/initialize functions for stations (in such a manner that they can be used for other pools too).
authorrubidium
Wed, 01 Aug 2007 23:49:06 +0000
changeset 7376 066596e64cd5
parent 7375 961ab798c4b6
child 7377 b6479e048c6e
(svn r10745) -Codechange: generalize the pool cleanup/initialize functions for stations (in such a manner that they can be used for other pools too).
src/oldpool.h
src/station.cpp
src/station.h
src/station_cmd.cpp
--- a/src/oldpool.h	Wed Aug 01 22:10:54 2007 +0000
+++ b/src/oldpool.h	Wed Aug 01 23:49:06 2007 +0000
@@ -92,6 +92,40 @@
 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 @@
 		#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) \
--- a/src/station.cpp	Wed Aug 01 22:10:54 2007 +0000
+++ b/src/station.cpp	Wed Aug 01 23:49:06 2007 +0000
@@ -64,7 +64,6 @@
 {
 	DEBUG(station, cDebugCtorLevel, "I-%3d", index);
 
-	DeleteName(string_id);
 	MarkDirty();
 	RebuildStationLists();
 	InvalidateWindowClasses(WC_STATION_LIST);
@@ -77,21 +76,28 @@
 	/* 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 @@
 	xy = INVALID_TILE;
 }
 
-
 /** Low-level function for allocating a RoadStop on the pool */
 RoadStop *RoadStop::AllocateRaw()
 {
--- a/src/station.h	Wed Aug 01 22:10:54 2007 +0000
+++ b/src/station.h	Wed Aug 01 23:49:06 2007 +0000
@@ -55,6 +55,9 @@
 	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 @@
 	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);
--- a/src/station_cmd.cpp	Wed Aug 01 22:10:54 2007 +0000
+++ b/src/station_cmd.cpp	Wed Aug 01 23:49:06 2007 +0000
@@ -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)
 
 
 /**