diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f9d42ae9..78252f227 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1690,7 +1690,6 @@ set_src(BASE GLOB_RECURSE src/base tl/allocator.h tl/array.h tl/range.h - tl/sorted_array.h tl/threading.h unicode/confusables.cpp unicode/confusables.h @@ -2504,7 +2503,6 @@ if(GTEST_FOUND OR DOWNLOAD_GTEST) secure_random.cpp serverbrowser.cpp serverinfo.cpp - sorted_array.cpp str.cpp strip_path_and_extension.cpp teehistorian.cpp diff --git a/src/base/tl/sorted_array.h b/src/base/tl/sorted_array.h deleted file mode 100644 index b7ae5bd0a..000000000 --- a/src/base/tl/sorted_array.h +++ /dev/null @@ -1,53 +0,0 @@ -/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ -/* If you are missing that file, acquire a complete release at teeworlds.com. */ -#ifndef BASE_TL_SORTED_ARRAY_H -#define BASE_TL_SORTED_ARRAY_H - -#include "base/tl/algorithm.h" -#include "base/tl/array.h" - -template> -class sorted_array : public array -{ - typedef array parent; - - // insert and size is not allowed - int insert(const T &item, typename parent::range r) - { - dbg_break(); - return 0; - } - int set_size(int new_size) - { - dbg_break(); - return 0; - } - -public: - typedef plain_range_sorted range; - - int add(const T &item) - { - return parent::insert(item, partition_binary(all(), item)); - } - - int add_unsorted(const T &item) - { - return parent::add(item); - } - - void sort_range() - { - if(parent::size() > 0) - sort(all()); - } - - /* - Function: all - Returns a sorted range that contains the whole array. - */ - range all() { return range(parent::list, parent::list + parent::num_elements); } - range all() const { return range(parent::list, parent::list + parent::num_elements); } -}; - -#endif // TL_FILE_SORTED_ARRAY_HPP diff --git a/src/engine/shared/uuid_manager.cpp b/src/engine/shared/uuid_manager.cpp index 01d39517d..dd16b55f1 100644 --- a/src/engine/shared/uuid_manager.cpp +++ b/src/engine/shared/uuid_manager.cpp @@ -112,7 +112,7 @@ void CUuidManager::RegisterName(int ID, const char *pName) CNameIndexed NameIndexed; NameIndexed.m_Uuid = Name.m_Uuid; NameIndexed.m_ID = GetIndex(ID); - m_aNamesSorted.add(NameIndexed); + m_aNamesSorted.insert(std::lower_bound(m_aNamesSorted.begin(), m_aNamesSorted.end(), NameIndexed), NameIndexed); } CUuid CUuidManager::GetUuid(int ID) const @@ -127,10 +127,13 @@ const char *CUuidManager::GetName(int ID) const int CUuidManager::LookupUuid(CUuid Uuid) const { - sorted_array::range Pos = ::find_binary(m_aNamesSorted.all(), Uuid); - if(!Pos.empty()) + CNameIndexed Needle; + Needle.m_Uuid = Uuid; + Needle.m_ID = 0; + auto Range = std::equal_range(m_aNamesSorted.begin(), m_aNamesSorted.end(), Needle); + if(std::distance(Range.first, Range.second) == 1) { - return GetID(Pos.front().m_ID); + return GetID(Range.first->m_ID); } return UUID_UNKNOWN; } diff --git a/src/engine/shared/uuid_manager.h b/src/engine/shared/uuid_manager.h index 87b4f2064..5a0798d5f 100644 --- a/src/engine/shared/uuid_manager.h +++ b/src/engine/shared/uuid_manager.h @@ -2,7 +2,7 @@ #define ENGINE_SHARED_UUID_MANAGER_H #include -#include +#include enum { @@ -42,8 +42,7 @@ struct CNameIndexed int m_ID; bool operator<(const CNameIndexed &Other) const { return m_Uuid < Other.m_Uuid; } - bool operator<(const CUuid &Other) const { return m_Uuid < Other; } - bool operator==(const CUuid &Other) const { return m_Uuid == Other; } + bool operator==(const CNameIndexed &Other) const { return m_Uuid == Other.m_Uuid; } }; class CPacker; @@ -52,7 +51,7 @@ class CUnpacker; class CUuidManager { array m_aNames; - sorted_array m_aNamesSorted; + std::vector m_aNamesSorted; public: void RegisterName(int ID, const char *pName); diff --git a/src/game/client/components/chat.cpp b/src/game/client/components/chat.cpp index c4d3ed7e9..98f16ae92 100644 --- a/src/game/client/components/chat.cpp +++ b/src/game/client/components/chat.cpp @@ -34,7 +34,7 @@ CChat::CChat() #define CHAT_COMMAND(name, params, flags, callback, userdata, help) RegisterCommand(name, params, flags, help); #include - m_Commands.sort_range(); + std::sort(m_Commands.begin(), m_Commands.end()); m_Mode = MODE_NONE; Reset(); @@ -42,7 +42,7 @@ CChat::CChat() void CChat::RegisterCommand(const char *pName, const char *pParams, int flags, const char *pHelp) { - m_Commands.add_unsorted(CCommand{pName, pParams}); + m_Commands.emplace_back(pName, pParams); } void CChat::RebuildChat() @@ -380,7 +380,7 @@ bool CChat::OnInput(IInput::CEvent Event) auto &Command = m_Commands[Index]; - if(str_startswith(Command.pName, pCommandStart)) + if(str_startswith(Command.m_pName, pCommandStart)) { pCompletionCommand = &Command; m_CompletionChosen = Index + SearchType * NumCommands; @@ -397,10 +397,10 @@ bool CChat::OnInput(IInput::CEvent Event) // add the command str_append(aBuf, "/", sizeof(aBuf)); - str_append(aBuf, pCompletionCommand->pName, sizeof(aBuf)); + str_append(aBuf, pCompletionCommand->m_pName, sizeof(aBuf)); // add separator - const char *pSeparator = pCompletionCommand->pParams[0] == '\0' ? "" : " "; + const char *pSeparator = pCompletionCommand->m_pParams[0] == '\0' ? "" : " "; str_append(aBuf, pSeparator, sizeof(aBuf)); if(*pSeparator) str_append(aBuf, pSeparator, sizeof(aBuf)); @@ -408,7 +408,7 @@ bool CChat::OnInput(IInput::CEvent Event) // add part after the name str_append(aBuf, m_Input.GetString() + m_PlaceholderOffset + m_PlaceholderLength, sizeof(aBuf)); - m_PlaceholderLength = str_length(pSeparator) + str_length(pCompletionCommand->pName) + 1; + m_PlaceholderLength = str_length(pSeparator) + str_length(pCompletionCommand->m_pName) + 1; m_OldChatStringLength = m_Input.GetLength(); m_Input.Set(aBuf); // TODO: Use Add instead m_Input.SetCursorOffset(m_PlaceholderOffset + m_PlaceholderLength); diff --git a/src/game/client/components/chat.h b/src/game/client/components/chat.h index ab122836c..645c57e2a 100644 --- a/src/game/client/components/chat.h +++ b/src/game/client/components/chat.h @@ -2,6 +2,8 @@ /* If you are missing that file, acquire a complete release at teeworlds.com. */ #ifndef GAME_CLIENT_COMPONENTS_CHAT_H #define GAME_CLIENT_COMPONENTS_CHAT_H +#include + #include #include @@ -91,15 +93,21 @@ class CChat : public CComponent struct CCommand { - const char *pName; - const char *pParams; + const char *m_pName; + const char *m_pParams; - bool operator<(const CCommand &Other) const { return str_comp(pName, Other.pName) < 0; } - bool operator<=(const CCommand &Other) const { return str_comp(pName, Other.pName) <= 0; } - bool operator==(const CCommand &Other) const { return str_comp(pName, Other.pName) == 0; } + CCommand() {} + CCommand(const char *pName, const char *pParams) : + m_pName(pName), m_pParams(pParams) + { + } + + bool operator<(const CCommand &Other) const { return str_comp(m_pName, Other.m_pName) < 0; } + bool operator<=(const CCommand &Other) const { return str_comp(m_pName, Other.m_pName) <= 0; } + bool operator==(const CCommand &Other) const { return str_comp(m_pName, Other.m_pName) == 0; } }; - sorted_array m_Commands; + std::vector m_Commands; bool m_ReverseTAB; struct CHistoryEntry diff --git a/src/game/client/components/console.cpp b/src/game/client/components/console.cpp index fe47a1388..4b6286c59 100644 --- a/src/game/client/components/console.cpp +++ b/src/game/client/components/console.cpp @@ -2,7 +2,6 @@ /* If you are missing that file, acquire a complete release at teeworlds.com. */ #include -#include #include #include diff --git a/src/game/client/components/controls.cpp b/src/game/client/components/controls.cpp index 460f03529..15b6fbe2d 100644 --- a/src/game/client/components/controls.cpp +++ b/src/game/client/components/controls.cpp @@ -1,7 +1,5 @@ /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ /* If you are missing that file, acquire a complete release at teeworlds.com. */ -#include - #include #include diff --git a/src/game/client/components/countryflags.cpp b/src/game/client/components/countryflags.cpp index 0ee749ccf..9ee715189 100644 --- a/src/game/client/components/countryflags.cpp +++ b/src/game/client/components/countryflags.cpp @@ -81,15 +81,15 @@ void CCountryFlags::LoadCountryflagsIndexfile() str_format(aBuf, sizeof(aBuf), "loaded country flag '%s'", aOrigin); Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "countryflags", aBuf); } - m_aCountryFlags.add_unsorted(CountryFlag); + m_aCountryFlags.push_back(CountryFlag); } io_close(File); - m_aCountryFlags.sort_range(); + std::sort(m_aCountryFlags.begin(), m_aCountryFlags.end()); // find index of default item - int DefaultIndex = 0, Index = 0; - for(sorted_array::range r = m_aCountryFlags.all(); !r.empty(); r.pop_front(), ++Index) - if(r.front().m_CountryCode == -1) + size_t DefaultIndex = 0; + for(size_t Index = 0; Index < m_aCountryFlags.size(); ++Index) + if(m_aCountryFlags[Index].m_CountryCode == -1) { DefaultIndex = Index; break; @@ -97,11 +97,11 @@ void CCountryFlags::LoadCountryflagsIndexfile() // init LUT if(DefaultIndex != 0) - for(int &CodeIndexLUT : m_CodeIndexLUT) + for(size_t &CodeIndexLUT : m_CodeIndexLUT) CodeIndexLUT = DefaultIndex; else mem_zero(m_CodeIndexLUT, sizeof(m_CodeIndexLUT)); - for(int i = 0; i < m_aCountryFlags.size(); ++i) + for(size_t i = 0; i < m_aCountryFlags.size(); ++i) m_CodeIndexLUT[maximum(0, (m_aCountryFlags[i].m_CountryCode - CODE_LB) % CODE_RANGE)] = i; } @@ -110,13 +110,13 @@ void CCountryFlags::OnInit() // load country flags m_aCountryFlags.clear(); LoadCountryflagsIndexfile(); - if(!m_aCountryFlags.size()) + if(m_aCountryFlags.empty()) { Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "countryflags", "failed to load country flags. folder='countryflags/'"); CCountryFlag DummyEntry; DummyEntry.m_CountryCode = -1; mem_zero(DummyEntry.m_aCountryCodeString, sizeof(DummyEntry.m_aCountryCodeString)); - m_aCountryFlags.add(DummyEntry); + m_aCountryFlags.push_back(DummyEntry); } m_FlagsQuadContainerIndex = Graphics()->CreateQuadContainer(false); @@ -126,7 +126,7 @@ void CCountryFlags::OnInit() Graphics()->QuadContainerUpload(m_FlagsQuadContainerIndex); } -int CCountryFlags::Num() const +size_t CCountryFlags::Num() const { return m_aCountryFlags.size(); } @@ -136,9 +136,9 @@ const CCountryFlags::CCountryFlag *CCountryFlags::GetByCountryCode(int CountryCo return GetByIndex(m_CodeIndexLUT[maximum(0, (CountryCode - CODE_LB) % CODE_RANGE)]); } -const CCountryFlags::CCountryFlag *CCountryFlags::GetByIndex(int Index) const +const CCountryFlags::CCountryFlag *CCountryFlags::GetByIndex(size_t Index) const { - return &m_aCountryFlags[maximum(0, Index % m_aCountryFlags.size())]; + return &m_aCountryFlags[Index % m_aCountryFlags.size()]; } void CCountryFlags::Render(int CountryCode, const ColorRGBA *pColor, float x, float y, float w, float h) diff --git a/src/game/client/components/countryflags.h b/src/game/client/components/countryflags.h index ac199087d..f3b2d1e57 100644 --- a/src/game/client/components/countryflags.h +++ b/src/game/client/components/countryflags.h @@ -2,9 +2,9 @@ /* If you are missing that file, acquire a complete release at teeworlds.com. */ #ifndef GAME_CLIENT_COMPONENTS_COUNTRYFLAGS_H #define GAME_CLIENT_COMPONENTS_COUNTRYFLAGS_H -#include #include #include +#include class CCountryFlags : public CComponent { @@ -21,9 +21,9 @@ public: virtual int Sizeof() const override { return sizeof(*this); } void OnInit() override; - int Num() const; + size_t Num() const; const CCountryFlag *GetByCountryCode(int CountryCode) const; - const CCountryFlag *GetByIndex(int Index) const; + const CCountryFlag *GetByIndex(size_t Index) const; void Render(int CountryCode, const ColorRGBA *pColor, float x, float y, float w, float h); private: @@ -33,8 +33,8 @@ private: CODE_UB = 999, CODE_RANGE = CODE_UB - CODE_LB + 1, }; - sorted_array m_aCountryFlags; - int m_CodeIndexLUT[CODE_RANGE]; + std::vector m_aCountryFlags; + size_t m_CodeIndexLUT[CODE_RANGE]; int m_FlagsQuadContainerIndex; diff --git a/src/game/client/components/effects.cpp b/src/game/client/components/effects.cpp index e3dafe12b..193db8433 100644 --- a/src/game/client/components/effects.cpp +++ b/src/game/client/components/effects.cpp @@ -1,8 +1,6 @@ /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ /* If you are missing that file, acquire a complete release at teeworlds.com. */ -#include - #include #include diff --git a/src/game/client/components/menus.cpp b/src/game/client/components/menus.cpp index 94c5074f8..6e24a59ff 100644 --- a/src/game/client/components/menus.cpp +++ b/src/game/client/components/menus.cpp @@ -3,8 +3,6 @@ #include -#include - #include #include @@ -1873,13 +1871,13 @@ int CMenus::Render() int OldSelected = -1; UiDoListboxStart(&s_ScrollValue, &Box, 50.0f, Localize("Country / Region"), "", m_pClient->m_CountryFlags.Num(), 6, OldSelected, s_ScrollValue); - for(int i = 0; i < m_pClient->m_CountryFlags.Num(); ++i) + for(size_t i = 0; i < m_pClient->m_CountryFlags.Num(); ++i) { const CCountryFlags::CCountryFlag *pEntry = m_pClient->m_CountryFlags.GetByIndex(i); if(pEntry->m_CountryCode == CurSelection) OldSelected = i; - CListboxItem Item = UiDoListboxNextItem(&pEntry->m_CountryCode, OldSelected == i); + CListboxItem Item = UiDoListboxNextItem(&pEntry->m_CountryCode, OldSelected >= 0 && (size_t)OldSelected == i); if(Item.m_Visible) { CUIRect Label; diff --git a/src/game/client/components/menus.h b/src/game/client/components/menus.h index 6a7b458cd..1482e07a0 100644 --- a/src/game/client/components/menus.h +++ b/src/game/client/components/menus.h @@ -3,10 +3,11 @@ #ifndef GAME_CLIENT_COMPONENTS_MENUS_H #define GAME_CLIENT_COMPONENTS_MENUS_H -#include #include #include +#include + #include #include #include @@ -252,11 +253,11 @@ public: }; protected: - sorted_array m_EntitiesList; - sorted_array m_GameList; - sorted_array m_EmoticonList; - sorted_array m_ParticlesList; - sorted_array m_HudList; + std::vector m_EntitiesList; + std::vector m_GameList; + std::vector m_EmoticonList; + std::vector m_ParticlesList; + std::vector m_HudList; bool m_IsInit = false; @@ -428,7 +429,6 @@ protected: } }; - //sorted_array m_lDemos; char m_aCurrentDemoFolder[256]; char m_aCurrentDemoFile[64]; int m_DemolistSelectedIndex; @@ -448,6 +448,12 @@ protected: const CFriendInfo *m_pFriendInfo; int m_NumFound; + CFriendItem() {} + CFriendItem(const CFriendInfo *pFriendInfo) : + m_pFriendInfo(pFriendInfo), m_NumFound(0) + { + } + bool operator<(const CFriendItem &Other) const { if(m_NumFound && !Other.m_NumFound) @@ -465,7 +471,7 @@ protected: } }; - sorted_array m_lFriends; + std::vector m_lFriends; int m_FriendlistSelectedIndex; void FriendlistOnUpdate(); @@ -616,7 +622,7 @@ public: // DDRace int DoButton_CheckBox_DontCare(const void *pID, const char *pText, int Checked, const CUIRect *pRect); - sorted_array m_lDemos; + std::vector m_lDemos; void DemolistPopulate(); bool m_Dummy; @@ -641,7 +647,7 @@ public: bool HasFile() const { return m_aFilename[0]; } }; - sorted_array m_lGhosts; + std::vector m_lGhosts; std::chrono::nanoseconds m_GhostPopulateStartTime{0}; diff --git a/src/game/client/components/menus_browser.cpp b/src/game/client/components/menus_browser.cpp index 85cef8271..244c90d2a 100644 --- a/src/game/client/components/menus_browser.cpp +++ b/src/game/client/components/menus_browser.cpp @@ -221,8 +221,8 @@ void CMenus::RenderServerbrowserServerList(CUIRect View) m_SelectedIndex = -1; // reset friend counter - for(int i = 0; i < m_lFriends.size(); m_lFriends[i++].m_NumFound = 0) - ; + for(auto &Friend : m_lFriends) + Friend.m_NumFound = 0; auto RenderBrowserIcons = [this](CUIElement::SUIElementRect &UIRect, CUIRect *pRect, const ColorRGBA &TextColor, const ColorRGBA &TextOutlineColor, const char *pText, ETextAlignment TextAlign, bool SmallFont = false) { float FontSize = 14.0f * UI()->Scale(); @@ -269,13 +269,13 @@ void CMenus::RenderServerbrowserServerList(CUIRect View) { unsigned NameHash = str_quickhash(pItem->m_aClients[j].m_aName); unsigned ClanHash = str_quickhash(pItem->m_aClients[j].m_aClan); - for(int f = 0; f < m_lFriends.size(); ++f) + for(auto &Friend : m_lFriends) { - if(((g_Config.m_ClFriendsIgnoreClan && m_lFriends[f].m_pFriendInfo->m_aName[0]) || (ClanHash == m_lFriends[f].m_pFriendInfo->m_ClanHash && !str_comp(m_lFriends[f].m_pFriendInfo->m_aClan, pItem->m_aClients[j].m_aClan))) && - (!m_lFriends[f].m_pFriendInfo->m_aName[0] || (NameHash == m_lFriends[f].m_pFriendInfo->m_NameHash && !str_comp(m_lFriends[f].m_pFriendInfo->m_aName, pItem->m_aClients[j].m_aName)))) + if(((g_Config.m_ClFriendsIgnoreClan && Friend.m_pFriendInfo->m_aName[0]) || (ClanHash == Friend.m_pFriendInfo->m_ClanHash && !str_comp(Friend.m_pFriendInfo->m_aClan, pItem->m_aClients[j].m_aClan))) && + (!Friend.m_pFriendInfo->m_aName[0] || (NameHash == Friend.m_pFriendInfo->m_NameHash && !str_comp(Friend.m_pFriendInfo->m_aName, pItem->m_aClients[j].m_aName)))) { - m_lFriends[f].m_NumFound++; - if(m_lFriends[f].m_pFriendInfo->m_aName[0]) + Friend.m_NumFound++; + if(Friend.m_pFriendInfo->m_aName[0]) break; } } @@ -1250,13 +1250,8 @@ void CMenus::FriendlistOnUpdate() { m_lFriends.clear(); for(int i = 0; i < m_pClient->Friends()->NumFriends(); ++i) - { - CFriendItem Item; - Item.m_pFriendInfo = m_pClient->Friends()->GetFriend(i); - Item.m_NumFound = 0; - m_lFriends.add_unsorted(Item); - } - m_lFriends.sort_range(); + m_lFriends.emplace_back(m_pClient->Friends()->GetFriend(i)); + std::sort(m_lFriends.begin(), m_lFriends.end()); } void CMenus::RenderServerbrowserFriends(CUIRect View) @@ -1286,14 +1281,14 @@ void CMenus::RenderServerbrowserFriends(CUIRect View) // friends list(remove friend) static float s_ScrollValue = 0; - if(m_FriendlistSelectedIndex >= m_lFriends.size()) + if(m_FriendlistSelectedIndex >= (int)m_lFriends.size()) m_FriendlistSelectedIndex = m_lFriends.size() - 1; UiDoListboxStart(&m_lFriends, &List, 30.0f, "", "", m_lFriends.size(), 1, m_FriendlistSelectedIndex, s_ScrollValue); - m_lFriends.sort_range(); - for(int i = 0; i < m_lFriends.size(); ++i) + std::sort(m_lFriends.begin(), m_lFriends.end()); + for(auto &Friend : m_lFriends) { - CListboxItem Item = UiDoListboxNextItem(&m_lFriends[i], false, false); + CListboxItem Item = UiDoListboxNextItem(&Friend.m_NumFound, false, false); if(Item.m_Visible) { @@ -1304,14 +1299,14 @@ void CMenus::RenderServerbrowserFriends(CUIRect View) Item.m_Rect.VMargin(2.5f, &Item.m_Rect); Item.m_Rect.HSplitTop(12.0f, &Item.m_Rect, &Button); - UI()->DoLabelScaled(&Item.m_Rect, m_lFriends[i].m_pFriendInfo->m_aName, FontSize, TEXTALIGN_LEFT); - UI()->DoLabelScaled(&Button, m_lFriends[i].m_pFriendInfo->m_aClan, FontSize, TEXTALIGN_LEFT); + UI()->DoLabelScaled(&Item.m_Rect, Friend.m_pFriendInfo->m_aName, FontSize, TEXTALIGN_LEFT); + UI()->DoLabelScaled(&Button, Friend.m_pFriendInfo->m_aClan, FontSize, TEXTALIGN_LEFT); - RenderTools()->DrawUIRect(&OnState, m_lFriends[i].m_NumFound ? ColorRGBA(0.0f, 1.0f, 0.0f, 0.25f) : ColorRGBA(1.0f, 0.0f, 0.0f, 0.25f), CUI::CORNER_R, 4.0f); + RenderTools()->DrawUIRect(&OnState, Friend.m_NumFound ? ColorRGBA(0.0f, 1.0f, 0.0f, 0.25f) : ColorRGBA(1.0f, 0.0f, 0.0f, 0.25f), CUI::CORNER_R, 4.0f); OnState.HMargin((OnState.h - FontSize) / 3, &OnState); OnState.VMargin(5.0f, &OnState); char aBuf[64]; - str_format(aBuf, sizeof(aBuf), "%i", m_lFriends[i].m_NumFound); + str_format(aBuf, sizeof(aBuf), "%i", Friend.m_NumFound); UI()->DoLabelScaled(&OnState, aBuf, FontSize + 2, TEXTALIGN_RIGHT); } } diff --git a/src/game/client/components/menus_demo.cpp b/src/game/client/components/menus_demo.cpp index 6c8013492..acc524477 100644 --- a/src/game/client/components/menus_demo.cpp +++ b/src/game/client/components/menus_demo.cpp @@ -767,7 +767,7 @@ int CMenus::DemolistFetchCallback(const CFsFileInfo *pInfo, int IsDir, int Stora } Item.m_IsDir = IsDir != 0; Item.m_StorageType = StorageType; - pSelf->m_lDemos.add_unsorted(Item); + pSelf->m_lDemos.push_back(Item); if(tw::time_get() - pSelf->m_DemoPopulateStartTime > 500ms) { @@ -788,7 +788,7 @@ void CMenus::DemolistPopulate() if(g_Config.m_BrDemoFetchInfo) FetchAllHeaders(); - m_lDemos.sort_range(); + std::stable_sort(m_lDemos.begin(), m_lDemos.end()); } void CMenus::DemolistOnUpdate(bool Reset) @@ -800,11 +800,11 @@ void CMenus::DemolistOnUpdate(bool Reset) bool Found = false; int SelectedIndex = -1; // search for selected index - for(sorted_array::range r = m_lDemos.all(); !r.empty(); r.pop_front()) + for(auto &Item : m_lDemos) { SelectedIndex++; - if(str_comp(g_Config.m_UiDemoSelected, r.front().m_aName) == 0) + if(str_comp(g_Config.m_UiDemoSelected, Item.m_aName) == 0) { Found = true; break; @@ -815,8 +815,8 @@ void CMenus::DemolistOnUpdate(bool Reset) m_DemolistSelectedIndex = SelectedIndex; } - m_DemolistSelectedIndex = Reset ? m_lDemos.size() > 0 ? 0 : -1 : - m_DemolistSelectedIndex >= m_lDemos.size() ? m_lDemos.size() - 1 : m_DemolistSelectedIndex; + m_DemolistSelectedIndex = Reset ? !m_lDemos.empty() ? 0 : -1 : + m_DemolistSelectedIndex >= (int)m_lDemos.size() ? m_lDemos.size() - 1 : m_DemolistSelectedIndex; m_DemolistSelectedIsDir = m_DemolistSelectedIndex < 0 ? false : m_lDemos[m_DemolistSelectedIndex].m_IsDir; } @@ -834,11 +834,11 @@ bool CMenus::FetchHeader(CDemoItem &Item) void CMenus::FetchAllHeaders() { - for(sorted_array::range r = m_lDemos.all(); !r.empty(); r.pop_front()) + for(auto &Item : m_lDemos) { - FetchHeader(r.front()); + FetchHeader(Item); } - m_lDemos.sort_range(); + std::stable_sort(m_lDemos.begin(), m_lDemos.end()); } void CMenus::RenderDemoList(CUIRect MainView) @@ -1070,7 +1070,7 @@ void CMenus::RenderDemoList(CUIRect MainView) } // Don't rescan in order to keep fetched headers, just resort - m_lDemos.sort_range(); + std::stable_sort(m_lDemos.begin(), m_lDemos.end()); DemolistOnUpdate(false); } } @@ -1095,13 +1095,13 @@ void CMenus::RenderDemoList(CUIRect MainView) CUIRect OriginalView = ListBox; int Num = (int)(ListBox.h / s_aCols[0].m_Rect.h) + 1; - int ScrollNum = maximum(m_lDemos.size() - Num + 1, 0); + int ScrollNum = maximum(m_lDemos.size() - Num + 1, 0); ListBox.y -= s_ScrollValue * ScrollNum * s_aCols[0].m_Rect.h; int ItemIndex = -1; bool DoubleClicked = false; - for(sorted_array::range r = m_lDemos.all(); !r.empty(); r.pop_front()) + for(auto &Item : m_lDemos) { ItemIndex++; @@ -1126,10 +1126,10 @@ void CMenus::RenderDemoList(CUIRect MainView) RenderTools()->DrawUIRect(&Rect, ColorRGBA(1, 1, 1, 0.25f), CUI::CORNER_ALL, 4.0f); } - if(UI()->DoButtonLogic(r.front().m_aName, Selected, &Row)) + if(UI()->DoButtonLogic(Item.m_aName, Selected, &Row)) { DoubleClicked |= ItemIndex == m_DoubleClickIndex; - str_copy(g_Config.m_UiDemoSelected, r.front().m_aName, sizeof(g_Config.m_UiDemoSelected)); + str_copy(g_Config.m_UiDemoSelected, Item.m_aName, sizeof(g_Config.m_UiDemoSelected)); DemolistOnUpdate(false); m_DoubleClickIndex = ItemIndex; } @@ -1152,7 +1152,7 @@ void CMenus::RenderDemoList(CUIRect MainView) if(ID == COL_ICON) { - DoButton_Icon(IMAGE_FILEICONS, r.front().m_IsDir ? SPRITE_FILE_FOLDER : SPRITE_FILE_DEMO1, &Button); + DoButton_Icon(IMAGE_FILEICONS, Item.m_IsDir ? SPRITE_FILE_FOLDER : SPRITE_FILE_DEMO1, &Button); } else if(ID == COL_DEMONAME) { @@ -1160,27 +1160,27 @@ void CMenus::RenderDemoList(CUIRect MainView) TextRender()->SetCursor(&Cursor, Button.x, Button.y + (Button.h - 12.0f * UI()->Scale()) / 2.f, 12.0f * UI()->Scale(), TEXTFLAG_RENDER | TEXTFLAG_STOP_AT_END); Cursor.m_LineWidth = Button.w; - TextRender()->TextEx(&Cursor, r.front().m_aName, -1); + TextRender()->TextEx(&Cursor, Item.m_aName, -1); } - else if(ID == COL_MARKERS && !r.front().m_IsDir && r.front().m_InfosLoaded) + else if(ID == COL_MARKERS && !Item.m_IsDir && Item.m_InfosLoaded) { char aBuf[3]; - str_format(aBuf, sizeof(aBuf), "%d", r.front().NumMarkers()); + str_format(aBuf, sizeof(aBuf), "%d", Item.NumMarkers()); Button.VMargin(4.0f, &Button); UI()->DoLabelScaled(&Button, aBuf, 12.0f, TEXTALIGN_RIGHT); } - else if(ID == COL_LENGTH && !r.front().m_IsDir && r.front().m_InfosLoaded) + else if(ID == COL_LENGTH && !Item.m_IsDir && Item.m_InfosLoaded) { - int Length = r.front().Length(); + int Length = Item.Length(); char aBuf[32]; str_time((int64_t)Length * 100, TIME_HOURS, aBuf, sizeof(aBuf)); Button.VMargin(4.0f, &Button); UI()->DoLabelScaled(&Button, aBuf, 12.0f, TEXTALIGN_RIGHT); } - else if(ID == COL_DATE && !r.front().m_IsDir) + else if(ID == COL_DATE && !Item.m_IsDir) { char aBuf[64]; - str_timestamp_ex(r.front().m_Date, aBuf, sizeof(aBuf), FORMAT_SPACE); + str_timestamp_ex(Item.m_Date, aBuf, sizeof(aBuf), FORMAT_SPACE); Button.VSplitRight(24.0f, &Button, 0); UI()->DoLabelScaled(&Button, aBuf, 12.0f, TEXTALIGN_RIGHT); } diff --git a/src/game/client/components/menus_ingame.cpp b/src/game/client/components/menus_ingame.cpp index f741f4426..4a62b26ed 100644 --- a/src/game/client/components/menus_ingame.cpp +++ b/src/game/client/components/menus_ingame.cpp @@ -918,7 +918,7 @@ int CMenus::GhostlistFetchCallback(const char *pName, int IsDir, int StorageType str_copy(Item.m_aPlayer, Info.m_aOwner, sizeof(Item.m_aPlayer)); Item.m_Time = Info.m_Time; if(Item.m_Time > 0) - pSelf->m_lGhosts.add(Item); + pSelf->m_lGhosts.push_back(Item); if(tw::time_get() - pSelf->m_GhostPopulateStartTime > 500ms) { @@ -930,16 +930,15 @@ int CMenus::GhostlistFetchCallback(const char *pName, int IsDir, int StorageType void CMenus::GhostlistPopulate() { - CGhostItem *pOwnGhost = 0; m_lGhosts.clear(); m_GhostPopulateStartTime = tw::time_get(); Storage()->ListDirectory(IStorage::TYPE_ALL, m_pClient->m_Ghost.GetGhostDir(), GhostlistFetchCallback, this); + std::sort(m_lGhosts.begin(), m_lGhosts.end()); - for(int i = 0; i < m_lGhosts.size(); i++) - { - if(str_comp(m_lGhosts[i].m_aPlayer, Client()->PlayerName()) == 0 && (!pOwnGhost || m_lGhosts[i] < *pOwnGhost)) - pOwnGhost = &m_lGhosts[i]; - } + CGhostItem *pOwnGhost = 0; + for(auto &Ghost : m_lGhosts) + if(str_comp(Ghost.m_aPlayer, Client()->PlayerName()) == 0 && (!pOwnGhost || Ghost < *pOwnGhost)) + pOwnGhost = &Ghost; if(pOwnGhost) { @@ -950,16 +949,16 @@ void CMenus::GhostlistPopulate() CMenus::CGhostItem *CMenus::GetOwnGhost() { - for(int i = 0; i < m_lGhosts.size(); i++) - if(m_lGhosts[i].m_Own) - return &m_lGhosts[i]; - return 0; + for(auto &Ghost : m_lGhosts) + if(Ghost.m_Own) + return &Ghost; + return nullptr; } void CMenus::UpdateOwnGhost(CGhostItem Item) { int Own = -1; - for(int i = 0; i < m_lGhosts.size(); i++) + for(size_t i = 0; i < m_lGhosts.size(); i++) if(m_lGhosts[i].m_Own) Own = i; @@ -972,14 +971,14 @@ void CMenus::UpdateOwnGhost(CGhostItem Item) } Item.m_Own = true; - m_lGhosts.add(Item); + m_lGhosts.insert(std::lower_bound(m_lGhosts.begin(), m_lGhosts.end(), Item), Item); } void CMenus::DeleteGhostItem(int Index) { if(m_lGhosts[Index].HasFile()) Storage()->RemoveFile(m_lGhosts[Index].m_aFilename, IStorage::TYPE_SAVE); - m_lGhosts.remove_index(Index); + m_lGhosts.erase(m_lGhosts.begin() + Index); } void CMenus::RenderGhost(CUIRect MainView) @@ -1158,7 +1157,7 @@ void CMenus::RenderGhost(CUIRect MainView) GhostlistPopulate(); } - if(s_SelectedIndex == -1 || s_SelectedIndex >= m_lGhosts.size()) + if(s_SelectedIndex == -1 || s_SelectedIndex >= (int)m_lGhosts.size()) return; CGhostItem *pGhost = &m_lGhosts[s_SelectedIndex]; diff --git a/src/game/client/components/menus_settings.cpp b/src/game/client/components/menus_settings.cpp index 93cafa14f..15ef1552f 100644 --- a/src/game/client/components/menus_settings.cpp +++ b/src/game/client/components/menus_settings.cpp @@ -408,13 +408,13 @@ void CMenus::RenderSettingsPlayer(CUIRect MainView) int OldSelected = -1; UiDoListboxStart(&s_ScrollValue, &MainView, 50.0f, Localize("Country / Region"), "", m_pClient->m_CountryFlags.Num(), 6, OldSelected, s_ScrollValue); - for(int i = 0; i < m_pClient->m_CountryFlags.Num(); ++i) + for(size_t i = 0; i < m_pClient->m_CountryFlags.Num(); ++i) { const CCountryFlags::CCountryFlag *pEntry = m_pClient->m_CountryFlags.GetByIndex(i); if(pEntry->m_CountryCode == *pCountry) OldSelected = i; - CListboxItem Item = UiDoListboxNextItem(&pEntry->m_CountryCode, OldSelected == i, s_ListBoxUsed); + CListboxItem Item = UiDoListboxNextItem(&pEntry->m_CountryCode, OldSelected >= 0 && (size_t)OldSelected == i, s_ListBoxUsed); if(Item.m_Visible) { Item.m_Rect.Margin(5.0f, &Item.m_Rect); @@ -673,12 +673,12 @@ void CMenus::RenderSettingsTee(CUIRect MainView) // skin selector MainView.HSplitTop(20.0f, 0, &MainView); MainView.HSplitTop(230.0f - RenderEyesBelow * 25.0f, &SkinList, &MainView); - static sorted_array s_paSkinList; + static std::vector s_vSkinList; static int s_SkinCount = 0; static float s_ScrollValue = 0.0f; if(s_InitSkinlist || m_pClient->m_Skins.Num() != s_SkinCount) { - s_paSkinList.clear(); + s_vSkinList.clear(); for(int i = 0; i < m_pClient->m_Skins.Num(); ++i) { const CSkin *s = m_pClient->m_Skins.Get(i); @@ -698,22 +698,23 @@ void CMenus::RenderSettingsTee(CUIRect MainView) if(s == 0) continue; - s_paSkinList.add(CUISkin(s)); + s_vSkinList.emplace_back(s); } + std::sort(s_vSkinList.begin(), s_vSkinList.end()); s_InitSkinlist = false; s_SkinCount = m_pClient->m_Skins.Num(); } int OldSelected = -1; - UiDoListboxStart(&s_InitSkinlist, &SkinList, 50.0f, Localize("Skins"), "", s_paSkinList.size(), 4, OldSelected, s_ScrollValue); - for(int i = 0; i < s_paSkinList.size(); ++i) + UiDoListboxStart(&s_InitSkinlist, &SkinList, 50.0f, Localize("Skins"), "", s_vSkinList.size(), 4, OldSelected, s_ScrollValue); + for(size_t i = 0; i < s_vSkinList.size(); ++i) { - const CSkin *s = s_paSkinList[i].m_pSkin; + const CSkin *s = s_vSkinList[i].m_pSkin; if(str_comp(s->m_aName, pSkinName) == 0) OldSelected = i; - CListboxItem Item = UiDoListboxNextItem(s_paSkinList[i].m_pSkin, OldSelected == i); + CListboxItem Item = UiDoListboxNextItem(s, OldSelected >= 0 && (size_t)OldSelected == i); if(Item.m_Visible) { CTeeRenderInfo Info = OwnSkinInfo; @@ -728,10 +729,9 @@ void CMenus::RenderSettingsTee(CUIRect MainView) RenderTools()->RenderTee(pIdleState, &Info, Emote, vec2(1.0f, 0.0f), TeeRenderPos); Item.m_Rect.VSplitLeft(60.0f, 0, &Item.m_Rect); - str_format(aBuf, sizeof(aBuf), "%s", s->m_aName); SLabelProperties Props; Props.m_MaxWidth = Item.m_Rect.w; - UI()->DoLabelScaled(&Item.m_Rect, aBuf, 12.0f, TEXTALIGN_LEFT, Props); + UI()->DoLabelScaled(&Item.m_Rect, s->m_aName, 12.0f, TEXTALIGN_LEFT, Props); if(g_Config.m_Debug) { ColorRGBA BloodColor = *UseCustomColor ? color_cast(ColorHSLA(*ColorBody)) : s->m_BloodColor; @@ -748,7 +748,7 @@ void CMenus::RenderSettingsTee(CUIRect MainView) const int NewSelected = UiDoListboxEnd(&s_ScrollValue, 0); if(OldSelected != NewSelected) { - mem_copy(pSkinName, s_paSkinList[NewSelected].m_pSkin->m_aName, sizeof(g_Config.m_ClPlayerSkin)); + mem_copy(pSkinName, s_vSkinList[NewSelected].m_pSkin->m_aName, sizeof(g_Config.m_ClPlayerSkin)); SetNeedSendInfo(); } @@ -1704,7 +1704,7 @@ public: bool operator<(const CLanguage &Other) const { return m_Name < Other.m_Name; } }; -void LoadLanguageIndexfile(IStorage *pStorage, IConsole *pConsole, sorted_array *pLanguages) +void LoadLanguageIndexfile(IStorage *pStorage, IConsole *pConsole, std::vector &Languages) { IOHANDLE File = pStorage->OpenFile("languages/index.txt", IOFLAG_READ | IOFLAG_SKIP_BOM, IStorage::TYPE_ALL); if(!File) @@ -1759,7 +1759,7 @@ void LoadLanguageIndexfile(IStorage *pStorage, IConsole *pConsole, sorted_array< char aFileName[IO_MAX_PATH_LENGTH]; str_format(aFileName, sizeof(aFileName), "languages/%s.txt", aOrigin); - pLanguages->add(CLanguage(aReplacement, aFileName, str_toint(pLine + 3))); + Languages.emplace_back(aReplacement, aFileName, str_toint(pLine + 3)); } io_close(File); } @@ -1768,14 +1768,15 @@ void CMenus::RenderLanguageSelection(CUIRect MainView) { static int s_LanguageList = 0; static int s_SelectedLanguage = 0; - static sorted_array s_Languages; + static std::vector s_Languages; static float s_ScrollValue = 0; - if(s_Languages.size() == 0) + if(s_Languages.empty()) { - s_Languages.add(CLanguage("English", "", 826)); - LoadLanguageIndexfile(Storage(), Console(), &s_Languages); - for(int i = 0; i < s_Languages.size(); i++) + s_Languages.emplace_back("English", "", 826); + LoadLanguageIndexfile(Storage(), Console(), s_Languages); + std::sort(s_Languages.begin(), s_Languages.end()); + for(size_t i = 0; i < s_Languages.size(); i++) if(str_comp(s_Languages[i].m_FileName.c_str(), g_Config.m_ClLanguagefile) == 0) { s_SelectedLanguage = i; @@ -1787,10 +1788,9 @@ void CMenus::RenderLanguageSelection(CUIRect MainView) UiDoListboxStart(&s_LanguageList, &MainView, 24.0f, Localize("Language"), "", s_Languages.size(), 1, s_SelectedLanguage, s_ScrollValue); - for(sorted_array::range r = s_Languages.all(); !r.empty(); r.pop_front()) + for(auto &Language : s_Languages) { - CListboxItem Item = UiDoListboxNextItem(&r.front()); - + CListboxItem Item = UiDoListboxNextItem(&Language.m_Name); if(Item.m_Visible) { CUIRect Rect; @@ -1798,9 +1798,9 @@ void CMenus::RenderLanguageSelection(CUIRect MainView) Rect.VMargin(6.0f, &Rect); Rect.HMargin(3.0f, &Rect); ColorRGBA Color(1.0f, 1.0f, 1.0f, 1.0f); - m_pClient->m_CountryFlags.Render(r.front().m_CountryCode, &Color, Rect.x, Rect.y, Rect.w, Rect.h); + m_pClient->m_CountryFlags.Render(Language.m_CountryCode, &Color, Rect.x, Rect.y, Rect.w, Rect.h); Item.m_Rect.HSplitTop(2.0f, 0, &Item.m_Rect); - UI()->DoLabelScaled(&Item.m_Rect, r.front().m_Name.c_str(), 16.0f, TEXTALIGN_LEFT); + UI()->DoLabelScaled(&Item.m_Rect, Language.m_Name.c_str(), 16.0f, TEXTALIGN_LEFT); } } diff --git a/src/game/client/components/menus_settings_assets.cpp b/src/game/client/components/menus_settings_assets.cpp index e7c50ee39..2d64a9246 100644 --- a/src/game/client/components/menus_settings_assets.cpp +++ b/src/game/client/components/menus_settings_assets.cpp @@ -101,7 +101,7 @@ int CMenus::EntitiesScan(const char *pName, int IsDir, int DirType, void *pUser) SCustomEntities EntitiesItem; str_copy(EntitiesItem.m_aName, pName, sizeof(EntitiesItem.m_aName)); CMenus::LoadEntities(&EntitiesItem, pUser); - pThis->m_EntitiesList.add(EntitiesItem); + pThis->m_EntitiesList.push_back(EntitiesItem); } else { @@ -116,7 +116,7 @@ int CMenus::EntitiesScan(const char *pName, int IsDir, int DirType, void *pUser) SCustomEntities EntitiesItem; str_copy(EntitiesItem.m_aName, aName, sizeof(EntitiesItem.m_aName)); CMenus::LoadEntities(&EntitiesItem, pUser); - pThis->m_EntitiesList.add(EntitiesItem); + pThis->m_EntitiesList.push_back(EntitiesItem); } } @@ -162,7 +162,7 @@ static void LoadAsset(TName *pAssetItem, const char *pAssetName, IGraphics *pGra } template -static int AssetScan(const char *pName, int IsDir, int DirType, sorted_array &AssetList, const char *pAssetName, IGraphics *pGraphics, void *pUser) +static int AssetScan(const char *pName, int IsDir, int DirType, std::vector &AssetList, const char *pAssetName, IGraphics *pGraphics, void *pUser) { auto *pRealUser = (SMenuAssetScanUser *)pUser; if(IsDir) @@ -177,7 +177,7 @@ static int AssetScan(const char *pName, int IsDir, int DirType, sorted_arraym_HudList, "hud", pGraphics, pUser); } -static sorted_array s_SearchEntitiesList; -static sorted_array s_SearchGamesList; -static sorted_array s_SearchEmoticonsList; -static sorted_array s_SearchParticlesList; -static sorted_array s_SearchHudList; +static std::vector s_SearchEntitiesList; +static std::vector s_SearchGamesList; +static std::vector s_SearchEmoticonsList; +static std::vector s_SearchParticlesList; +static std::vector s_SearchHudList; static const int NumberOfAssetsTabs = 5; static bool s_InitCustomList[NumberOfAssetsTabs] = { true, }; -static int s_CustomListSize[NumberOfAssetsTabs] = { +static size_t s_CustomListSize[NumberOfAssetsTabs] = { 0, }; @@ -252,7 +252,7 @@ static char s_aFilterString[NumberOfAssetsTabs][50]; static int s_CurCustomTab = ASSETS_TAB_ENTITIES; -static const CMenus::SCustomItem *GetCustomItem(int CurTab, int Index) +static const CMenus::SCustomItem *GetCustomItem(int CurTab, size_t Index) { if(CurTab == ASSETS_TAB_ENTITIES) return s_SearchEntitiesList[Index]; @@ -269,9 +269,9 @@ static const CMenus::SCustomItem *GetCustomItem(int CurTab, int Index) } template -void ClearAssetList(sorted_array &List, IGraphics *pGraphics) +void ClearAssetList(std::vector &List, IGraphics *pGraphics) { - for(int i = 0; i < List.size(); ++i) + for(size_t i = 0; i < List.size(); ++i) { if(List[i].m_RenderTexture.IsValid()) pGraphics->UnloadTexture(&(List[i].m_RenderTexture)); @@ -284,9 +284,9 @@ void CMenus::ClearCustomItems(int CurTab) { if(CurTab == ASSETS_TAB_ENTITIES) { - for(int i = 0; i < m_EntitiesList.size(); ++i) + for(auto &Entity : m_EntitiesList) { - for(auto &Image : m_EntitiesList[i].m_aImages) + for(auto &Image : Entity.m_aImages) { if(Image.m_Texture.IsValid()) Graphics()->UnloadTexture(&Image.m_Texture); @@ -330,24 +330,25 @@ void CMenus::ClearCustomItems(int CurTab) } template -void InitAssetList(sorted_array &AssetList, const char *pAssetPath, const char *pAssetName, FS_LISTDIR_CALLBACK pfnCallback, IGraphics *pGraphics, IStorage *pStorage, TCaller Caller) +void InitAssetList(std::vector &AssetList, const char *pAssetPath, const char *pAssetName, FS_LISTDIR_CALLBACK pfnCallback, IGraphics *pGraphics, IStorage *pStorage, TCaller Caller) { - if(AssetList.size() == 0) + if(AssetList.empty()) { TName AssetItem; str_copy(AssetItem.m_aName, "default", sizeof(AssetItem.m_aName)); LoadAsset(&AssetItem, pAssetName, pGraphics, Caller); - AssetList.add(AssetItem); + AssetList.push_back(AssetItem); // load assets pStorage->ListDirectory(IStorage::TYPE_ALL, pAssetPath, pfnCallback, Caller); + std::sort(AssetList.begin(), AssetList.end()); } if(AssetList.size() != s_CustomListSize[s_CurCustomTab]) s_InitCustomList[s_CurCustomTab] = true; } template -int InitSearchList(sorted_array &SearchList, sorted_array &AssetList) +int InitSearchList(std::vector &SearchList, std::vector &AssetList) { SearchList.clear(); int ListSize = AssetList.size(); @@ -359,7 +360,7 @@ int InitSearchList(sorted_array &SearchList, sorted_array if(s_aFilterString[s_CurCustomTab][0] != '\0' && !str_utf8_find_nocase(s->m_aName, s_aFilterString[s_CurCustomTab])) continue; - SearchList.add_unsorted(s); + SearchList.push_back(s); } return AssetList.size(); } @@ -397,15 +398,16 @@ void CMenus::RenderSettingsCustom(CUIRect MainView) }; if(s_CurCustomTab == ASSETS_TAB_ENTITIES) { - if(m_EntitiesList.size() == 0) + if(m_EntitiesList.empty()) { SCustomEntities EntitiesItem; str_copy(EntitiesItem.m_aName, "default", sizeof(EntitiesItem.m_aName)); LoadEntities(&EntitiesItem, &User); - m_EntitiesList.add(EntitiesItem); + m_EntitiesList.push_back(EntitiesItem); // load entities Storage()->ListDirectory(IStorage::TYPE_ALL, "assets/entities", EntitiesScan, &User); + std::sort(m_EntitiesList.begin(), m_EntitiesList.end()); } if(m_EntitiesList.size() != s_CustomListSize[s_CurCustomTab]) s_InitCustomList[s_CurCustomTab] = true; @@ -447,7 +449,7 @@ void CMenus::RenderSettingsCustom(CUIRect MainView) if(s_aFilterString[s_CurCustomTab][0] != '\0' && !str_utf8_find_nocase(s->m_aName, s_aFilterString[s_CurCustomTab])) continue; - s_SearchEntitiesList.add_unsorted(s); + s_SearchEntitiesList.push_back(s); } } else if(s_CurCustomTab == ASSETS_TAB_GAME) @@ -475,7 +477,7 @@ void CMenus::RenderSettingsCustom(CUIRect MainView) float TextureWidth = 150; float TextureHeight = 150; - int SearchListSize = 0; + size_t SearchListSize = 0; if(s_CurCustomTab == ASSETS_TAB_ENTITIES) { @@ -501,7 +503,7 @@ void CMenus::RenderSettingsCustom(CUIRect MainView) } UiDoListboxStart(&s_InitCustomList[s_CurCustomTab], &CustomList, TextureHeight + 15.0f + 10.0f + Margin, "", "", SearchListSize, CustomList.w / (Margin + TextureWidth), OldSelected, s_ScrollValue, true); - for(int i = 0; i < SearchListSize; ++i) + for(size_t i = 0; i < SearchListSize; ++i) { const SCustomItem *s = GetCustomItem(s_CurCustomTab, i); if(s == NULL) @@ -533,7 +535,7 @@ void CMenus::RenderSettingsCustom(CUIRect MainView) OldSelected = i; } - CListboxItem Item = UiDoListboxNextItem(s, OldSelected == i); + CListboxItem Item = UiDoListboxNextItem(s, OldSelected >= 0 && (size_t)OldSelected == i); CUIRect ItemRect = Item.m_Rect; ItemRect.Margin(Margin / 2, &ItemRect); if(Item.m_Visible) diff --git a/src/game/client/components/players.cpp b/src/game/client/components/players.cpp index 6c741d4bc..bbe1fb421 100644 --- a/src/game/client/components/players.cpp +++ b/src/game/client/components/players.cpp @@ -1,8 +1,6 @@ /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ /* If you are missing that file, acquire a complete release at teeworlds.com. */ -#include - #include #include #include diff --git a/src/game/client/components/skins.cpp b/src/game/client/components/skins.cpp index 0b3936d44..9dde84b3a 100644 --- a/src/game/client/components/skins.cpp +++ b/src/game/client/components/skins.cpp @@ -295,7 +295,7 @@ int CSkins::LoadSkin(const char *pName, CImageInfo &Info) Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "game", aBuf); } - m_aSkins.add(Skin); + m_aSkins.insert(std::lower_bound(m_aSkins.begin(), m_aSkins.end(), Skin), Skin); return 0; } @@ -324,24 +324,24 @@ void CSkins::OnInit() void CSkins::Refresh(TSkinLoadedCBFunc &&SkinLoadedFunc) { - for(int i = 0; i < m_aSkins.size(); ++i) + for(auto &Skin : m_aSkins) { - Graphics()->UnloadTexture(&m_aSkins[i].m_OriginalSkin.m_Body); - Graphics()->UnloadTexture(&m_aSkins[i].m_OriginalSkin.m_BodyOutline); - Graphics()->UnloadTexture(&m_aSkins[i].m_OriginalSkin.m_Feet); - Graphics()->UnloadTexture(&m_aSkins[i].m_OriginalSkin.m_FeetOutline); - Graphics()->UnloadTexture(&m_aSkins[i].m_OriginalSkin.m_Hands); - Graphics()->UnloadTexture(&m_aSkins[i].m_OriginalSkin.m_HandsOutline); - for(auto &Eye : m_aSkins[i].m_OriginalSkin.m_Eyes) + Graphics()->UnloadTexture(&Skin.m_OriginalSkin.m_Body); + Graphics()->UnloadTexture(&Skin.m_OriginalSkin.m_BodyOutline); + Graphics()->UnloadTexture(&Skin.m_OriginalSkin.m_Feet); + Graphics()->UnloadTexture(&Skin.m_OriginalSkin.m_FeetOutline); + Graphics()->UnloadTexture(&Skin.m_OriginalSkin.m_Hands); + Graphics()->UnloadTexture(&Skin.m_OriginalSkin.m_HandsOutline); + for(auto &Eye : Skin.m_OriginalSkin.m_Eyes) Graphics()->UnloadTexture(&Eye); - Graphics()->UnloadTexture(&m_aSkins[i].m_ColorableSkin.m_Body); - Graphics()->UnloadTexture(&m_aSkins[i].m_ColorableSkin.m_BodyOutline); - Graphics()->UnloadTexture(&m_aSkins[i].m_ColorableSkin.m_Feet); - Graphics()->UnloadTexture(&m_aSkins[i].m_ColorableSkin.m_FeetOutline); - Graphics()->UnloadTexture(&m_aSkins[i].m_ColorableSkin.m_Hands); - Graphics()->UnloadTexture(&m_aSkins[i].m_ColorableSkin.m_HandsOutline); - for(auto &Eye : m_aSkins[i].m_ColorableSkin.m_Eyes) + Graphics()->UnloadTexture(&Skin.m_ColorableSkin.m_Body); + Graphics()->UnloadTexture(&Skin.m_ColorableSkin.m_BodyOutline); + Graphics()->UnloadTexture(&Skin.m_ColorableSkin.m_Feet); + Graphics()->UnloadTexture(&Skin.m_ColorableSkin.m_FeetOutline); + Graphics()->UnloadTexture(&Skin.m_ColorableSkin.m_Hands); + Graphics()->UnloadTexture(&Skin.m_ColorableSkin.m_HandsOutline); + for(auto &Eye : Skin.m_ColorableSkin.m_Eyes) Graphics()->UnloadTexture(&Eye); } @@ -351,14 +351,14 @@ void CSkins::Refresh(TSkinLoadedCBFunc &&SkinLoadedFunc) SkinScanUser.m_pThis = this; SkinScanUser.m_SkinLoadedFunc = SkinLoadedFunc; Storage()->ListDirectory(IStorage::TYPE_ALL, "skins", SkinScan, &SkinScanUser); - if(!m_aSkins.size()) + if(m_aSkins.empty()) { Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "gameclient", "failed to load skins. folder='skins/'"); CSkin DummySkin; DummySkin.m_IsVanilla = true; str_copy(DummySkin.m_aName, "dummy", sizeof(DummySkin.m_aName)); DummySkin.m_BloodColor = ColorRGBA(1.0f, 1.0f, 1.0f); - m_aSkins.add(DummySkin); + m_aSkins.push_back(DummySkin); } } @@ -402,9 +402,12 @@ int CSkins::Find(const char *pName) int CSkins::FindImpl(const char *pName) { - auto r = ::find_binary(m_aSkins.all(), pName); - if(!r.empty()) - return &r.front() - m_aSkins.base_ptr(); + CSkin Needle; + mem_zero(&Needle, sizeof(Needle)); + str_copy(Needle.m_aName, pName, sizeof(Needle.m_aName)); + auto Range = std::equal_range(m_aSkins.begin(), m_aSkins.end(), Needle); + if(std::distance(Range.first, Range.second) == 1) + return Range.first - m_aSkins.begin(); if(str_comp(pName, "default") == 0) return -1; @@ -415,20 +418,23 @@ int CSkins::FindImpl(const char *pName) if(str_find(pName, "/") != 0) return -1; - auto d = ::find_binary(m_aDownloadSkins.all(), pName); - if(!d.empty()) + CDownloadSkin DownloadNeedle; + mem_zero(&DownloadNeedle, sizeof(DownloadNeedle)); + str_copy(DownloadNeedle.m_aName, pName, sizeof(DownloadNeedle.m_aName)); + const auto &[RangeBegin, RangeEnd] = std::equal_range(m_aDownloadSkins.begin(), m_aDownloadSkins.end(), DownloadNeedle); + if(std::distance(RangeBegin, RangeEnd) == 1) { - if(d.front().m_pTask && d.front().m_pTask->State() == HTTP_DONE) + if(RangeBegin->m_pTask && RangeBegin->m_pTask->State() == HTTP_DONE) { char aPath[IO_MAX_PATH_LENGTH]; - str_format(aPath, sizeof(aPath), "downloadedskins/%s.png", d.front().m_aName); - Storage()->RenameFile(d.front().m_aPath, aPath, IStorage::TYPE_SAVE); - LoadSkin(d.front().m_aName, d.front().m_pTask->m_Info); - d.front().m_pTask = nullptr; + str_format(aPath, sizeof(aPath), "downloadedskins/%s.png", RangeBegin->m_aName); + Storage()->RenameFile(RangeBegin->m_aPath, aPath, IStorage::TYPE_SAVE); + LoadSkin(RangeBegin->m_aName, RangeBegin->m_pTask->m_Info); + RangeBegin->m_pTask = nullptr; } - if(d.front().m_pTask && (d.front().m_pTask->State() == HTTP_ERROR || d.front().m_pTask->State() == HTTP_ABORTED)) + if(RangeBegin->m_pTask && (RangeBegin->m_pTask->State() == HTTP_ERROR || RangeBegin->m_pTask->State() == HTTP_ABORTED)) { - d.front().m_pTask = nullptr; + RangeBegin->m_pTask = nullptr; } return -1; } @@ -444,6 +450,6 @@ int CSkins::FindImpl(const char *pName) str_format(Skin.m_aPath, sizeof(Skin.m_aPath), "downloadedskins/%s", IStorage::FormatTmpPath(aBuf, sizeof(aBuf), pName)); Skin.m_pTask = std::make_shared(this, aUrl, Storage(), Skin.m_aPath); m_pClient->Engine()->AddJob(Skin.m_pTask); - m_aDownloadSkins.add(Skin); + m_aDownloadSkins.insert(std::lower_bound(m_aDownloadSkins.begin(), m_aDownloadSkins.end(), Skin), Skin); return -1; } diff --git a/src/game/client/components/skins.h b/src/game/client/components/skins.h index e5b445243..9231814bb 100644 --- a/src/game/client/components/skins.h +++ b/src/game/client/components/skins.h @@ -3,11 +3,11 @@ #ifndef GAME_CLIENT_COMPONENTS_SKINS_H #define GAME_CLIENT_COMPONENTS_SKINS_H #include -#include #include #include #include #include +#include class CSkins : public CComponent { @@ -46,8 +46,8 @@ public: int Find(const char *pName); private: - sorted_array m_aSkins; - sorted_array m_aDownloadSkins; + std::vector m_aSkins; + std::vector m_aDownloadSkins; char m_EventSkinPrefix[24]; bool LoadSkinPNG(CImageInfo &Info, const char *pName, const char *pPath, int DirType); diff --git a/src/game/client/components/sounds.cpp b/src/game/client/components/sounds.cpp index 4a23b7edc..77f19874f 100644 --- a/src/game/client/components/sounds.cpp +++ b/src/game/client/components/sounds.cpp @@ -1,8 +1,6 @@ /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ /* If you are missing that file, acquire a complete release at teeworlds.com. */ -#include - #include "sounds.h" #include #include diff --git a/src/game/client/skin.h b/src/game/client/skin.h index 5b3050553..e51ca71e8 100644 --- a/src/game/client/skin.h +++ b/src/game/client/skin.h @@ -1,8 +1,6 @@ - #ifndef GAME_CLIENT_SKIN_H #define GAME_CLIENT_SKIN_H #include -#include #include #include #include @@ -132,9 +130,7 @@ struct CSkin SSkinMetrics m_Metrics; bool operator<(const CSkin &Other) const { return str_comp(m_aName, Other.m_aName) < 0; } - - bool operator<(const char *pOther) const { return str_comp(m_aName, pOther) < 0; } - bool operator==(const char *pOther) const { return !str_comp(m_aName, pOther); } + bool operator==(const CSkin &Other) const { return !str_comp(m_aName, Other.m_aName); } }; #endif diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp index 4cbc9f773..150424225 100644 --- a/src/game/editor/editor.cpp +++ b/src/game/editor/editor.cpp @@ -4331,7 +4331,7 @@ static int EditorListdirCallback(const char *pName, int IsDir, int StorageType, Item.m_IsDir = IsDir != 0; Item.m_IsLink = false; Item.m_StorageType = StorageType; - pEditor->m_FileList.add(Item); + pEditor->m_FileList.push_back(Item); return 0; } @@ -4462,7 +4462,7 @@ void CEditor::RenderFileDialog() m_FileDialogScrollValue = UIEx()->DoScrollbarV(&m_FileDialogScrollValue, &Scroll, m_FileDialogScrollValue); int ScrollNum = 0; - for(int i = 0; i < m_FileList.size(); i++) + for(size_t i = 0; i < m_FileList.size(); i++) { m_FileList[i].m_IsVisible = false; if(!m_aFileDialogSearchText[0] || str_utf8_find_nocase(m_FileList[i].m_aName, m_aFileDialogSearchText)) @@ -4498,7 +4498,7 @@ void CEditor::RenderFileDialog() { if(Input()->GetEvent(i).m_Key == KEY_DOWN) { - for(NewIndex = m_FilesSelectedIndex + 1; NewIndex < m_FileList.size(); NewIndex++) + for(NewIndex = m_FilesSelectedIndex + 1; NewIndex < (int)m_FileList.size(); NewIndex++) { if(m_FileList[NewIndex].m_IsVisible) break; @@ -4513,7 +4513,7 @@ void CEditor::RenderFileDialog() } } } - if(NewIndex > -1 && NewIndex < m_FileList.size()) + if(NewIndex > -1 && NewIndex < (int)m_FileList.size()) { //scroll float IndexY = View.y - m_FileDialogScrollValue * ScrollNum * 17.0f + NewIndex * 17.0f; @@ -4710,10 +4710,11 @@ void CEditor::FilelistPopulate(int StorageType) Item.m_IsDir = true; Item.m_IsLink = true; Item.m_StorageType = IStorage::TYPE_SAVE; - m_FileList.add(Item); + m_FileList.push_back(Item); } Storage()->ListDirectory(StorageType, m_pFileDialogPath, EditorListdirCallback, this); - m_FilesSelectedIndex = m_FileList.size() ? 0 : -1; + std::sort(m_FileList.begin(), m_FileList.end()); + m_FilesSelectedIndex = m_FileList.empty() ? -1 : 0; m_PreviewImageIsLoaded = false; m_FileDialogActivate = false; diff --git a/src/game/editor/editor.h b/src/game/editor/editor.h index f6a5ab83f..187be6337 100644 --- a/src/game/editor/editor.h +++ b/src/game/editor/editor.h @@ -12,7 +12,6 @@ #include #include -#include #include #include @@ -884,7 +883,7 @@ public: bool operator<(const CFilelistItem &Other) const { return !str_comp(m_aFilename, "..") ? true : !str_comp(Other.m_aFilename, "..") ? false : m_IsDir && !Other.m_IsDir ? true : !m_IsDir && Other.m_IsDir ? false : str_comp_nocase(m_aFilename, Other.m_aFilename) < 0; } }; - sorted_array m_FileList; + std::vector m_FileList; int m_FilesStartAt; int m_FilesCur; int m_FilesStopAt; diff --git a/src/game/editor/io.cpp b/src/game/editor/io.cpp index 6c850926b..2b07eb43d 100644 --- a/src/game/editor/io.cpp +++ b/src/game/editor/io.cpp @@ -1,8 +1,6 @@ /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ /* If you are missing that file, acquire a complete release at teeworlds.com. */ -#include - #include "editor.h" #include #include diff --git a/src/game/localization.cpp b/src/game/localization.cpp index da6aa87c2..7ec913a05 100644 --- a/src/game/localization.cpp +++ b/src/game/localization.cpp @@ -2,7 +2,6 @@ /* If you are missing that file, acquire a complete release at teeworlds.com. */ #include "localization.h" -#include #include #include @@ -38,11 +37,7 @@ CLocalizationDatabase::CLocalizationDatabase() void CLocalizationDatabase::AddString(const char *pOrgStr, const char *pNewStr, const char *pContext) { - CString s; - s.m_Hash = str_quickhash(pOrgStr); - s.m_ContextHash = str_quickhash(pContext); - s.m_pReplacement = m_StringsHeap.StoreString(*pNewStr ? pNewStr : pOrgStr); - m_Strings.add(s); + m_Strings.emplace_back(str_quickhash(pOrgStr), str_quickhash(pContext), m_StringsHeap.StoreString(*pNewStr ? pNewStr : pOrgStr)); } bool CLocalizationDatabase::Load(const char *pFilename, IStorage *pStorage, IConsole *pConsole) @@ -118,6 +113,7 @@ bool CLocalizationDatabase::Load(const char *pFilename, IStorage *pStorage, ICon AddString(aOrigin, pReplacement, aContext); } io_close(IoHandle); + std::sort(m_Strings.begin(), m_Strings.end()); m_CurrentVersion = ++m_VersionCounter; return true; @@ -129,22 +125,21 @@ const char *CLocalizationDatabase::FindString(unsigned Hash, unsigned ContextHas String.m_Hash = Hash; String.m_ContextHash = ContextHash; String.m_pReplacement = 0x0; - sorted_array::range r = ::find_binary(m_Strings.all(), String); - if(r.empty()) - return 0; + auto Range1 = std::equal_range(m_Strings.begin(), m_Strings.end(), String); + if(std::distance(Range1.first, Range1.second) == 1) + return Range1.first->m_pReplacement; - unsigned DefaultHash = str_quickhash(""); - unsigned DefaultIndex = 0; - for(unsigned i = 0; i < r.size() && r.index(i).m_Hash == Hash; ++i) + const unsigned DefaultHash = str_quickhash(""); + if(ContextHash != DefaultHash) { - const CString &rStr = r.index(i); - if(rStr.m_ContextHash == ContextHash) - return rStr.m_pReplacement; - else if(rStr.m_ContextHash == DefaultHash) - DefaultIndex = i; + // Do another lookup with the default context hash + String.m_ContextHash = DefaultHash; + auto Range2 = std::equal_range(m_Strings.begin(), m_Strings.end(), String); + if(std::distance(Range2.first, Range2.second) == 1) + return Range2.first->m_pReplacement; } - return r.index(DefaultIndex).m_pReplacement; + return nullptr; } CLocalizationDatabase g_Localization; diff --git a/src/game/localization.h b/src/game/localization.h index 8840b5abf..36d1422bb 100644 --- a/src/game/localization.h +++ b/src/game/localization.h @@ -2,9 +2,10 @@ /* If you are missing that file, acquire a complete release at teeworlds.com. */ #ifndef GAME_LOCALIZATION_H #define GAME_LOCALIZATION_H -#include +#include // GNUC_ATTRIBUTE #include +#include class CLocalizationDatabase { @@ -15,12 +16,18 @@ class CLocalizationDatabase unsigned m_ContextHash; const char *m_pReplacement; + CString() {} + CString(unsigned Hash, unsigned ContextHash, const char *pReplacement) : + m_Hash(Hash), m_ContextHash(ContextHash), m_pReplacement(pReplacement) + { + } + bool operator<(const CString &Other) const { return m_Hash < Other.m_Hash || (m_Hash == Other.m_Hash && m_ContextHash < Other.m_ContextHash); } bool operator<=(const CString &Other) const { return m_Hash < Other.m_Hash || (m_Hash == Other.m_Hash && m_ContextHash <= Other.m_ContextHash); } bool operator==(const CString &Other) const { return m_Hash == Other.m_Hash && m_ContextHash == Other.m_ContextHash; } }; - sorted_array m_Strings; + std::vector m_Strings; CHeap m_StringsHeap; int m_VersionCounter; int m_CurrentVersion; diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index bc55a7708..46d8e64d0 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -1,7 +1,7 @@ /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ /* If you are missing that file, acquire a complete release at teeworlds.com. */ -#include #include +#include #include "base/system.h" #include "gamecontext.h" @@ -3080,18 +3080,19 @@ void CGameContext::ConAddMapVotes(IConsole::IResult *pResult, void *pUserData) { CGameContext *pSelf = (CGameContext *)pUserData; - sorted_array MapList; + std::vector MapList; pSelf->Storage()->ListDirectory(IStorage::TYPE_ALL, "maps", MapScan, &MapList); + std::sort(MapList.begin(), MapList.end()); - for(int i = 0; i < MapList.size(); i++) + for(auto &Item : MapList) { char aDescription[64]; - str_format(aDescription, sizeof(aDescription), "Map: %s", MapList[i].m_aName); + str_format(aDescription, sizeof(aDescription), "Map: %s", Item.m_aName); char aCommand[IO_MAX_PATH_LENGTH * 2 + 10]; char aMapEscaped[IO_MAX_PATH_LENGTH * 2]; char *pDst = aMapEscaped; - str_escape(&pDst, MapList[i].m_aName, aMapEscaped + sizeof(aMapEscaped)); + str_escape(&pDst, Item.m_aName, aMapEscaped + sizeof(aMapEscaped)); str_format(aCommand, sizeof(aCommand), "change_map \"%s\"", aMapEscaped); pSelf->AddVote(aDescription, aCommand); @@ -3102,15 +3103,12 @@ void CGameContext::ConAddMapVotes(IConsole::IResult *pResult, void *pUserData) int CGameContext::MapScan(const char *pName, int IsDir, int DirType, void *pUserData) { - sorted_array *pMapList = (sorted_array *)pUserData; - if(IsDir || !str_endswith(pName, ".map")) return 0; CMapNameItem Item; - int Length = str_length(pName); - str_truncate(Item.m_aName, sizeof(Item.m_aName), pName, Length - 4); - pMapList->add(Item); + str_truncate(Item.m_aName, sizeof(Item.m_aName), pName, str_length(pName) - str_length(".map")); + static_cast *>(pUserData)->push_back(Item); return 0; } diff --git a/src/test/sorted_array.cpp b/src/test/sorted_array.cpp deleted file mode 100644 index a02edddfa..000000000 --- a/src/test/sorted_array.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include - -#include - -TEST(SortedArray, SortEmptyRange) -{ - sorted_array x; - x.sort_range(); -} diff --git a/src/tools/dummy_map.cpp b/src/tools/dummy_map.cpp index 8e2fb755f..8a9019ef8 100644 --- a/src/tools/dummy_map.cpp +++ b/src/tools/dummy_map.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include #include