From 063d97f4f2ad8aebcdad0c1a925ae954dea2916a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Tue, 21 Feb 2023 23:20:48 +0200 Subject: [PATCH] Use fixed size storage for Rides, cleanup interface a bit --- src/openrct2-ui/windows/TrackDesignPlace.cpp | 6 +- src/openrct2/actions/RideCreateAction.cpp | 2 +- src/openrct2/park/ParkFile.cpp | 2 +- src/openrct2/rct1/S4Importer.cpp | 2 +- src/openrct2/rct2/S6Importer.cpp | 2 +- src/openrct2/ride/Ride.cpp | 83 ++++++++++++-------- src/openrct2/ride/Ride.h | 4 +- src/openrct2/ride/TrackDesign.cpp | 6 +- 8 files changed, 63 insertions(+), 44 deletions(-) diff --git a/src/openrct2-ui/windows/TrackDesignPlace.cpp b/src/openrct2-ui/windows/TrackDesignPlace.cpp index 28b7fd777e..bd27be66a5 100644 --- a/src/openrct2-ui/windows/TrackDesignPlace.cpp +++ b/src/openrct2-ui/windows/TrackDesignPlace.cpp @@ -163,7 +163,7 @@ public: if (mapCoords == _placementLoc) { TrackDesignPreviewDrawOutlines( - tds, _trackDesign.get(), *GetOrAllocateRide(PreviewRideId), { mapCoords, 0, _currentTrackPieceDirection }); + tds, _trackDesign.get(), *RideAllocateAtIndex(PreviewRideId), { mapCoords, 0, _currentTrackPieceDirection }); return; } @@ -203,7 +203,7 @@ public: WidgetInvalidate(*this, WIDX_PRICE); } - TrackDesignPreviewDrawOutlines(tds, _trackDesign.get(), *GetOrAllocateRide(PreviewRideId), trackLoc); + TrackDesignPreviewDrawOutlines(tds, _trackDesign.get(), *RideAllocateAtIndex(PreviewRideId), trackLoc); } void OnToolDown(WidgetIndex widgetIndex, const ScreenCoordsXY& screenCoords) override @@ -425,7 +425,7 @@ private: return z + TrackDesignGetZPlacement( - _trackDesign.get(), *GetOrAllocateRide(PreviewRideId), { loc, z, _currentTrackPieceDirection }); + _trackDesign.get(), *RideAllocateAtIndex(PreviewRideId), { loc, z, _currentTrackPieceDirection }); } void DrawMiniPreviewTrack(TrackDesign* td6, int32_t pass, const CoordsXY& origin, CoordsXY min, CoordsXY max) diff --git a/src/openrct2/actions/RideCreateAction.cpp b/src/openrct2/actions/RideCreateAction.cpp index 53752387a9..938bc885a2 100644 --- a/src/openrct2/actions/RideCreateAction.cpp +++ b/src/openrct2/actions/RideCreateAction.cpp @@ -122,7 +122,7 @@ GameActions::Result RideCreateAction::Execute() const int32_t rideEntryIndex = RideGetEntryIndex(_rideType, _subType); auto rideIndex = GetNextFreeRideId(); - auto ride = GetOrAllocateRide(rideIndex); + auto ride = RideAllocateAtIndex(rideIndex); const auto* rideEntry = GetRideEntryByIndex(rideEntryIndex); if (rideEntry == nullptr) { diff --git a/src/openrct2/park/ParkFile.cpp b/src/openrct2/park/ParkFile.cpp index 5799d3a1fd..46b5d93428 100644 --- a/src/openrct2/park/ParkFile.cpp +++ b/src/openrct2/park/ParkFile.cpp @@ -1193,7 +1193,7 @@ namespace OpenRCT2 // Ride ID cs.ReadWrite(rideId); - auto& ride = *GetOrAllocateRide(rideId); + auto& ride = *RideAllocateAtIndex(rideId); // Status cs.ReadWrite(ride.type); diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index d9e57794b0..48baaf5dbd 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -775,7 +775,7 @@ namespace RCT1 if (_s4.Rides[i].Type != RideType::Null) { const auto rideId = RideId::FromUnderlying(i); - ImportRide(GetOrAllocateRide(rideId), &_s4.Rides[i], rideId); + ImportRide(RideAllocateAtIndex(rideId), &_s4.Rides[i], rideId); } } } diff --git a/src/openrct2/rct2/S6Importer.cpp b/src/openrct2/rct2/S6Importer.cpp index 945ab8c109..5e68c1659b 100644 --- a/src/openrct2/rct2/S6Importer.cpp +++ b/src/openrct2/rct2/S6Importer.cpp @@ -703,7 +703,7 @@ namespace RCT2 if (src->Type != RIDE_TYPE_NULL) { const auto rideId = RideId::FromUnderlying(index); - auto dst = GetOrAllocateRide(rideId); + auto dst = RideAllocateAtIndex(rideId); ImportRide(dst, src, rideId); } } diff --git a/src/openrct2/ride/Ride.cpp b/src/openrct2/ride/Ride.cpp index 7169a69e7b..e39b800f53 100644 --- a/src/openrct2/ride/Ride.cpp +++ b/src/openrct2/ride/Ride.cpp @@ -95,7 +95,10 @@ static constexpr const int32_t RideInspectionInterval[] = { 10, 20, 30, 45, 60, 120, 0, 0, }; -static std::vector _rides; +static std::array _rides{}; + +// This is not the real size of rides in use, rather the highest slot used + 1. +static size_t _maxRideSize = 0; struct StationIndexWithMessage { @@ -124,7 +127,7 @@ RideManager GetRideManager() size_t RideManager::size() const { size_t count = 0; - for (size_t i = 0; i < _rides.size(); i++) + for (size_t i = 0; i < _maxRideSize; i++) { if (_rides[i].type != RIDE_TYPE_NULL) { @@ -136,64 +139,80 @@ size_t RideManager::size() const RideManager::Iterator RideManager::begin() { - const auto endIndex = static_cast(_rides.size()); - return RideManager::Iterator(*this, 0u, endIndex); + return RideManager::Iterator(*this, 0u, _maxRideSize); } RideManager::Iterator RideManager::end() { - const auto endIndex = static_cast(_rides.size()); - return RideManager::Iterator(*this, endIndex, endIndex); + return RideManager::Iterator(*this, _maxRideSize, _maxRideSize); } RideManager::Iterator RideManager::get(RideId rideId) { - return RideManager::Iterator(*this, rideId.ToUnderlying(), _rides.size()); + return RideManager::Iterator(*this, rideId.ToUnderlying(), _maxRideSize); } RideId GetNextFreeRideId() { - auto result = static_cast(_rides.size()); for (RideId::UnderlyingType i = 0; i < _rides.size(); i++) { if (_rides[i].type == RIDE_TYPE_NULL) { - result = i; - break; + return RideId::FromUnderlying(i); } } - if (result >= OpenRCT2::Limits::MaxRidesInPark) - { - return RideId::GetNull(); - } - return RideId::FromUnderlying(result); + return RideId::GetNull(); } -Ride* GetOrAllocateRide(RideId index) +Ride* RideAllocateAtIndex(RideId index) { const auto idx = index.ToUnderlying(); - if (_rides.size() <= idx) - { - _rides.resize(idx + 1); - } + _maxRideSize = std::max(idx + 1, _maxRideSize); auto result = &_rides[idx]; result->id = index; return result; } +void RideDelete(RideId id) +{ + const auto idx = id.ToUnderlying(); + + assert(idx < _rides.size()); + assert(_rides[idx].type != RIDE_TYPE_NULL); + + auto& ride = _rides[idx]; + ride.type = RIDE_TYPE_NULL; + ride.custom_name = {}; + ride.measurement = {}; + + while (_maxRideSize > 0 && _rides[_maxRideSize - 1].type == RIDE_TYPE_NULL) + { + _maxRideSize--; + } +} + Ride* GetRide(RideId index) { - const auto idx = index.ToUnderlying(); - if (idx < _rides.size()) + if (index.IsNull()) { - auto& ride = _rides[idx]; - if (ride.type != RIDE_TYPE_NULL) - { - assert(ride.id == index); - return &ride; - } + return nullptr; } + + const auto idx = index.ToUnderlying(); + assert(idx < _rides.size()); + if (idx >= _rides.size()) + { + return nullptr; + } + + auto& ride = _rides[idx]; + if (ride.type != RIDE_TYPE_NULL) + { + assert(ride.id == index); + return &ride; + } + return nullptr; } @@ -904,8 +923,8 @@ bool Ride::SupportsStatus(RideStatus s) const */ void RideInitAll() { - _rides.clear(); - _rides.shrink_to_fit(); + std::for_each(std::begin(_rides), std::end(_rides), [](auto& ride) { ride.type = RIDE_TYPE_NULL; }); + _maxRideSize = 0; } /** @@ -5119,9 +5138,7 @@ Vehicle* RideGetBrokenVehicle(const Ride& ride) */ void Ride::Delete() { - custom_name = {}; - measurement = {}; - type = RIDE_TYPE_NULL; + RideDelete(id); } void Ride::Renew() diff --git a/src/openrct2/ride/Ride.h b/src/openrct2/ride/Ride.h index fc02a57c5b..9e48f6b165 100644 --- a/src/openrct2/ride/Ride.h +++ b/src/openrct2/ride/Ride.h @@ -995,7 +995,9 @@ struct RideManager RideManager GetRideManager(); RideId GetNextFreeRideId(); -Ride* GetOrAllocateRide(RideId index); +Ride* RideAllocateAtIndex(RideId index); +void RideDelete(RideId id); + const RideObjectEntry* GetRideEntryByIndex(ObjectEntryIndex index); std::string_view GetRideEntryName(ObjectEntryIndex index); diff --git a/src/openrct2/ride/TrackDesign.cpp b/src/openrct2/ride/TrackDesign.cpp index c1a8c52004..a7c746fb72 100644 --- a/src/openrct2/ride/TrackDesign.cpp +++ b/src/openrct2/ride/TrackDesign.cpp @@ -339,7 +339,7 @@ ResultWithMessage TrackDesign::CreateTrackDesignTrack(TrackDesignState& tds, con } TrackDesignPreviewDrawOutlines( - tds, this, *GetOrAllocateRide(PreviewRideId), { 4096, 4096, 0, _currentTrackPieceDirection }); + tds, this, *RideAllocateAtIndex(PreviewRideId), { 4096, 4096, 0, _currentTrackPieceDirection }); // Resave global vars for scenery reasons. tds.Origin = startPos; @@ -459,7 +459,7 @@ ResultWithMessage TrackDesign::CreateTrackDesignMaze(TrackDesignState& tds, cons // Save global vars as they are still used by scenery???? int32_t startZ = tds.Origin.z; TrackDesignPreviewDrawOutlines( - tds, this, *GetOrAllocateRide(PreviewRideId), { 4096, 4096, 0, _currentTrackPieceDirection }); + tds, this, *RideAllocateAtIndex(PreviewRideId), { 4096, 4096, 0, _currentTrackPieceDirection }); tds.Origin = { startLoc.x, startLoc.y, startZ }; gMapSelectFlags &= ~MAP_SELECT_FLAG_ENABLE_CONSTRUCT; @@ -2038,7 +2038,7 @@ static bool TrackDesignPlacePreview(TrackDesignState& tds, TrackDesign* td6, mon _currentTrackPieceDirection = 0; int32_t z = TrackDesignGetZPlacement( - tds, td6, *GetOrAllocateRide(PreviewRideId), { mapSize.x, mapSize.y, 16, _currentTrackPieceDirection }); + tds, td6, *RideAllocateAtIndex(PreviewRideId), { mapSize.x, mapSize.y, 16, _currentTrackPieceDirection }); if (tds.HasScenery) {