* Determine default engine sorting and execute recorded ListOrderChanges from AlterVehicleListOrder. */
| 1373 | * Determine default engine sorting and execute recorded ListOrderChanges from AlterVehicleListOrder. |
| 1374 | */ |
| 1375 | void CommitVehicleListOrderChanges() |
| 1376 | { |
| 1377 | /* Build a list of EngineIDs. EngineIDs are sequential from 0 up to the number of pool items with no gaps. */ |
| 1378 | std::vector<EngineID> ordering(Engine::GetNumItems()); |
| 1379 | std::iota(std::begin(ordering), std::end(ordering), EngineID::Begin()); |
| 1380 | |
| 1381 | /* Pre-sort engines by scope-grfid and local index */ |
| 1382 | std::ranges::sort(ordering, EnginePreSort); |
| 1383 | |
| 1384 | /* Apply Insertion-Sort operations */ |
| 1385 | for (const ListOrderChange &loc : _list_order_changes) { |
| 1386 | EngineID source = loc.engine; |
| 1387 | |
| 1388 | Engine *engine_source = Engine::Get(source); |
| 1389 | if (engine_source->grf_prop.local_id == loc.target) continue; |
| 1390 | |
| 1391 | EngineID target = _engine_mngr.GetID(engine_source->type, loc.target, engine_source->grf_prop.grfid); |
| 1392 | if (target == EngineID::Invalid()) continue; |
| 1393 | |
| 1394 | auto it_source = std::ranges::find(ordering, source); |
| 1395 | auto it_target = std::ranges::find(ordering, target); |
| 1396 | |
| 1397 | assert(it_source != std::end(ordering) && it_target != std::end(ordering)); |
| 1398 | assert(it_source != it_target); |
| 1399 | |
| 1400 | /* Move just this item to before the target. */ |
| 1401 | Slide(it_source, std::next(it_source), it_target); |
| 1402 | } |
| 1403 | |
| 1404 | /* Store final sort-order */ |
| 1405 | for (uint16_t index = 0; const EngineID &eid : ordering) { |
| 1406 | Engine::Get(eid)->list_position = index; |
| 1407 | ++index; |
| 1408 | } |
| 1409 | |
| 1410 | /* Clear out the queue */ |
| 1411 | _list_order_changes.clear(); |
| 1412 | _list_order_changes.shrink_to_fit(); |
| 1413 | } |
| 1414 | |
| 1415 | /** |
| 1416 | * Fill the grf_cache of the given vehicle. |