diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index ae88417751..5b5746563a 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -1668,7 +1668,7 @@ static void AircraftEventHandler_Flying(Aircraft *v, const AirportFTAClass *apc) * if it is an airplane, look for LANDING, for helicopter HELILANDING * it is possible to choose from multiple landing runways, so loop until a free one is found */ uint8_t landingtype = (v->subtype == AIR_HELICOPTER) ? HELILANDING : LANDING; - const AirportFTA *current = apc->layout[v->pos].next; + const AirportFTA *current = apc->layout[v->pos].next.get(); while (current != nullptr) { if (current->heading == landingtype) { /* save speed before, since if AirportHasBlock is false, it resets them to 0 @@ -1689,7 +1689,7 @@ static void AircraftEventHandler_Flying(Aircraft *v, const AirportFTAClass *apc) v->cur_speed = tcur_speed; v->subspeed = tsubspeed; } - current = current->next; + current = current->next.get(); } } v->state = FLYING; @@ -1843,7 +1843,7 @@ static bool AirportMove(Aircraft *v, const AirportFTAClass *apc) } // move to next position return false; } - current = current->next; + current = current->next.get(); } while (current != nullptr); Debug(misc, 0, "[Ap] cannot move further on Airport! (pos {} state {}) for vehicle {}", v->pos, v->state, v->index); @@ -1893,13 +1893,13 @@ static bool AirportSetBlocks(Aircraft *v, const AirportFTA *current_pos, const A /* search for all all elements in the list with the same state, and blocks != N * this means more blocks should be checked/set */ const AirportFTA *current = current_pos; - if (current == reference) current = current->next; + if (current == reference) current = current->next.get(); while (current != nullptr) { if (current->heading == current_pos->heading && current->block != 0) { airport_flags |= current->block; break; } - current = current->next; + current = current->next.get(); } /* if the block to be checked is in the next position, then exclude that from @@ -2000,7 +2000,7 @@ static bool AirportFindFreeTerminal(Aircraft *v, const AirportFTAClass *apc) */ if (apc->terminals[0] > 1) { const Station *st = Station::Get(v->targetairport); - const AirportFTA *temp = apc->layout[v->pos].next; + const AirportFTA *temp = apc->layout[v->pos].next.get(); while (temp != nullptr) { if (temp->heading == TERMGROUP) { @@ -2025,7 +2025,7 @@ static bool AirportFindFreeTerminal(Aircraft *v, const AirportFTAClass *apc) * So we cannot move */ return false; } - temp = temp->next; + temp = temp->next.get(); } } diff --git a/src/airport.cpp b/src/airport.cpp index a1e68b0629..a46e30a88e 100644 --- a/src/airport.cpp +++ b/src/airport.cpp @@ -66,7 +66,7 @@ AIRPORT_GENERIC(dummy, nullptr, 0, AirportFTAClass::ALL, 0) static uint16_t AirportGetNofElements(const AirportFTAbuildup *apFA); -static AirportFTA *AirportBuildAutomata(uint nofelements, const AirportFTAbuildup *apFA); +static void AirportBuildAutomata(std::vector &layout, uint8_t nofelements, const AirportFTAbuildup *apFA); /** @@ -126,20 +126,7 @@ AirportFTAClass::AirportFTAClass( delta_z(delta_z_) { /* Build the state machine itself */ - this->layout = AirportBuildAutomata(this->nofelements, apFA); -} - -AirportFTAClass::~AirportFTAClass() -{ - for (uint i = 0; i < nofelements; i++) { - AirportFTA *current = layout[i].next; - while (current != nullptr) { - AirportFTA *next = current->next; - free(current); - current = next; - } - } - free(layout); + AirportBuildAutomata(this->layout, this->nofelements, apFA); } /** @@ -162,41 +149,32 @@ static uint16_t AirportGetNofElements(const AirportFTAbuildup *apFA) return nofelements; } +AirportFTA::AirportFTA(const AirportFTAbuildup &buildup) : block(buildup.block), position(buildup.position), next_position(buildup.next), heading(buildup.heading) +{ +} + /** * Construct the FTA given a description. + * @param layout The vector to write the automata to. * @param nofelements The number of elements in the FTA. * @param apFA The description of the FTA. - * @return The FTA describing the airport. */ -static AirportFTA *AirportBuildAutomata(uint nofelements, const AirportFTAbuildup *apFA) +static void AirportBuildAutomata(std::vector &layout, uint8_t nofelements, const AirportFTAbuildup *apFA) { - AirportFTA *FAutomata = MallocT(nofelements); uint16_t internalcounter = 0; + layout.reserve(nofelements); for (uint i = 0; i < nofelements; i++) { - AirportFTA *current = &FAutomata[i]; - current->position = apFA[internalcounter].position; - current->heading = apFA[internalcounter].heading; - current->block = apFA[internalcounter].block; - current->next_position = apFA[internalcounter].next; + AirportFTA *current = &layout.emplace_back(apFA[internalcounter]); /* outgoing nodes from the same position, create linked list */ while (current->position == apFA[internalcounter + 1].position) { - AirportFTA *newNode = MallocT(1); - - newNode->position = apFA[internalcounter + 1].position; - newNode->heading = apFA[internalcounter + 1].heading; - newNode->block = apFA[internalcounter + 1].block; - newNode->next_position = apFA[internalcounter + 1].next; - /* create link */ - current->next = newNode; - current = current->next; + current->next = std::make_unique(apFA[internalcounter + 1]); + current = current->next.get(); internalcounter++; } - current->next = nullptr; internalcounter++; } - return FAutomata; } /** diff --git a/src/airport.h b/src/airport.h index 2662639341..6f3548e382 100644 --- a/src/airport.h +++ b/src/airport.h @@ -139,6 +139,17 @@ AirportMovingData RotateAirportMovingData(const AirportMovingData *orig, Directi struct AirportFTAbuildup; +/** Internal structure used in openttd - Finite sTate mAchine --> FTA */ +struct AirportFTA { + AirportFTA(const AirportFTAbuildup&); + + std::unique_ptr next; ///< possible extra movement choices from this position + uint64_t block; ///< bitmap of blocks that could be reserved + uint8_t position; ///< the position that an airplane is at + uint8_t next_position; ///< next position from this position + uint8_t heading; ///< heading (current orders), guiding an airplane to its target on an airport +}; + /** Finite sTate mAchine (FTA) of an airport. */ struct AirportFTAClass { public: @@ -160,8 +171,6 @@ public: uint8_t delta_z ); - ~AirportFTAClass(); - /** * Get movement data at a position. * @param position Element number to get movement data about. @@ -174,7 +183,7 @@ public: } const AirportMovingData *moving_data; ///< Movement data. - struct AirportFTA *layout; ///< state machine for airport + std::vector layout; ///< state machine for airport const uint8_t *terminals; ///< %Array with the number of terminal groups, followed by the number of terminals in each group. const uint8_t num_helipads; ///< Number of helipads on this airport. When 0 helicopters will go to normal terminals. Flags flags; ///< Flags for this airport type. @@ -186,15 +195,6 @@ public: DECLARE_ENUM_AS_BIT_SET(AirportFTAClass::Flags) -/** Internal structure used in openttd - Finite sTate mAchine --> FTA */ -struct AirportFTA { - AirportFTA *next; ///< possible extra movement choices from this position - uint64_t block; ///< 64 bit blocks (st->airport.flags), should be enough for the most complex airports - uint8_t position; ///< the position that an airplane is at - uint8_t next_position; ///< next position from this position - uint8_t heading; ///< heading (current orders), guiding an airplane to its target on an airport -}; - const AirportFTAClass *GetAirport(const uint8_t airport_type); uint8_t GetVehiclePosOnBuild(TileIndex hangar_tile); diff --git a/src/vehicle.cpp b/src/vehicle.cpp index e0c1f9fcc1..7c2797dd45 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -852,7 +852,7 @@ void Vehicle::PreDestructor() Aircraft *a = Aircraft::From(this); Station *st = GetTargetAirportIfValid(a); if (st != nullptr) { - const AirportFTA *layout = st->airport.GetFTA()->layout; + const auto &layout = st->airport.GetFTA()->layout; CLRBITS(st->airport.flags, layout[a->previous_pos].block | layout[a->pos].block); } }