From 1723161503b03b778df03b65b7e173b43e11a533 Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 11 Jan 2021 22:41:42 +0000 Subject: [PATCH] Optimise guest list sort Format all guest names in advance and store them in a list for sorting. This reduces the number of calls to format_string considerably. --- src/openrct2-ui/windows/GuestList.cpp | 62 +++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 9 deletions(-) diff --git a/src/openrct2-ui/windows/GuestList.cpp b/src/openrct2-ui/windows/GuestList.cpp index 9a4fbb28f4..7caf70b3a9 100644 --- a/src/openrct2-ui/windows/GuestList.cpp +++ b/src/openrct2-ui/windows/GuestList.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -114,6 +115,14 @@ private: uint8_t Faces[58]{}; }; + struct GuestItem + { + using CompareFunc = bool (*)(const GuestItem&, const GuestItem&); + + uint16_t Id; + char Name[256]; + }; + static constexpr const uint8_t SUMMARISED_GUEST_ROW_HEIGHT = SCROLLABLE_ROW_HEIGHT + 11; static constexpr const auto GUESTS_PER_PAGE = 2000; static constexpr const auto GUEST_PAGE_HEIGHT = GUESTS_PER_PAGE * SCROLLABLE_ROW_HEIGHT; @@ -134,7 +143,7 @@ private: uint32_t _lastFindGroupsWait{}; std::vector _groups; - std::vector _guestList; + std::vector _guestList; std::optional _highlightedIndex; uint32_t _tabAnimationIndex{}; @@ -542,11 +551,11 @@ public: { auto i = screenCoords.y / SCROLLABLE_ROW_HEIGHT; i += static_cast(_selectedPage * GUESTS_PER_PAGE); - for (auto spriteIndex : _guestList) + for (const auto& guestItem : _guestList) { if (i == 0) { - auto guest = GetEntity(spriteIndex); + auto guest = GetEntity(guestItem.Id); if (guest != nullptr) { window_guest_open(guest); @@ -601,6 +610,7 @@ public: else { _guestList.clear(); + for (auto peep : EntityList(EntityListId::Peep)) { sprite_set_flashing(peep, false); @@ -614,12 +624,16 @@ public: } if (!GuestShouldBeVisible(*peep)) continue; - _guestList.push_back(peep->sprite_index); + + auto& item = _guestList.emplace_back(); + item.Id = peep->sprite_index; + + Formatter ft; + peep->FormatNameTo(ft); + format_string(item.Name, sizeof(item.Name), STR_STRINGID, ft.Data()); } - std::sort(_guestList.begin(), _guestList.end(), [](const uint16_t a, const uint16_t b) { - return peep_compare(a, b) < 0; - }); + std::sort(_guestList.begin(), _guestList.end(), GetGuestCompareFunc()); } } @@ -642,7 +656,7 @@ private: { size_t index = 0; auto y = static_cast(_selectedPage) * -GUEST_PAGE_HEIGHT; - for (auto spriteIndex : _guestList) + for (const auto& guestItem : _guestList) { // Check if y is beyond the scroll control if (y + SCROLLABLE_ROW_HEIGHT + 1 >= -0x7FFF && y + SCROLLABLE_ROW_HEIGHT + 1 > dpi.y && y < 0x7FFF @@ -657,7 +671,7 @@ private: } // Guest name - auto peep = GetEntity(spriteIndex); + auto peep = GetEntity(guestItem.Id); if (peep == nullptr) { continue; @@ -914,6 +928,36 @@ private: return STR_GUESTS_FILTER_THINKING_ABOUT; } } + + template static bool CompareGuestItem(const GuestItem& a, const GuestItem& b) + { + const auto* peepA = GetEntity(a.Id); + const auto* peepB = GetEntity(b.Id); + if (peepA != nullptr && peepB != nullptr) + { + // Compare types + if (peepA->AssignedPeepType != peepB->AssignedPeepType) + { + return static_cast(peepA->AssignedPeepType) < static_cast(peepB->AssignedPeepType); + } + + // Compare name + if constexpr (!TRealNames) + { + if (peepA->Name == nullptr && peepB->Name == nullptr) + { + // Simple ID comparison for when both peeps use a number or a generated name + return peepA->Id < peepB->Id; + } + } + } + return strlogicalcmp(a.Name, b.Name) < 0; + } + + static GuestItem::CompareFunc GetGuestCompareFunc() + { + return gParkFlags & PARK_FLAGS_SHOW_REAL_GUEST_NAMES ? CompareGuestItem : CompareGuestItem; + } }; rct_window* window_guest_list_open()