From cfb995b6e99a6bb0e379c2664206f84b65950ac4 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Thu, 5 Dec 2024 22:17:40 +0000 Subject: [PATCH] Codechange: Reimplement engine sort order with std::rotate. (#13124) --- src/newgrf_engine.cpp | 51 +++++++++++++++++++------------------------ src/newgrf_engine.h | 2 +- 2 files changed, 23 insertions(+), 30 deletions(-) diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index 1d78504f88..bbad159637 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -1285,8 +1285,10 @@ void TriggerVehicle(Vehicle *v, VehicleTrigger trigger) /* Functions for changing the order of vehicle purchase lists */ struct ListOrderChange { - EngineID engine; - uint target; ///< local ID + EngineID engine; ///< Engine ID + uint16_t target; ///< GRF-local ID + + ListOrderChange(EngineID engine, uint16_t target) : engine(engine), target(target) {} }; static std::vector _list_order_changes; @@ -1297,10 +1299,10 @@ static std::vector _list_order_changes; * @param target Local engine ID to move \a engine in front of * @note All sorting is done later in CommitVehicleListOrderChanges */ -void AlterVehicleListOrder(EngineID engine, uint target) +void AlterVehicleListOrder(EngineID engine, uint16_t target) { /* Add the list order change to a queue */ - _list_order_changes.push_back({engine, target}); + _list_order_changes.emplace_back(engine, target); } /** @@ -1329,44 +1331,35 @@ static bool EnginePreSort(const EngineID &a, const EngineID &b) */ void CommitVehicleListOrderChanges() { + /* Build a list of EngineIDs. EngineIDs are sequential from 0 up to the number of pool items with no gaps. */ + std::vector ordering(Engine::GetNumItems()); + std::iota(std::begin(ordering), std::end(ordering), 0); + /* Pre-sort engines by scope-grfid and local index */ - std::vector ordering; - for (const Engine *e : Engine::Iterate()) { - ordering.push_back(e->index); - } - std::sort(ordering.begin(), ordering.end(), EnginePreSort); + std::ranges::sort(ordering, EnginePreSort); /* Apply Insertion-Sort operations */ - for (const ListOrderChange &it : _list_order_changes) { - EngineID source = it.engine; - uint local_target = it.target; + for (const ListOrderChange &loc : _list_order_changes) { + EngineID source = loc.engine; Engine *engine_source = Engine::Get(source); - if (engine_source->grf_prop.local_id == local_target) continue; + if (engine_source->grf_prop.local_id == loc.target) continue; - EngineID target = _engine_mngr.GetID(engine_source->type, local_target, engine_source->grf_prop.grfid); + EngineID target = _engine_mngr.GetID(engine_source->type, loc.target, engine_source->grf_prop.grfid); if (target == INVALID_ENGINE) continue; - int source_index = find_index(ordering, source); - int target_index = find_index(ordering, target); + auto it_source = std::ranges::find(ordering, source); + auto it_target = std::ranges::find(ordering, target); - assert(source_index >= 0 && target_index >= 0); - assert(source_index != target_index); + assert(it_source != std::end(ordering) && it_target != std::end(ordering)); + assert(it_source != it_target); - EngineID *list = ordering.data(); - if (source_index < target_index) { - --target_index; - for (int i = source_index; i < target_index; ++i) list[i] = list[i + 1]; - list[target_index] = source; - } else { - for (int i = source_index; i > target_index; --i) list[i] = list[i - 1]; - list[target_index] = source; - } + /* Move just this item to before the target. */ + Slide(it_source, std::next(it_source), it_target); } /* Store final sort-order */ - uint index = 0; - for (const EngineID &eid : ordering) { + for (uint16_t index = 0; const EngineID &eid : ordering) { Engine::Get(eid)->list_position = index; ++index; } diff --git a/src/newgrf_engine.h b/src/newgrf_engine.h index 88e8e41303..bc396e7620 100644 --- a/src/newgrf_engine.h +++ b/src/newgrf_engine.h @@ -122,7 +122,7 @@ enum VehicleTrigger { }; void TriggerVehicle(Vehicle *veh, VehicleTrigger trigger); -void AlterVehicleListOrder(EngineID engine, uint target); +void AlterVehicleListOrder(EngineID engine, uint16_t target); void CommitVehicleListOrderChanges(); EngineID GetNewEngineID(const GRFFile *file, VehicleType type, uint16_t internal_id);