summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPeterN <peter@fuzzle.org>2019-03-02 17:08:45 +0000
committerGitHub <noreply@github.com>2019-03-02 17:08:45 +0000
commitcbaf52fbe1aaf7fc34cd585739b4f9fc10af1ad8 (patch)
treed6d75c25d3301c784c1f3889a392b018b05973ca /src
parentc3bc7d657e84824bb2cfdea39f604c33110eaa14 (diff)
downloadopenttd-cbaf52fbe1aaf7fc34cd585739b4f9fc10af1ad8.tar.xz
Codechange: Sort and filter sign names directly rather than through string system. (#7304)
This provides a notable performance benefit in the Sign List window when there are many signs.
Diffstat (limited to 'src')
-rw-r--r--src/signs_gui.cpp48
1 files changed, 26 insertions, 22 deletions
diff --git a/src/signs_gui.cpp b/src/signs_gui.cpp
index 15adef089..56af6e665 100644
--- a/src/signs_gui.cpp
+++ b/src/signs_gui.cpp
@@ -41,11 +41,11 @@ struct SignList {
*/
typedef GUIList<const Sign *, StringFilter &> GUISignList;
- static const Sign *last_sign;
GUISignList signs;
StringFilter string_filter; ///< The match string to be used when the GUIList is (re)-sorted.
static bool match_case; ///< Should case sensitive matching be used?
+ static char default_name[64]; ///< Default sign name, used if Sign::name is NULL.
/**
* Creates a SignList with filtering disabled by default.
@@ -74,19 +74,17 @@ struct SignList {
/** Sort signs by their name */
static int CDECL SignNameSorter(const Sign * const *a, const Sign * const *b)
{
- static char buf_cache[64];
- char buf[64];
+ /* Signs are very very rarely using the default text, but there can also be
+ * a lot of them. Therefore a worthwhile performance gain can be made by
+ * directly comparing Sign::name instead of going through the string
+ * system for each comparison. */
+ const char *a_name = (*a)->name;
+ const char *b_name = (*b)->name;
- SetDParam(0, (*a)->index);
- GetString(buf, STR_SIGN_NAME, lastof(buf));
+ if (a_name == NULL) a_name = SignList::default_name;
+ if (b_name == NULL) b_name = SignList::default_name;
- if (*b != last_sign) {
- last_sign = *b;
- SetDParam(0, (*b)->index);
- GetString(buf_cache, STR_SIGN_NAME, lastof(buf_cache));
- }
-
- int r = strnatcmp(buf, buf_cache); // Sort by name (natural sorting).
+ int r = strnatcmp(a_name, b_name); // Sort by name (natural sorting).
return r != 0 ? r : ((*a)->index - (*b)->index);
}
@@ -94,21 +92,18 @@ struct SignList {
void SortSignsList()
{
if (!this->signs.Sort(&SignNameSorter)) return;
-
- /* Reset the name sorter sort cache */
- this->last_sign = NULL;
}
/** Filter sign list by sign name */
static bool CDECL SignNameFilter(const Sign * const *a, StringFilter &filter)
{
- /* Get sign string */
- char buf1[MAX_LENGTH_SIGN_NAME_CHARS * MAX_CHAR_LENGTH];
- SetDParam(0, (*a)->index);
- GetString(buf1, STR_SIGN_NAME, lastof(buf1));
+ /* Same performance benefit as above for sorting. */
+ const char *a_name = (*a)->name;
+
+ if (a_name == NULL) a_name = SignList::default_name;
filter.ResetState();
- filter.AddLine(buf1);
+ filter.AddLine(a_name);
return filter.GetState();
}
@@ -138,8 +133,8 @@ struct SignList {
}
};
-const Sign *SignList::last_sign = NULL;
bool SignList::match_case = false;
+char SignList::default_name[64];
/** Enum referring to the Hotkeys in the sign list window */
enum SignListHotkeys {
@@ -171,6 +166,15 @@ struct SignListWindow : Window, SignList {
this->BuildSortSignList();
}
+ virtual void OnInit()
+ {
+ /* Default sign name, used if Sign::name is NULL. */
+ GetString(SignList::default_name, STR_DEFAULT_SIGN_NAME, lastof(SignList::default_name));
+ this->signs.ForceResort();
+ this->SortSignsList();
+ this->SetDirty();
+ }
+
/**
* This function sets the filter string of the sign list. The contents of
* the edit widget is not updated by this function. Depending on if the
@@ -188,7 +192,7 @@ struct SignListWindow : Window, SignList {
virtual void OnPaint()
{
- if (this->signs.NeedRebuild()) this->BuildSortSignList();
+ if (!this->IsShaded() && this->signs.NeedRebuild()) this->BuildSortSignList();
this->DrawWidgets();
}