changeset 5708:3dc3a5375999 draft

(svn r8185) -Codechange: Equipped Roadstops with new/delete operators and gave them proper constructors/destructors (Thanks to KUDr for a nice interactive C++ lesson)
author celestar <celestar@openttd.org>
date Wed, 17 Jan 2007 11:15:51 +0000
parents ec270c5719b1
children ae0941f46aeb
files src/oldloader.cpp src/station.cpp src/station.h src/station_cmd.cpp
diffstat 4 files changed, 122 insertions(+), 94 deletions(-) [+]
line wrap: on
line diff
--- a/src/oldloader.cpp
+++ b/src/oldloader.cpp
@@ -314,27 +314,10 @@
 		}
 
 		/* Check if there is a bus or truck station, and convert to new format */
-		if (st->bus_tile_obsolete != 0) {
-			st->bus_stops = AllocateRoadStop();
-			st->bus_stops->xy = st->bus_tile_obsolete;
-			st->bus_stops->used = true;
-			st->bus_stops->status = 3;
-			st->bus_stops->station = st->index;
-			st->bus_stops->next = NULL;
-			st->bus_stops->prev = NULL;
-			st->bus_stops->num_vehicles = 0;
-		}
+		if (st->bus_tile_obsolete != 0) st->bus_stops = new RoadStop(st->bus_tile_obsolete, st->index);
 
-		if (st->lorry_tile_obsolete != 0) {
-			st->truck_stops = AllocateRoadStop();
-			st->truck_stops->xy = st->lorry_tile_obsolete;
-			st->truck_stops->used = true;
-			st->truck_stops->status = 3;
-			st->truck_stops->station = st->index;
-			st->truck_stops->next = NULL;
-			st->truck_stops->prev = NULL;
-			st->truck_stops->num_vehicles = 0;
-		}
+		if (st->lorry_tile_obsolete != 0) st->truck_stops = new RoadStop(st->lorry_tile_obsolete, st->index);
+
 	}
 }
 
--- a/src/station.cpp
+++ b/src/station.cpp
@@ -312,3 +312,100 @@
 	return *this;
 }
 
+
+/************************************************************************/
+/*                     RoadStop implementation                          */
+/************************************************************************/
+
+/** Allocates a new RoadStop onto the pool, or recycles an unsed one
+ *  @return a pointer to the new roadstop
+ */
+void *RoadStop::operator new(size_t size)
+{
+	RoadStop *rs = AllocateRaw();
+	return rs;
+}
+
+/** Gets a RoadStop with a given index and allocates it when needed
+  * @return a pointer to the roadstop
+  */
+void *RoadStop::operator new(size_t size, int index)
+{
+	if (!AddBlockIfNeeded(&_RoadStop_pool, index)) {
+		error("RoadStops: failed loading savegame: too many RoadStops");
+	}
+
+	RoadStop *rs = GetRoadStop(index);
+	return rs;
+}
+
+void RoadStop::operator delete(void *p)
+{
+}
+
+void RoadStop::operator delete(void *p, int index)
+{
+}
+
+/** Initializes a RoadStop */
+RoadStop::RoadStop(TileIndex tile, StationID index)
+{
+	DEBUG(ms, cDebugCtorLevel,  "I+%3d at %d[0x%x]", index, tile, tile);
+	xy = tile;
+	used = true;
+	status = 3; //stop is free
+	next = NULL;
+	prev = NULL;
+	station = index;
+	num_vehicles = 0;
+}
+
+/** De-Initializes a RoadStops. This includes clearing all slots that vehicles might
+  * have and unlinks it from the linked list of road stops at the given station
+  */
+RoadStop::~RoadStop()
+{
+	Vehicle *v;
+
+	/* Clear the slot assignment of all vehicles heading for this road stop */
+	if (num_vehicles != 0) {
+		FOR_ALL_VEHICLES(v) {
+			if (v->type == VEH_Road && v->u.road.slot == this) ClearSlot(v);
+		}
+	}
+	assert(num_vehicles == 0);
+
+	if (prev != NULL) prev->next = next;
+	if (next != NULL) next->prev = prev;
+
+	used = false;
+	DEBUG(ms, cDebugCtorLevel , "I- at %3d%d[0x%x]", station, xy, xy);
+
+	xy = INVALID_TILE;
+	station = INVALID_STATION;
+}
+
+
+/** Low-level function for allocating a RoadStop on the pool */
+RoadStop *RoadStop::AllocateRaw( void )
+{
+	RoadStop *rs;
+
+	/* 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 (rs = GetRoadStop(0); rs != NULL; rs = (rs->index + 1U < GetRoadStopPoolSize()) ? GetRoadStop(rs->index + 1U) : NULL) {
+		if (!IsValidRoadStop(rs)) {
+			RoadStopID index = rs->index;
+
+			memset(rs, 0, sizeof(*rs));
+			rs->index = index;
+
+			return rs;
+		}
+	}
+
+	/* Check if we can add a block to the pool */
+	if (AddBlockToPool(&_RoadStop_pool)) return AllocateRaw();
+
+	return NULL;
+}
--- a/src/station.h
+++ b/src/station.h
@@ -53,6 +53,20 @@
 	StationID station;
 	struct RoadStop *next;
 	struct RoadStop *prev;
+
+	static const int cDebugCtorLevel = 3;
+
+	RoadStop(TileIndex tile, StationID index);
+	~RoadStop();
+
+	void *operator new (size_t size);
+	void operator delete(void *rs);
+
+	/* For loading games */
+	void *operator new (size_t size, int index);
+	void operator delete(void *rs, int index);
+
+	static RoadStop *AllocateRaw( void );
 } RoadStop;
 
 typedef struct StationSpecList {
@@ -248,14 +262,6 @@
 	return rs->used;
 }
 
-void DestroyRoadStop(RoadStop* rs);
-
-static inline void DeleteRoadStop(RoadStop *rs)
-{
-	DestroyRoadStop(rs);
-	rs->used = false;
-}
-
 #define FOR_ALL_ROADSTOPS_FROM(rs, start) for (rs = GetRoadStop(start); rs != NULL; rs = (rs->index + 1U < GetRoadStopPoolSize()) ? GetRoadStop(rs->index + 1U) : NULL) if (IsValidRoadStop(rs))
 #define FOR_ALL_ROADSTOPS(rs) FOR_ALL_ROADSTOPS_FROM(rs, 0)
 
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -77,16 +77,6 @@
 
 extern void UpdateAirplanesOnNewStation(Station *st);
 
-static void InitializeRoadStop(RoadStop *road_stop, RoadStop *previous, TileIndex tile, StationID index)
-{
-	road_stop->xy = tile;
-	road_stop->used = true;
-	road_stop->status = 3; //stop is free
-	road_stop->next = NULL;
-	road_stop->prev = previous;
-	road_stop->station = index;
-	road_stop->num_vehicles = 0;
-}
 
 RoadStop* GetPrimaryRoadStop(const Station* st, RoadStopType type)
 {
@@ -122,28 +112,6 @@
 	return num;
 }
 
-RoadStop *AllocateRoadStop(void)
-{
-	RoadStop *rs;
-
-	/* 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 (rs = GetRoadStop(0); rs != NULL; rs = (rs->index + 1U < GetRoadStopPoolSize()) ? GetRoadStop(rs->index + 1U) : NULL) {
-		if (!IsValidRoadStop(rs)) {
-			RoadStopID index = rs->index;
-
-			memset(rs, 0, sizeof(*rs));
-			rs->index = index;
-
-			return rs;
-		}
-	}
-
-	/* Check if we can add a block to the pool */
-	if (AddBlockToPool(&_RoadStop_pool)) return AllocateRoadStop();
-
-	return NULL;
-}
 
 /* Calculate the radius of the station. Basicly it is the biggest
  *  radius that is available within the station */
@@ -1393,7 +1361,7 @@
 	}
 
 	//give us a road stop in the list, and check if something went wrong
-	road_stop = AllocateRoadStop();
+	road_stop = new RoadStop(tile, INVALID_STATION);
 	if (road_stop == NULL) {
 		return_cmd_error(type ? STR_3008B_TOO_MANY_TRUCK_STOPS : STR_3008A_TOO_MANY_BUS_STOPS);
 	}
@@ -1443,7 +1411,8 @@
 		*currstop = road_stop;
 
 		//initialize an empty station
-		InitializeRoadStop(road_stop, prev, tile, st->index);
+		road_stop->prev = prev;
+		road_stop->station = st->index;
 		if (!st->facilities) st->xy = tile;
 		st->facilities |= (type) ? FACIL_TRUCK_STOP : FACIL_BUS_STOP;
 		st->owner = _current_player;
@@ -1499,7 +1468,7 @@
 			*primary_stop = (*primary_stop)->next;
 		}
 
-		DeleteRoadStop(cur_stop);
+		delete cur_stop;
 		DoClearSquare(tile);
 		st->rect.AfterRemoveTile(st, tile);
 
@@ -2356,27 +2325,6 @@
 	return 0;
 }
 
-/**
- * Cleanup a RoadStop. Make sure no vehicles try to go to this roadstop.
- */
-void DestroyRoadStop(RoadStop* rs)
-{
-	Vehicle *v;
-
-	/* Clear the slot assignment of all vehicles heading for this road stop */
-	if (rs->num_vehicles != 0) {
-		FOR_ALL_VEHICLES(v) {
-			if (v->type == VEH_Road && v->u.road.slot == rs) {
-				ClearSlot(v);
-			}
-		}
-	}
-	assert(rs->num_vehicles == 0);
-
-	if (rs->prev != NULL) rs->prev->next = rs->next;
-	if (rs->next != NULL) rs->next->prev = rs->prev;
-}
-
 
 void DeleteAllPlayerStations(void)
 {
@@ -3059,18 +3007,16 @@
 		 *  convert, if needed */
 		if (CheckSavegameVersion(6)) {
 			if (st->bus_tile_obsolete != 0) {
-				st->bus_stops = AllocateRoadStop();
+				st->bus_stops = new RoadStop(st->bus_tile_obsolete, st->index);
 				if (st->bus_stops == NULL)
 					error("Station: too many busstations in savegame");
 
-				InitializeRoadStop(st->bus_stops, NULL, st->bus_tile_obsolete, st->index);
 			}
 			if (st->lorry_tile_obsolete != 0) {
-				st->truck_stops = AllocateRoadStop();
+				st->truck_stops = new RoadStop(st->lorry_tile_obsolete, st->index);
 				if (st->truck_stops == NULL)
 					error("Station: too many truckstations in savegame");
 
-				InitializeRoadStop(st->truck_stops, NULL, st->lorry_tile_obsolete, st->index);
 			}
 		}
 	}
@@ -3094,12 +3040,8 @@
 	int index;
 
 	while ((index = SlIterateArray()) != -1) {
-		RoadStop *rs;
-
-		if (!AddBlockIfNeeded(&_RoadStop_pool, index))
-			error("RoadStops: failed loading savegame: too many RoadStops");
-
-		rs = GetRoadStop(index);
+		RoadStop *rs = new (index) RoadStop(INVALID_TILE, INVALID_STATION);
+
 		SlObject(rs, _roadstop_desc);
 	}
 }