From 836105864c840469cbaea7776fe376a2008d72fc Mon Sep 17 00:00:00 2001 From: rubidium Date: Fri, 3 Aug 2007 19:36:00 +0000 Subject: [PATCH] (svn r10770) -Codechange: use the pool item class as super class for the vehicle struct. -Codechange: do not force "special" vehicles to be allocated in the low 1024 vehicle slots and non "special" vehicles in the rest of the slots. --- src/aircraft_cmd.cpp | 2 +- src/articulated_vehicles.cpp | 2 +- src/disaster_cmd.cpp | 33 +++--- src/economy.cpp | 4 +- src/roadveh_cmd.cpp | 6 +- src/ship_cmd.cpp | 8 +- src/train_cmd.cpp | 17 ++- src/vehicle.cpp | 211 +++++++++++------------------------ src/vehicle.h | 68 ++++------- 9 files changed, 122 insertions(+), 229 deletions(-) diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index d12114d3f3..b214487867 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -287,7 +287,7 @@ CommandCost CmdBuildAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) /* Allocate 2 or 3 vehicle structs, depending on type * vl[0] = aircraft, vl[1] = shadow, [vl[2] = rotor] */ Vehicle *vl[3]; - if (!AllocateVehicles(vl, avi->subtype & AIR_CTOL ? 2 : 3)) { + if (!Vehicle::AllocateList(vl, avi->subtype & AIR_CTOL ? 2 : 3)) { return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); } diff --git a/src/articulated_vehicles.cpp b/src/articulated_vehicles.cpp index 9ae398f4d3..2fad997695 100644 --- a/src/articulated_vehicles.cpp +++ b/src/articulated_vehicles.cpp @@ -42,7 +42,7 @@ void AddArticulatedParts(Vehicle **vl, VehicleType type) /* 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->next = vl[i]; - if (u->next == NULL) u->next = AllocateVehicle(); + if (u->next == NULL) u->next = new InvalidVehicle(); if (u->next == NULL) return; u = u->next; diff --git a/src/disaster_cmd.cpp b/src/disaster_cmd.cpp index 7414b7f372..c274513a76 100644 --- a/src/disaster_cmd.cpp +++ b/src/disaster_cmd.cpp @@ -121,7 +121,6 @@ static void DisasterVehicleUpdateImage(Vehicle *v) * and owned by nobody */ static void InitializeDisasterVehicle(Vehicle *v, int x, int y, byte z, Direction direction, byte subtype) { - v = new (v) DisasterVehicle(); v->x_pos = x; v->y_pos = y; v->z_pos = z; @@ -600,7 +599,7 @@ static void DisasterTick_Big_Ufo(Vehicle *v) v->tile, 0); - u = ForceAllocateSpecialVehicle(); + u = new DisasterVehicle(); if (u == NULL) { DeleteDisasterVeh(v); return; @@ -609,7 +608,7 @@ static void DisasterTick_Big_Ufo(Vehicle *v) InitializeDisasterVehicle(u, -6 * TILE_SIZE, v->y_pos, 135, DIR_SW, ST_Big_Ufo_Destroyer); u->u.disaster.big_ufo_destroyer_target = v->index; - w = ForceAllocateSpecialVehicle(); + w = new DisasterVehicle(); if (w == NULL) return; u->next = w; @@ -706,7 +705,7 @@ static void DisasterTick_Submarine(Vehicle *v) VehiclePositionChanged(v); BeginVehicleMove(v); EndVehicleMove(v); - DeleteVehicle(v); + delete v; return; } @@ -760,7 +759,7 @@ typedef void DisasterInitProc(); * otherwise crashes on a random tile */ static void Disaster_Zeppeliner_Init() { - Vehicle *v = ForceAllocateSpecialVehicle(), *u; + Vehicle *v = new DisasterVehicle(), *u; Station *st; int x; @@ -781,7 +780,7 @@ static void Disaster_Zeppeliner_Init() InitializeDisasterVehicle(v, x, 0, 135, DIR_SE, ST_Zeppeliner); /* Allocate shadow too? */ - u = ForceAllocateSpecialVehicle(); + u = new DisasterVehicle(); if (u != NULL) { v->next = u; InitializeDisasterVehicle(u, x, 0, 0, DIR_SE, ST_Zeppeliner_Shadow); @@ -794,7 +793,7 @@ static void Disaster_Zeppeliner_Init() * until it locates a road vehicle which it targets and then destroys */ static void Disaster_Small_Ufo_Init() { - Vehicle *v = ForceAllocateSpecialVehicle(), *u; + Vehicle *v = new DisasterVehicle(), *u; int x; if (v == NULL) return; @@ -806,7 +805,7 @@ static void Disaster_Small_Ufo_Init() v->age = 0; /* Allocate shadow too? */ - u = ForceAllocateSpecialVehicle(); + u = new DisasterVehicle(); if (u != NULL) { v->next = u; InitializeDisasterVehicle(u, x, 0, 0, DIR_SE, ST_Small_Ufo_Shadow); @@ -833,7 +832,7 @@ static void Disaster_Airplane_Init() if (found == NULL) return; - v = ForceAllocateSpecialVehicle(); + v = new DisasterVehicle(); if (v == NULL) return; /* Start from the bottom (south side) of the map */ @@ -842,7 +841,7 @@ static void Disaster_Airplane_Init() InitializeDisasterVehicle(v, x, y, 135, DIR_NE, ST_Airplane); - u = ForceAllocateSpecialVehicle(); + u = new DisasterVehicle(); if (u != NULL) { v->next = u; InitializeDisasterVehicle(u, x, y, 0, DIR_SE, ST_Airplane_Shadow); @@ -869,7 +868,7 @@ static void Disaster_Helicopter_Init() if (found == NULL) return; - v = ForceAllocateSpecialVehicle(); + v = new DisasterVehicle(); if (v == NULL) return; x = -16 * TILE_SIZE; @@ -877,13 +876,13 @@ static void Disaster_Helicopter_Init() InitializeDisasterVehicle(v, x, y, 135, DIR_SW, ST_Helicopter); - u = ForceAllocateSpecialVehicle(); + u = new DisasterVehicle(); if (u != NULL) { v->next = u; InitializeDisasterVehicle(u, x, y, 0, DIR_SW, ST_Helicopter_Shadow); u->vehstatus |= VS_SHADOW; - w = ForceAllocateSpecialVehicle(); + w = new DisasterVehicle(); if (w != NULL) { u->next = w; InitializeDisasterVehicle(w, x, y, 140, DIR_SW, ST_Helicopter_Rotors); @@ -896,7 +895,7 @@ static void Disaster_Helicopter_Init() * down by a combat airplane, destroying the surroundings */ static void Disaster_Big_Ufo_Init() { - Vehicle *v = ForceAllocateSpecialVehicle(), *u; + Vehicle *v = new DisasterVehicle(), *u; int x, y; if (v == NULL) return; @@ -909,7 +908,7 @@ static void Disaster_Big_Ufo_Init() v->age = 0; /* Allocate shadow too? */ - u = ForceAllocateSpecialVehicle(); + u = new DisasterVehicle(); if (u != NULL) { v->next = u; InitializeDisasterVehicle(u, x, y, 0, DIR_NW, ST_Big_Ufo_Shadow); @@ -921,7 +920,7 @@ static void Disaster_Big_Ufo_Init() /* Curious submarine #1, just floats around */ static void Disaster_Small_Submarine_Init() { - Vehicle *v = ForceAllocateSpecialVehicle(); + Vehicle *v = new DisasterVehicle(); int x, y; Direction dir; uint32 r; @@ -946,7 +945,7 @@ static void Disaster_Small_Submarine_Init() /* Curious submarine #2, just floats around */ static void Disaster_Big_Submarine_Init() { - Vehicle *v = ForceAllocateSpecialVehicle(); + Vehicle *v = new DisasterVehicle(); int x, y; Direction dir; uint32 r; diff --git a/src/economy.cpp b/src/economy.cpp index 5cf7298b63..ee7ac8d5d2 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -355,14 +355,14 @@ void ChangeOwnershipOfPlayerItems(PlayerID old_player, PlayerID new_player) Vehicle *u = v; do { Vehicle *next = GetNextVehicle(u); - DeleteVehicle(u); + delete u; u = next; } while (u != NULL); } break; case VEH_ROAD: case VEH_SHIP: - DeleteVehicle(v); + delete v; break; case VEH_AIRCRAFT: diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 0180b345f1..56d48a816d 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.cpp @@ -185,7 +185,7 @@ CommandCost CmdBuildRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) Vehicle *vl[11]; memset(&vl, 0, sizeof(vl)); - if (!AllocateVehicles(vl, num_vehicles)) { + if (!Vehicle::AllocateList(vl, num_vehicles)) { return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); } @@ -372,7 +372,7 @@ CommandCost CmdSellRoadVeh(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) InvalidateWindow(WC_COMPANY, v->owner); DeleteWindowById(WC_VEHICLE_VIEW, v->index); DeleteDepotHighlightOfVehicle(v); - DeleteVehicle(v); + delete v; } return CommandCost(-v->value); @@ -610,7 +610,7 @@ static void DeleteLastRoadVeh(Vehicle *v) BeginVehicleMove(v); EndVehicleMove(v); - DeleteVehicle(v); + delete v; } static byte SetRoadVehPosition(Vehicle *v, int x, int y) diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index 4a8fbe6304..1cba23e0d6 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.cpp @@ -33,6 +33,7 @@ #include "newgrf_sound.h" #include "date.h" #include "spritecache.h" +#include "misc/autoptr.hpp" static const uint16 _ship_sprites[] = {0x0E5D, 0x0E55, 0x0E65, 0x0E6D}; @@ -833,8 +834,9 @@ CommandCost CmdBuildShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) if (!IsTileDepotType(tile, TRANSPORT_WATER)) return CMD_ERROR; if (!IsTileOwner(tile, _current_player)) return CMD_ERROR; - v = AllocateVehicle(); + v = new Ship(); unit_num = HASBIT(p2, 0) ? 0 : GetFreeUnitNumber(VEH_SHIP); + AutoPtrT v_auto_delete = v; if (v == NULL || unit_num > _patches.max_ships) return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); @@ -898,6 +900,8 @@ CommandCost CmdBuildShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) InvalidateAutoreplaceWindow(VEH_SHIP, v->group_id); // updates the replace Ship window GetPlayer(_current_player)->num_engines[p1]++; + + v_auto_delete.Detach(); } return value; @@ -931,7 +935,7 @@ CommandCost CmdSellShip(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) InvalidateWindow(WC_COMPANY, v->owner); DeleteWindowById(WC_VEHICLE_VIEW, v->index); DeleteDepotHighlightOfVehicle(v); - DeleteVehicle(v); + delete v; } return CommandCost(-v->value); diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 0477252695..eab077ad65 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -518,7 +518,7 @@ static CommandCost CmdBuildRailWagon(EngineID engine, TileIndex tile, uint32 fla memset(&vl, 0, sizeof(vl)); - if (!AllocateVehicles(vl, num_vehicles)) + if (!Vehicle::AllocateList(vl, num_vehicles)) return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); if (flags & DC_EXEC) { @@ -686,7 +686,7 @@ CommandCost CmdBuildRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 memset(&vl, 0, sizeof(vl)); - if (!AllocateVehicles(vl, num_vehicles)) + if (!Vehicle::AllocateList(vl, num_vehicles)) return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); Vehicle *v = vl[0]; @@ -1253,7 +1253,7 @@ CommandCost CmdSellRailWagon(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) if (flags & DC_EXEC) { UnlinkWagon(rear, first); DeleteDepotHighlightOfVehicle(rear); - DeleteVehicle(rear); + delete rear; } } @@ -1308,7 +1308,7 @@ CommandCost CmdSellRailWagon(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) if (flags & DC_EXEC) { first = UnlinkWagon(v, first); DeleteDepotHighlightOfVehicle(v); - DeleteVehicle(v); + delete v; /* 4 If the second wagon was an engine, update it to front_engine * which UnlinkWagon() has changed to TS_Free_Car */ @@ -1367,7 +1367,7 @@ CommandCost CmdSellRailWagon(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) if (flags & DC_EXEC) { first = UnlinkWagon(rear, first); DeleteDepotHighlightOfVehicle(rear); - DeleteVehicle(rear); + delete rear; } } } else if (v->u.rail.other_multiheaded_part != NULL) { @@ -1380,7 +1380,7 @@ CommandCost CmdSellRailWagon(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) if (flags & DC_EXEC) { first = UnlinkWagon(v, first); DeleteDepotHighlightOfVehicle(v); - DeleteVehicle(v); + delete v; RemoveVehicleFromGroup(v); } } @@ -3039,7 +3039,7 @@ static void DeleteLastWagon(Vehicle *v) BeginVehicleMove(v); EndVehicleMove(v); - DeleteVehicle(v); + delete v; if (v->u.rail.track != TRACK_BIT_DEPOT && v->u.rail.track != TRACK_BIT_WORMHOLE) SetSignalsOnBothDir(v->tile, FIND_FIRST_BIT(v->u.rail.track)); @@ -3329,8 +3329,7 @@ void Train::Tick() TrainLocoHandler(this, true); } else if (IsFreeWagon(this) && HASBITS(this->vehstatus, VS_CRASHED)) { /* Delete flooded standalone wagon */ - if (++this->u.rail.crash_anim_pos >= 4400) - DeleteVehicle(this); + if (++this->u.rail.crash_anim_pos >= 4400) delete this; } } diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 86a87c5c63..e4d6b09d4e 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -282,28 +282,12 @@ void AfterLoadVehicles() } } -static Vehicle *InitializeVehicle(Vehicle *v) -{ - VehicleID index = v->index; - memset(v, 0, sizeof(Vehicle)); - v->index = index; - - assert(v->orders == NULL); - - v = new (v) InvalidVehicle(); - v->left_coord = INVALID_COORD; - v->first = NULL; - v->next = NULL; - v->next_hash = NULL; - v->string_id = 0; - v->next_shared = NULL; - v->prev_shared = NULL; - v->depot_list = NULL; - v->random_bits = 0; - v->group_id = DEFAULT_GROUP; - v->fill_percent_te_id = INVALID_TE_ID; - - return v; +Vehicle::Vehicle() +{ + this->type = VEH_INVALID; + this->left_coord = INVALID_COORD; + this->group_id = DEFAULT_GROUP; + this->fill_percent_te_id = INVALID_TE_ID; } /** @@ -315,87 +299,21 @@ byte VehicleRandomBits() return GB(Random(), 0, 8); } -Vehicle *ForceAllocateSpecialVehicle() -{ - /* This stays a strange story.. there should always be room for special - * vehicles (special effects all over the map), but with 65k of vehicles - * is this realistic to double-check for that? For now we just reserve - * BLOCKS_FOR_SPECIAL_VEHICLES times block_size vehicles that may only - * be used for special vehicles.. should work nicely :) */ - - Vehicle *v; - - /* 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 (v = GetVehicle(0); v != NULL; v = (v->index + 1U < GetVehiclePoolSize()) ? GetVehicle(v->index + 1) : NULL) { - /* No more room for the special vehicles, return NULL */ - if (v->index >= (1 << Vehicle_POOL_BLOCK_SIZE_BITS) * BLOCKS_FOR_SPECIAL_VEHICLES) - return NULL; - - if (!v->IsValid()) return InitializeVehicle(v); - } - - return NULL; -} -/** - * finds a free vehicle in the memory or allocates a new one - * returns a pointer to the first free vehicle or NULL if all vehicles are in use - * *skip_vehicles is an offset to where in the array we should begin looking - * this is to avoid looping though the same vehicles more than once after we learned that they are not free - * this feature is used by AllocateVehicles() since it need to allocate more than one and when - * another block is added to _Vehicle_pool, since we only do that when we know it's already full - */ -static Vehicle *AllocateSingleVehicle(VehicleID *skip_vehicles) +/* static */ bool Vehicle::AllocateList(Vehicle **vl, int num) { - /* See note by ForceAllocateSpecialVehicle() why we skip the - * first blocks */ - Vehicle *v; - const int offset = (1 << Vehicle_POOL_BLOCK_SIZE_BITS) * BLOCKS_FOR_SPECIAL_VEHICLES; - - /* We don't use FOR_ALL here, because FOR_ALL skips invalid items. - * @todo - This is just a temporary stage, this will be removed. */ - if (*skip_vehicles < (_Vehicle_pool.GetSize() - offset)) { // make sure the offset in the array is not larger than the array itself - for (v = GetVehicle(offset + *skip_vehicles); v != NULL; v = (v->index + 1U < GetVehiclePoolSize()) ? GetVehicle(v->index + 1) : NULL) { - (*skip_vehicles)++; - if (!v->IsValid()) return InitializeVehicle(v); - } - } + uint counter = _Vehicle_pool.first_free_index; - /* Check if we can add a block to the pool */ - if (AddBlockToPool(&_Vehicle_pool)) - return AllocateSingleVehicle(skip_vehicles); + for (int i = 0; i != num; i++) { + Vehicle *v = AllocateRaw(counter); - return NULL; -} - - -Vehicle *AllocateVehicle() -{ - VehicleID counter = 0; - return AllocateSingleVehicle(&counter); -} - - -/** Allocates a lot of vehicles and frees them again - * @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 - */ -bool AllocateVehicles(Vehicle **vl, int num) -{ - int i; - Vehicle *v; - VehicleID counter = 0; + if (v == NULL) return false; + v = new (v) InvalidVehicle(); - for (i = 0; i != num; i++) { - v = AllocateSingleVehicle(&counter); - if (v == NULL) { - return false; - } if (vl != NULL) { vl[i] = v; } + counter++; } return true; @@ -671,44 +589,51 @@ bool IsEngineCountable(const Vehicle *v) } } -void DestroyVehicle(Vehicle *v) +Vehicle::~Vehicle() { - if (IsValidStationID(v->last_station_visited)) { - GetStation(v->last_station_visited)->loading_vehicles.remove(v); + if (IsValidStationID(this->last_station_visited)) { + GetStation(this->last_station_visited)->loading_vehicles.remove(this); - HideFillingPercent(v->fill_percent_te_id); - v->fill_percent_te_id = INVALID_TE_ID; + HideFillingPercent(this->fill_percent_te_id); + this->fill_percent_te_id = INVALID_TE_ID; } - if (IsEngineCountable(v)) { - GetPlayer(v->owner)->num_engines[v->engine_type]--; - if (v->owner == _local_player) InvalidateAutoreplaceWindow(v->engine_type, v->group_id); + if (IsEngineCountable(this)) { + GetPlayer(this->owner)->num_engines[this->engine_type]--; + if (this->owner == _local_player) InvalidateAutoreplaceWindow(this->engine_type, this->group_id); - if (IsValidGroupID(v->group_id)) GetGroup(v->group_id)->num_engines[v->engine_type]--; - if (v->IsPrimaryVehicle()) DecreaseGroupNumVehicle(v->group_id); + if (IsValidGroupID(this->group_id)) GetGroup(this->group_id)->num_engines[this->engine_type]--; + if (this->IsPrimaryVehicle()) DecreaseGroupNumVehicle(this->group_id); } - DeleteVehicleNews(v->index, INVALID_STRING_ID); + DeleteVehicleNews(this->index, INVALID_STRING_ID); - DeleteName(v->string_id); - if (v->type == VEH_ROAD) ClearSlot(v); + this->QuickFree(); + if (this->type == VEH_ROAD) ClearSlot(this); - if (v->type != VEH_TRAIN || (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v)))) { - InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile); + if (this->type != VEH_TRAIN || (this->type == VEH_TRAIN && (IsFrontEngine(this) || IsFreeWagon(this)))) { + InvalidateWindowData(WC_VEHICLE_DEPOT, this->tile); } - v->cargo.Truncate(0); - UpdateVehiclePosHash(v, INVALID_COORD, 0); - v->next_hash = NULL; - v->next_new_hash = NULL; - if (IsPlayerBuildableVehicleType(v)) DeleteVehicleOrders(v); + this->cargo.Truncate(0); + UpdateVehiclePosHash(this, INVALID_COORD, 0); + this->next_hash = NULL; + this->next_new_hash = NULL; + if (IsPlayerBuildableVehicleType(this)) DeleteVehicleOrders(this); /* Now remove any artic part. This will trigger an other * destroy vehicle, which on his turn can remove any * other artic parts. */ - if ((v->type == VEH_TRAIN && EngineHasArticPart(v)) || (v->type == VEH_ROAD && RoadVehHasArticPart(v))) { - DeleteVehicle(v->next); + if ((this->type == VEH_TRAIN && EngineHasArticPart(this)) || (this->type == VEH_ROAD && RoadVehHasArticPart(this))) { + delete this->next; } + + new (this) InvalidVehicle(); +} + +void Vehicle::QuickFree() +{ + DeleteName(this->string_id); } /** @@ -725,7 +650,7 @@ void DeleteVehicleChain(Vehicle *v) do { Vehicle *u = v; v = v->next; - DeleteVehicle(u); + delete u; } while (v != NULL); } @@ -932,7 +857,7 @@ static void ChimneySmokeTick(Vehicle *v) tile = TileVirtXY(v->x_pos, v->y_pos); if (!IsTileType(tile, MP_INDUSTRY)) { EndVehicleMove(v); - DeleteVehicle(v); + delete v; return; } @@ -971,7 +896,7 @@ static void SteamSmokeTick(Vehicle *v) v->cur_image++; } else { EndVehicleMove(v); - DeleteVehicle(v); + delete v; return; } moved = true; @@ -1006,7 +931,7 @@ static void DieselSmokeTick(Vehicle *v) EndVehicleMove(v); } else { EndVehicleMove(v); - DeleteVehicle(v); + delete v; } } } @@ -1030,7 +955,7 @@ static void ElectricSparkTick(Vehicle *v) EndVehicleMove(v); } else { EndVehicleMove(v); - DeleteVehicle(v); + delete v; } } } @@ -1059,7 +984,7 @@ static void SmokeTick(Vehicle *v) v->cur_image++; } else { EndVehicleMove(v); - DeleteVehicle(v); + delete v; return; } moved = true; @@ -1088,7 +1013,7 @@ static void ExplosionLargeTick(Vehicle *v) EndVehicleMove(v); } else { EndVehicleMove(v); - DeleteVehicle(v); + delete v; } } } @@ -1117,7 +1042,7 @@ static void BreakdownSmokeTick(Vehicle *v) if (v->u.special.animation_state == 0) { BeginVehicleMove(v); EndVehicleMove(v); - DeleteVehicle(v); + delete v; } } @@ -1138,7 +1063,7 @@ static void ExplosionSmallTick(Vehicle *v) EndVehicleMove(v); } else { EndVehicleMove(v); - DeleteVehicle(v); + delete v; } } } @@ -1209,7 +1134,7 @@ static void BulldozerTick(Vehicle *v) v->u.special.animation_state++; if (v->u.special.animation_state == lengthof(_bulldozer_movement)) { EndVehicleMove(v); - DeleteVehicle(v); + delete v; return; } } @@ -1413,7 +1338,7 @@ static void BubbleTick(Vehicle *v) if (b->y == 4 && b->x == 0) { EndVehicleMove(v); - DeleteVehicle(v); + delete v; return; } @@ -1482,9 +1407,8 @@ Vehicle *CreateEffectVehicle(int x, int y, int z, EffectVehicle type) { Vehicle *v; - v = ForceAllocateSpecialVehicle(); + v = new SpecialVehicle(); if (v != NULL) { - v = new (v) SpecialVehicle(); v->subtype = type; v->x_pos = x; v->y_pos = y; @@ -1878,7 +1802,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2) veh_counter++; } while ((v = v->next) != NULL); - if (!AllocateVehicles(NULL, veh_counter)) { + if (!Vehicle::AllocateList(NULL, veh_counter)) { return_cmd_error(STR_00E1_TOO_MANY_VEHICLES_IN_GAME); } } @@ -3091,7 +3015,7 @@ static const SaveLoad _disaster_desc[] = { }; -static const void *_veh_descs[] = { +static const SaveLoad *_veh_descs[] = { _train_desc, _roadveh_desc, _ship_desc, @@ -3107,7 +3031,7 @@ static void Save_VEHS() /* Write the vehicles */ FOR_ALL_VEHICLES(v) { SlSetArrayIndex(v->index); - SlObject(v, (SaveLoad*)_veh_descs[v->type]); + SlObject(v, _veh_descs[v->type]); } } @@ -3121,25 +3045,20 @@ static void Load_VEHS() while ((index = SlIterateArray()) != -1) { Vehicle *v; - - if (!AddBlockIfNeeded(&_Vehicle_pool, index)) - error("Vehicles: failed loading savegame: too many vehicles"); - - v = GetVehicle(index); VehicleType vtype = (VehicleType)SlReadByte(); switch (vtype) { - case VEH_TRAIN: v = new (v) Train(); break; - case VEH_ROAD: v = new (v) RoadVehicle(); break; - case VEH_SHIP: v = new (v) Ship(); break; - case VEH_AIRCRAFT: v = new (v) Aircraft(); break; - case VEH_SPECIAL: v = new (v) SpecialVehicle(); break; - case VEH_DISASTER: v = new (v) DisasterVehicle(); break; - case VEH_INVALID: v = new (v) InvalidVehicle(); break; + case VEH_TRAIN: v = new (index) Train(); break; + case VEH_ROAD: v = new (index) RoadVehicle(); break; + case VEH_SHIP: v = new (index) Ship(); break; + case VEH_AIRCRAFT: v = new (index) Aircraft(); break; + case VEH_SPECIAL: v = new (index) SpecialVehicle(); break; + case VEH_DISASTER: v = new (index) DisasterVehicle(); break; + case VEH_INVALID: v = new (index) InvalidVehicle(); break; default: NOT_REACHED(); } - SlObject(v, (SaveLoad*)_veh_descs[vtype]); + SlObject(v, _veh_descs[vtype]); if (_cargo_count != 0 && IsPlayerBuildableVehicleType(v)) { /* Don't construct the packet with station here, because that'll fail with old savegames */ diff --git a/src/vehicle.h b/src/vehicle.h index 0ff3c247fb..410b66890b 100644 --- a/src/vehicle.h +++ b/src/vehicle.h @@ -215,13 +215,13 @@ struct VehicleShip { TrackBitsByte state; }; +struct Vehicle; +DECLARE_OLD_POOL(Vehicle, Vehicle, 9, 125) -struct Vehicle { +struct Vehicle : PoolItem { VehicleTypeByte type; ///< Type of vehicle byte subtype; // subtype (Filled with values from EffectVehicles/TrainSubTypes/AircraftSubTypes) - VehicleID index; // NOSAVE: Index in vehicle array - Vehicle *next; // next Vehicle *first; // NOSAVE: pointer to the first vehicle in the chain Vehicle *depot_list; //NOSAVE: linked list to tell what vehicles entered a depot during the last tick. Used by autoreplace @@ -335,6 +335,23 @@ struct Vehicle { VehicleShip ship; } u; + + /** + * 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(); + + /** We want to 'destruct' the right class. */ + virtual ~Vehicle(); + + void QuickFree(); + void BeginLoading(); void LeaveStation(); @@ -345,37 +362,6 @@ struct Vehicle { */ void HandleLoading(bool mode = false); - /** - * An overriden version of new, so you can use the vehicle instance - * instead of a newly allocated piece of memory. - * @param size the size of the variable (unused) - * @param v the vehicle to use as 'storage' backend - * @return the memory that is 'allocated' - */ - void *operator new(size_t size, Vehicle *v) { return v; } - - /** - * 'Free' the memory allocated by the overriden new. - * @param p the memory to 'free' - * @param v the vehicle that was given to 'new' on creation. - * @note This function isn't used (at the moment) and only added - * to please some compiler. - */ - void operator delete(void *p, Vehicle *v) {} - - /** - * 'Free' the memory allocated by the overriden new. - * @param p the memory to 'free' - * @note This function isn't used (at the moment) and only added - * as the above function was needed to please some compiler - * which made it necessary to add this to please yet - * another compiler... - */ - void operator delete(void *p) {} - - /** We want to 'destruct' the right class. */ - virtual ~Vehicle() {} - /** * Get a string 'representation' of the vehicle type. * @return the string representation. @@ -509,10 +495,6 @@ struct InvalidVehicle : public Vehicle { typedef void *VehicleFromPosProc(Vehicle *v, void *data); void VehicleServiceInDepot(Vehicle *v); -Vehicle *AllocateVehicle(); -bool AllocateVehicles(Vehicle **vl, int num); -Vehicle *ForceAllocateVehicle(); -Vehicle *ForceAllocateSpecialVehicle(); void VehiclePositionChanged(Vehicle *v); void AfterLoadVehicles(); Vehicle *GetLastVehicleInChain(Vehicle *v); @@ -619,8 +601,6 @@ Direction GetDirectionTowards(const Vehicle *v, int x, int y); #define BEGIN_ENUM_WAGONS(v) do { #define END_ENUM_WAGONS(v) } while ((v = v->next) != NULL); -DECLARE_OLD_POOL(Vehicle, Vehicle, 9, 125) - static inline VehicleID GetMaxVehicleIndex() { /* TODO - This isn't the real content of the function, but @@ -636,14 +616,6 @@ static inline uint GetNumVehicles() return GetVehiclePoolSize(); } -void DestroyVehicle(Vehicle *v); - -static inline void DeleteVehicle(Vehicle *v) -{ - DestroyVehicle(v); - v = new (v) InvalidVehicle(); -} - static inline bool IsPlayerBuildableVehicleType(VehicleType type) { switch (type) {