45 byte vehicle_type; // The vehicle type that is sorted |
45 byte vehicle_type; // The vehicle type that is sorted |
46 list_d l; // General list struct |
46 list_d l; // General list struct |
47 } vehiclelist_d; |
47 } vehiclelist_d; |
48 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(vehiclelist_d)); |
48 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(vehiclelist_d)); |
49 |
49 |
50 static uint32 _internal_name_sorter_id; // internal StringID for default vehicle-names |
|
51 static const Vehicle* _last_vehicle; // cached vehicle to hopefully speed up name-sorting |
|
52 static bool _internal_sort_order; // descending/ascending |
50 static bool _internal_sort_order; // descending/ascending |
53 |
51 |
54 static RailType _railtype_selected_in_replace_gui; |
52 static RailType _railtype_selected_in_replace_gui; |
55 |
53 |
56 |
54 |
147 static void SortVehicleList(vehiclelist_d *vl) |
145 static void SortVehicleList(vehiclelist_d *vl) |
148 { |
146 { |
149 if (!(vl->l.flags & VL_RESORT)) return; |
147 if (!(vl->l.flags & VL_RESORT)) return; |
150 |
148 |
151 _internal_sort_order = vl->l.flags & VL_DESC; |
149 _internal_sort_order = vl->l.flags & VL_DESC; |
152 _internal_name_sorter_id = STR_SV_TRAIN_NAME; |
|
153 _last_vehicle = NULL; // used for "cache" in namesorting |
|
154 qsort((void*)vl->sort_list, vl->l.list_length, sizeof(vl->sort_list[0]), |
150 qsort((void*)vl->sort_list, vl->l.list_length, sizeof(vl->sort_list[0]), |
155 _vehicle_sorter[vl->l.sort_type]); |
151 _vehicle_sorter[vl->l.sort_type]); |
156 |
152 |
157 vl->l.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; |
153 vl->l.resort_timer = DAY_TICKS * PERIODIC_RESORT_DAYS; |
158 vl->l.flags &= ~VL_RESORT; |
154 vl->l.flags &= ~VL_RESORT; |
506 int r = va->unitnumber - vb->unitnumber; |
502 int r = va->unitnumber - vb->unitnumber; |
507 |
503 |
508 return (_internal_sort_order & 1) ? -r : r; |
504 return (_internal_sort_order & 1) ? -r : r; |
509 } |
505 } |
510 |
506 |
511 static char _bufcache[64]; // used together with _last_vehicle to hopefully speed up stringsorting |
|
512 static int CDECL VehicleNameSorter(const void *a, const void *b) |
507 static int CDECL VehicleNameSorter(const void *a, const void *b) |
513 { |
508 { |
|
509 static const Vehicle *last_vehicle[2] = { NULL, NULL }; |
|
510 static char last_name[2][64] = { "", "" }; |
|
511 |
514 const Vehicle* va = *(const Vehicle**)a; |
512 const Vehicle* va = *(const Vehicle**)a; |
515 const Vehicle* vb = *(const Vehicle**)b; |
513 const Vehicle* vb = *(const Vehicle**)b; |
516 char buf1[64] = "\0"; |
|
517 int r; |
514 int r; |
518 |
515 |
519 if (va->string_id != _internal_name_sorter_id) GetString(buf1, va->string_id); |
516 if (va != last_vehicle[0]) { |
520 |
517 last_vehicle[0] = va; |
521 if (vb != _last_vehicle) { |
518 if (IsCustomName(va->string_id)) { |
522 _last_vehicle = vb; |
519 GetString(last_name[0], va->string_id); |
523 _bufcache[0] = '\0'; |
520 } else { |
524 if (vb->string_id != _internal_name_sorter_id) { |
521 last_name[0][0] = '\0'; |
525 GetString(_bufcache, vb->string_id); |
522 } |
526 } |
523 } |
527 } |
524 |
528 |
525 if (vb != last_vehicle[1]) { |
529 r = strcmp(buf1, _bufcache); // sort by name |
526 last_vehicle[1] = vb; |
|
527 if (IsCustomName(vb->string_id)) { |
|
528 GetString(last_name[1], vb->string_id); |
|
529 } else { |
|
530 last_name[1][0] = '\0'; |
|
531 } |
|
532 } |
|
533 |
|
534 r = strcmp(last_name[0], last_name[1]); // sort by name |
530 |
535 |
531 VEHICLEUNITNUMBERSORTER(r, va, vb); |
536 VEHICLEUNITNUMBERSORTER(r, va, vb); |
532 |
537 |
533 return (_internal_sort_order & 1) ? -r : r; |
538 return (_internal_sort_order & 1) ? -r : r; |
534 } |
539 } |