changeset 11902:5b2be5f84fe8 draft

(svn r16302) -Codechange: remove Vehicle::AllocateList
author smatz <smatz@openttd.org>
date Wed, 13 May 2009 21:38:23 +0000
parents ad8901f29746
children c40e241e65ba
files src/articulated_vehicles.cpp src/articulated_vehicles.h src/roadveh_cmd.cpp src/train_cmd.cpp src/vehicle.cpp src/vehicle_base.h
diffstat 6 files changed, 47 insertions(+), 94 deletions(-) [+]
line wrap: on
line diff
--- a/src/articulated_vehicles.cpp
+++ b/src/articulated_vehicles.cpp
@@ -283,10 +283,10 @@
 	}
 }
 
-void AddArticulatedParts(Vehicle **vl, VehicleType type)
+void AddArticulatedParts(Vehicle *first, VehicleType type)
 {
-	const Vehicle *v = vl[0];
-	Vehicle *u = vl[0];
+	const Vehicle *v = first;
+	Vehicle *u = first;
 
 	if (!HasBit(EngInfo(v->engine_type)->callbackmask, CBM_VEHICLE_ARTIC_ENGINE)) return;
 
@@ -294,23 +294,20 @@
 		uint16 callback = GetVehicleCallback(CBID_VEHICLE_ARTIC_ENGINE, i, 0, v->engine_type, v);
 		if (callback == CALLBACK_FAILED || GB(callback, 0, 8) == 0xFF) return;
 
-		/* Attempt to use pre-allocated vehicles until they run out. This can happen
-		 * if the callback returns different values depending on the cargo type. */
-		u->SetNext(vl[i]);
-		if (u->Next() == NULL) return;
-
-		Vehicle *previous = u;
-		u = u->Next();
+		/* In the (very rare) case the GRF reported wrong number of articulated parts
+		 * and we run out of available vehicles, bail out. */
+		if (!Vehicle::CanAllocateItem()) return;
 
 		EngineID engine_type = GetNewEngineID(GetEngineGRF(v->engine_type), type, GB(callback, 0, 7));
 		bool flip_image = HasBit(callback, 7);
 
+		Vehicle *previous = u;
 		const Engine *e_artic = GetEngine(engine_type);
 		switch (type) {
 			default: NOT_REACHED();
 
 			case VEH_TRAIN:
-				u = new (u) Train();
+				u = new Train();
 				u->subtype = 0;
 				previous->SetNext(u);
 				u->u.rail.track = v->u.rail.track;
@@ -330,7 +327,7 @@
 				break;
 
 			case VEH_ROAD:
-				u = new (u) RoadVehicle();
+				u = new RoadVehicle();
 				u->subtype = 0;
 				previous->SetNext(u);
 				u->u.road.first_engine = v->engine_type;
--- a/src/articulated_vehicles.h
+++ b/src/articulated_vehicles.h
@@ -10,7 +10,7 @@
 
 uint CountArticulatedParts(EngineID engine_type, bool purchase_window);
 uint16 *GetCapacityOfArticulatedParts(EngineID engine, VehicleType type);
-void AddArticulatedParts(Vehicle **vl, VehicleType type);
+void AddArticulatedParts(Vehicle *first, VehicleType type);
 uint32 GetUnionOfArticulatedRefitMasks(EngineID engine, VehicleType type, bool include_initial_cargo_type);
 uint32 GetIntersectionOfArticulatedRefitMasks(EngineID engine, VehicleType type, bool include_initial_cargo_type);
 bool IsArticulatedVehicleCarryingDifferentCargos(const Vehicle *v, CargoID *cargo_type);
--- a/src/roadveh_cmd.cpp
+++ b/src/roadveh_cmd.cpp
@@ -160,9 +160,6 @@
  */
 CommandCost CmdBuildRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
 {
-	Vehicle *v;
-	UnitID unit_num;
-
 	if (!IsEngineBuildable(p1, VEH_ROAD, _current_company)) return_cmd_error(STR_ROAD_VEHICLE_NOT_AVAILABLE);
 
 	const Engine *e = GetEngine(p1);
@@ -181,47 +178,40 @@
 
 	uint num_vehicles = 1 + CountArticulatedParts(p1, false);
 
-	/* Allow for the front and the articulated parts, plus one to "terminate" the list. */
-	Vehicle **vl = AllocaM(Vehicle*, num_vehicles + 1);
-	memset(vl, 0, sizeof(*vl) * (num_vehicles + 1));
-
-	if (!Vehicle::AllocateList(vl, num_vehicles)) {
+	/* Allow for the front and the articulated parts */
+	if (!Vehicle::CanAllocateItem(num_vehicles)) {
 		return_cmd_error(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME);
 	}
 
-	v = vl[0];
-
 	/* find the first free roadveh id */
-	unit_num = (flags & DC_AUTOREPLACE) ? 0 : GetFreeUnitNumber(VEH_ROAD);
-	if (unit_num > _settings_game.vehicle.max_roadveh)
+	UnitID unit_num = (flags & DC_AUTOREPLACE) ? 0 : GetFreeUnitNumber(VEH_ROAD);
+	if (unit_num > _settings_game.vehicle.max_roadveh) {
 		return_cmd_error(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME);
+	}
 
 	if (flags & DC_EXEC) {
-		int x;
-		int y;
-
 		const RoadVehicleInfo *rvi = RoadVehInfo(p1);
 
-		v = new (v) RoadVehicle();
+		Vehicle *v = new RoadVehicle();
 		v->unitnumber = unit_num;
 		v->direction = DiagDirToDir(GetRoadDepotDirection(tile));
 		v->owner = _current_company;
 
 		v->tile = tile;
-		x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2;
-		y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2;
+		int x = TileX(tile) * TILE_SIZE + TILE_SIZE / 2;
+		int y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2;
 		v->x_pos = x;
 		v->y_pos = y;
 		v->z_pos = GetSlopeZ(x, y);
 
-		v->running_ticks = 0;
+//		v->running_ticks = 0;
 
 		v->u.road.state = RVSB_IN_DEPOT;
 		v->vehstatus = VS_HIDDEN | VS_STOPPED | VS_DEFPAL;
 
 		v->spritenum = rvi->image_index;
 		v->cargo_type = e->GetDefaultCargoType();
-		v->cargo_subtype = 0;
+//		v->cargo_subtype = 0;
 		v->cargo_cap = rvi->capacity;
 //		v->cargo_count = 0;
 		v->value = cost.GetCost();
@@ -230,7 +220,7 @@
 //		v->load_unload_time_rem = 0;
 //		v->progress = 0;
 
-//	v->u.road.overtaking = 0;
+//		v->u.road.overtaking = 0;
 
 		v->last_station_visited = INVALID_STATION;
 		v->max_speed = rvi->max_speed;
@@ -261,7 +251,7 @@
 
 		v->cargo_cap = rvi->capacity;
 
-		AddArticulatedParts(vl, VEH_ROAD);
+		AddArticulatedParts(v, VEH_ROAD);
 
 		/* Call various callbacks after the whole consist has been constructed */
 		for (Vehicle *u = v; u != NULL; u = u->Next()) {
--- a/src/train_cmd.cpp
+++ b/src/train_cmd.cpp
@@ -641,31 +641,28 @@
 
 	uint num_vehicles = 1 + CountArticulatedParts(engine, false);
 
-	/* Allow for the wagon and the articulated parts, plus one to "terminate" the list. */
-	Vehicle **vl = AllocaM(Vehicle*, num_vehicles + 1);
-	memset(vl, 0, sizeof(*vl) * (num_vehicles + 1));
-
-	if (!Vehicle::AllocateList(vl, num_vehicles)) {
+	/* Allow for the wagon and the articulated parts */
+	if (!Vehicle::CanAllocateItem(num_vehicles)) {
 		return_cmd_error(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME);
 	}
 
 	if (flags & DC_EXEC) {
-		Vehicle *v = vl[0];
-		v->spritenum = rvi->image_index;
-
 		Vehicle *u = NULL;
 
 		Vehicle *w;
 		FOR_ALL_VEHICLES(w) {
+			/* do not connect new wagon with crashed/flooded consists */
 			if (w->type == VEH_TRAIN && w->tile == tile &&
-			    IsFreeWagon(w) && w->engine_type == engine &&
-			    !HASBITS(w->vehstatus, VS_CRASHED)) {          /// do not connect new wagon with crashed/flooded consists
+					IsFreeWagon(w) && w->engine_type == engine &&
+					!HASBITS(w->vehstatus, VS_CRASHED)) {
 				u = GetLastVehicleInChain(w);
 				break;
 			}
 		}
 
-		v = new (v) Train();
+		Vehicle *v = new Train();
+		v->spritenum = rvi->image_index;
+
 		v->engine_type = engine;
 
 		DiagDirection dir = GetRailDepotDirection(tile);
@@ -707,7 +704,7 @@
 
 		v->group_id = DEFAULT_GROUP;
 
-		AddArticulatedParts(vl, VEH_TRAIN);
+		AddArticulatedParts(v, VEH_TRAIN);
 
 		_new_vehicle_id = v->index;
 
@@ -743,9 +740,11 @@
 	}
 }
 
-static void AddRearEngineToMultiheadedTrain(Vehicle *v, Vehicle *u)
+static void AddRearEngineToMultiheadedTrain(Vehicle *v)
 {
-	u = new (u) Train();
+	Vehicle *u = new Train();
+	v->value >>= 1;
+	u->value = v->value;
 	u->direction = v->direction;
 	u->owner = v->owner;
 	u->tile = v->tile;
@@ -755,20 +754,23 @@
 	u->u.rail.track = TRACK_BIT_DEPOT;
 	u->vehstatus = v->vehstatus & ~VS_STOPPED;
 //	u->subtype = 0;
-	SetMultiheaded(u);
 	u->spritenum = v->spritenum + 1;
 	u->cargo_type = v->cargo_type;
 	u->cargo_subtype = v->cargo_subtype;
 	u->cargo_cap = v->cargo_cap;
 	u->u.rail.railtype = v->u.rail.railtype;
-	v->SetNext(u);
 	u->engine_type = v->engine_type;
 	u->build_year = v->build_year;
-	v->value >>= 1;
-	u->value = v->value;
 	u->cur_image = 0xAC2;
 	u->random_bits = VehicleRandomBits();
+	SetMultiheaded(v);
+	SetMultiheaded(u);
+	v->SetNext(u);
 	VehicleMove(u, false);
+
+	/* Now we need to link the front and rear engines together */
+	v->u.rail.other_multiheaded_part = u;
+	u->u.rail.other_multiheaded_part = v;
 }
 
 /** Build a railroad vehicle.
@@ -806,16 +808,11 @@
 	 * We need to see if the engine got power on the tile to avoid eletric engines in non-electric depots */
 	if (!HasPowerOnRail(rvi->railtype, GetRailType(tile))) return CMD_ERROR;
 
-	/* Allow for the dual-heads and the articulated parts, plus one to "terminate" the list. */
-	Vehicle **vl = AllocaM(Vehicle*, num_vehicles + 1);
-	memset(vl, 0, sizeof(*vl) * (num_vehicles + 1));
-
-	if (!Vehicle::AllocateList(vl, num_vehicles)) {
+	/* Allow for the dual-heads and the articulated parts */
+	if (!Vehicle::CanAllocateItem(num_vehicles)) {
 		return_cmd_error(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME);
 	}
 
-	Vehicle *v = vl[0];
-
 	UnitID unit_num = (flags & DC_AUTOREPLACE) ? 0 : GetFreeUnitNumber(VEH_TRAIN);
 	if (unit_num > _settings_game.vehicle.max_trains) {
 		return_cmd_error(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME);
@@ -826,7 +823,7 @@
 		int x = TileX(tile) * TILE_SIZE + _vehicle_initial_x_fract[dir];
 		int y = TileY(tile) * TILE_SIZE + _vehicle_initial_y_fract[dir];
 
-		v = new (v) Train();
+		Vehicle *v = new Train();
 		v->unitnumber = unit_num;
 		v->direction = DiagDirToDir(dir);
 		v->tile = tile;
@@ -874,16 +871,9 @@
 		VehicleMove(v, false);
 
 		if (rvi->railveh_type == RAILVEH_MULTIHEAD) {
-			SetMultiheaded(v);
-			AddRearEngineToMultiheadedTrain(vl[0], vl[1]);
-			/* Now we need to link the front and rear engines together
-			 * other_multiheaded_part is the pointer that links to the other half of the engine
-			 * vl[0] is the front and vl[1] is the rear
-			 */
-			vl[0]->u.rail.other_multiheaded_part = vl[1];
-			vl[1]->u.rail.other_multiheaded_part = vl[0];
+			AddRearEngineToMultiheadedTrain(v);
 		} else {
-			AddArticulatedParts(vl, VEH_TRAIN);
+			AddArticulatedParts(v, VEH_TRAIN);
 		}
 
 		TrainConsistChanged(v, false);
--- a/src/vehicle.cpp
+++ b/src/vehicle.cpp
@@ -206,22 +206,6 @@
 	return GB(Random(), 0, 8);
 }
 
-
-/* static */ bool Vehicle::AllocateList(Vehicle **vl, int num)
-{
-	if (!Vehicle::CanAllocateItem(num)) return false;
-	if (vl == NULL) return true;
-
-	uint counter = _Vehicle_pool.first_free_index;
-
-	for (int i = 0; i != num; i++) {
-		vl[i] = new (AllocateRaw(counter)) InvalidVehicle();
-		counter++;
-	}
-
-	return true;
-}
-
 /* Size of the hash, 6 = 64 x 64, 7 = 128 x 128. Larger sizes will (in theory) reduce hash
  * lookup times at the expense of memory usage. */
 const int HASH_BITS = 7;
--- a/src/vehicle_base.h
+++ b/src/vehicle_base.h
@@ -327,14 +327,6 @@
 	uint32 cached_var42; ///< Cache for NewGRF var 42
 	uint32 cached_var43; ///< Cache for NewGRF var 43
 
-	/**
-	 * Allocates a lot of vehicles.
-	 * @param vl pointer to an array of vehicles to get allocated. Can be NULL if the vehicles aren't needed (makes it test only)
-	 * @param num number of vehicles to allocate room for
-	 * @return true if there is room to allocate all the vehicles
-	 */
-	static bool AllocateList(Vehicle **vl, int num);
-
 	/** Create a new vehicle */
 	Vehicle();