mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2026-07-24 03:56:43 +00:00
Codechange: simplify the FiosItem sorter logic
This commit is contained in:
+15
-28
@@ -26,7 +26,6 @@
|
||||
#include "safeguards.h"
|
||||
|
||||
static std::string *_fios_path = nullptr;
|
||||
SortingBits _savegame_sort_order = SORT_BY_DATE | SORT_DESCENDING;
|
||||
|
||||
/* OS-specific functions are taken from their respective files (win32/unix .c) */
|
||||
extern bool FiosIsRoot(const std::string &path);
|
||||
@@ -36,22 +35,17 @@ extern void FiosGetDrives(FileList &file_list);
|
||||
/* get the name of an oldstyle savegame */
|
||||
extern std::string GetOldSaveGameName(std::string_view file);
|
||||
|
||||
/**
|
||||
* Compare two FiosItem's. Used with sort when sorting the file list.
|
||||
* @param other The FiosItem to compare to.
|
||||
* @return for ascending order: returns true if da < db. Vice versa for descending order.
|
||||
*/
|
||||
bool FiosItem::operator< (const FiosItem &other) const
|
||||
/** Sort files by their name. @copydoc GUIList::Sorter */
|
||||
bool FiosItemNameSorter(const FiosItem &a, const FiosItem &b)
|
||||
{
|
||||
int r = false;
|
||||
return StrNaturalCompare(a.title.GetDecodedString(), b.title.GetDecodedString()) < 0;
|
||||
}
|
||||
|
||||
if ((_savegame_sort_order & SORT_BY_NAME) == 0 && (*this).mtime != other.mtime) {
|
||||
r = ClampTo<int32_t>(this->mtime - other.mtime);
|
||||
} else {
|
||||
r = StrNaturalCompare(this->title.GetDecodedString(), other.title.GetDecodedString());
|
||||
}
|
||||
if (r == 0) return false;
|
||||
return (_savegame_sort_order & SORT_DESCENDING) ? r > 0 : r < 0;
|
||||
/** Sort files by their modification date, and name when they are equal. @copydoc GUIList::Sorter */
|
||||
bool FiosItemModificationDateSorter(const FiosItem &a, const FiosItem &b)
|
||||
{
|
||||
if (a.mtime == b.mtime) return FiosItemNameSorter(a, b);
|
||||
return a.mtime < b.mtime;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -333,11 +327,8 @@ static void FiosGetFileList(SaveLoadOperation fop, bool show_dirs, FiosGetTypeAn
|
||||
fios.title = GetEncodedString(STR_SAVELOAD_DIRECTORY, fios.name + PATHSEP);
|
||||
}
|
||||
|
||||
/* Sort the subdirs always by name, ascending, remember user-sorting order */
|
||||
SortingBits order = _savegame_sort_order;
|
||||
_savegame_sort_order = SORT_BY_NAME | SORT_ASCENDING;
|
||||
std::sort(file_list.begin() + sort_start, file_list.end());
|
||||
_savegame_sort_order = order;
|
||||
/* Sort the subdirs always ascending by name. */
|
||||
std::sort(file_list.begin() + sort_start, file_list.end(), FiosItemNameSorter);
|
||||
}
|
||||
|
||||
/* This is where to start sorting for the filenames */
|
||||
@@ -351,7 +342,7 @@ static void FiosGetFileList(SaveLoadOperation fop, bool show_dirs, FiosGetTypeAn
|
||||
scanner.Scan({}, subdir, true, true);
|
||||
}
|
||||
|
||||
std::sort(file_list.begin() + sort_start, file_list.end());
|
||||
std::sort(file_list.begin() + sort_start, file_list.end(), FiosItemSorter);
|
||||
|
||||
/* Show drives */
|
||||
FiosGetDrives(file_list);
|
||||
@@ -718,13 +709,9 @@ FiosNumberedSaveName::FiosNumberedSaveName(const std::string &prefix) : prefix(p
|
||||
scanner.Scan(".sav", *_autosave_path, false);
|
||||
|
||||
/* Find the number for the most recent save, if any. */
|
||||
if (list.begin() != list.end()) {
|
||||
SortingBits order = _savegame_sort_order;
|
||||
_savegame_sort_order = SORT_BY_DATE | SORT_DESCENDING;
|
||||
std::sort(list.begin(), list.end());
|
||||
_savegame_sort_order = order;
|
||||
|
||||
std::string name = list.begin()->title.GetDecodedString();
|
||||
if (!list.empty()) {
|
||||
auto elem = std::ranges::max_element(list, FiosItemModificationDateSorter);
|
||||
std::string name = elem->title.GetDecodedString();
|
||||
std::from_chars(name.data() + this->prefix.size(), name.data() + name.size(), this->number);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-11
@@ -80,7 +80,6 @@ struct FiosItem {
|
||||
int64_t mtime;
|
||||
EncodedString title;
|
||||
std::string name;
|
||||
bool operator< (const FiosItem &other) const;
|
||||
};
|
||||
|
||||
/** List of file information. */
|
||||
@@ -89,16 +88,9 @@ public:
|
||||
void BuildFileList(AbstractFileType abstract_filetype, SaveLoadOperation fop, bool show_dirs);
|
||||
const FiosItem *FindItem(std::string_view file);
|
||||
};
|
||||
|
||||
enum SortingBits : uint8_t {
|
||||
SORT_ASCENDING = 0,
|
||||
SORT_DESCENDING = 1,
|
||||
SORT_BY_DATE = 0,
|
||||
SORT_BY_NAME = 2
|
||||
};
|
||||
DECLARE_ENUM_AS_BIT_SET(SortingBits)
|
||||
|
||||
extern SortingBits _savegame_sort_order;
|
||||
bool FiosItemSorter(const FiosItem &a, const FiosItem &b);
|
||||
bool FiosItemNameSorter(const FiosItem &a, const FiosItem &b);
|
||||
bool FiosItemModificationDateSorter(const FiosItem &a, const FiosItem &b);
|
||||
|
||||
void ShowSaveLoadDialog(AbstractFileType abstract_filetype, SaveLoadOperation fop);
|
||||
|
||||
|
||||
+31
-9
@@ -43,6 +43,28 @@ LoadCheckData _load_check_data; ///< Data loaded from save during SL_LOAD_CHE
|
||||
static bool _fios_path_changed;
|
||||
static bool _savegame_sort_dirty;
|
||||
|
||||
/** The available sorters for FiosItems. */
|
||||
enum class SavegameSorter : uint8_t {
|
||||
Date, ///< Sort by date.
|
||||
Name, ///< Sort by name.
|
||||
};
|
||||
|
||||
static SavegameSorter _savegame_sorter = SavegameSorter::Date; ///< Sorter for savegames.
|
||||
static bool _savegame_sorter_ascending = false; ///< Sorter for savegames.
|
||||
|
||||
/** Sorts the FiosItems based on the savegame sorter and order. @copydoc GUIList::Sorter */
|
||||
bool FiosItemSorter(const FiosItem &a, const FiosItem &b)
|
||||
{
|
||||
switch (_savegame_sorter) {
|
||||
case SavegameSorter::Date:
|
||||
return _savegame_sorter_ascending ? FiosItemModificationDateSorter(a, b) : FiosItemModificationDateSorter(b, a);
|
||||
case SavegameSorter::Name:
|
||||
return _savegame_sorter_ascending ? FiosItemNameSorter(a, b) : FiosItemNameSorter(b, a);
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset read data.
|
||||
*/
|
||||
@@ -317,7 +339,7 @@ static void SortSaveGameList(FileList &file_list)
|
||||
}
|
||||
}
|
||||
|
||||
std::sort(file_list.begin() + sort_start, file_list.end() - sort_end);
|
||||
std::sort(file_list.begin() + sort_start, file_list.end() - sort_end, FiosItemSorter);
|
||||
}
|
||||
|
||||
struct SaveLoadWindow : public Window {
|
||||
@@ -491,8 +513,8 @@ public:
|
||||
switch (widget) {
|
||||
case WID_SL_SORT_BYNAME:
|
||||
case WID_SL_SORT_BYDATE:
|
||||
if (((_savegame_sort_order & SORT_BY_NAME) != 0) == (widget == WID_SL_SORT_BYNAME)) {
|
||||
this->DrawSortButtonState(widget, _savegame_sort_order & SORT_DESCENDING ? SBS_DOWN : SBS_UP);
|
||||
if ((_savegame_sorter == SavegameSorter::Name) == (widget == WID_SL_SORT_BYNAME)) {
|
||||
this->DrawSortButtonState(widget, _savegame_sorter_ascending ? SBS_UP : SBS_DOWN);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -667,16 +689,16 @@ public:
|
||||
void OnClick([[maybe_unused]] Point pt, WidgetID widget, [[maybe_unused]] int click_count) override
|
||||
{
|
||||
switch (widget) {
|
||||
case WID_SL_SORT_BYNAME: // Sort save names by name
|
||||
_savegame_sort_order = (_savegame_sort_order == SORT_BY_NAME) ?
|
||||
SORT_BY_NAME | SORT_DESCENDING : SORT_BY_NAME;
|
||||
case WID_SL_SORT_BYNAME: // Sort save games by name
|
||||
_savegame_sorter_ascending = _savegame_sorter != SavegameSorter::Name || !_savegame_sorter_ascending;
|
||||
_savegame_sorter = SavegameSorter::Name;
|
||||
_savegame_sort_dirty = true;
|
||||
this->SetDirty();
|
||||
break;
|
||||
|
||||
case WID_SL_SORT_BYDATE: // Sort save names by date
|
||||
_savegame_sort_order = (_savegame_sort_order == SORT_BY_DATE) ?
|
||||
SORT_BY_DATE | SORT_DESCENDING : SORT_BY_DATE;
|
||||
case WID_SL_SORT_BYDATE: // Sort save games by date
|
||||
_savegame_sorter_ascending = _savegame_sorter != SavegameSorter::Date || !_savegame_sorter_ascending;
|
||||
_savegame_sorter = SavegameSorter::Date;
|
||||
_savegame_sort_dirty = true;
|
||||
this->SetDirty();
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user