1
0
Fork 0

Codechange: Reimplement engine sort order with std::rotate. (#13124)

pull/13151/head
Peter Nelson 2024-12-05 22:17:40 +00:00 committed by GitHub
parent f56b6756f1
commit cfb995b6e9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 23 additions and 30 deletions

View File

@ -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<ListOrderChange> _list_order_changes;
@ -1297,10 +1299,10 @@ static std::vector<ListOrderChange> _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<EngineID> ordering(Engine::GetNumItems());
std::iota(std::begin(ordering), std::end(ordering), 0);
/* Pre-sort engines by scope-grfid and local index */
std::vector<EngineID> 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;
}

View File

@ -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);