From b4f53939060307b29326d0a873ff9199528d1004 Mon Sep 17 00:00:00 2001 From: Maschell Date: Fri, 21 Feb 2020 14:22:36 +0100 Subject: [PATCH] - Use std::recursive_mutex instead of CMutex which is exactly the same - Load icons in one async task instead of creating one task for each icon to improve stability with many icons --- src/game/GameList.cpp | 75 +++++++++++++++++++-------------------- src/game/GameList.h | 3 +- src/gui/GuiIconGrid.cpp | 9 +++-- src/gui/GuiIconGrid.h | 2 +- src/menu/MainWindow.cpp | 1 - src/menu/MainWindow.h | 3 +- src/system/CMutex.h | 67 ---------------------------------- src/utils/AsyncExecutor.h | 3 +- 8 files changed, 48 insertions(+), 115 deletions(-) delete mode 100644 src/system/CMutex.h diff --git a/src/game/GameList.cpp b/src/game/GameList.cpp index 7798d13..63192ed 100644 --- a/src/game/GameList.cpp +++ b/src/game/GameList.cpp @@ -13,14 +13,13 @@ #include "fs/FSUtils.h" #include "utils/logger.h" #include "utils/StringTools.h" -#include "system/CMutex.h" void GameList::clear() { lock(); for (auto const& x : fullGameList) { if(x != NULL) { if(x->imageData != NULL) { - delete x->imageData; + AsyncExecutor::pushForDelete(x->imageData); x->imageData = NULL; } delete x; @@ -37,7 +36,6 @@ void GameList::clear() { titleListChanged(this); } - gameInfo * GameList::getGameInfo(uint64_t titleId) const { for (uint32_t i = 0; i < filteredList.size(); ++i) { if(titleId == filteredList[i]->titleId) @@ -83,8 +81,6 @@ int32_t GameList::readGameList() { titles.resize(realTitleCount); } - CMutex extraInfoMutex; - for (auto title_candidate : titles) { if((title_candidate.titleId & 0xFFFFFFFF00000000L) == 0x0005000000000000L) { gameInfo* newGameInfo = new gameInfo; @@ -97,42 +93,45 @@ int32_t GameList::readGameList() { fullGameList.push_back(newGameInfo); titleAdded(newGameInfo); cnt++; - - AsyncExecutor::execute([newGameInfo, this, &extraInfoMutex] { - extraInfoMutex.lock(); - DEBUG_FUNCTION_LINE("Load extra infos of %016llX\n",newGameInfo->titleId); - ACPMetaXml* meta = (ACPMetaXml*)calloc(1, 0x4000); //TODO fix wut - if(meta) { - auto acp = ACPGetTitleMetaXml(newGameInfo->titleId, meta); - if(acp >= 0) { - newGameInfo->name = meta->shortname_en; - } - free(meta); - } - - if(newGameInfo->imageData == NULL) { - std::string filepath = "fs:" + newGameInfo->gamePath + META_PATH + "/iconTex.tga"; - uint8_t *buffer = NULL; - uint32_t bufferSize = 0; - int iResult = FSUtils::LoadFileToMem(filepath.c_str(), &buffer, &bufferSize); - - if(iResult > 0) { - GuiImageData * imageData = new GuiImageData(buffer, bufferSize, GX2_TEX_CLAMP_MODE_MIRROR); - if(imageData) { - newGameInfo->imageData = imageData; - } - - //! free original image buffer which is converted to texture now and not needed anymore - free(buffer); - } - } - DCFlushRange(newGameInfo, sizeof(gameInfo)); - titleUpdated(newGameInfo); - extraInfoMutex.unlock(); - }); } } + AsyncExecutor::execute([this] { + lock(); + for (uint32_t i = 0; i < fullGameList.size(); ++i) { + gameInfo *header = fullGameList[i]; + + DEBUG_FUNCTION_LINE("Load extra infos of %016llX\n",header->titleId); + ACPMetaXml* meta = (ACPMetaXml*)calloc(1, 0x4000); //TODO fix wut + if(meta) { + auto acp = ACPGetTitleMetaXml(header->titleId, meta); + if(acp >= 0) { + header->name = meta->shortname_en; + } + free(meta); + } + + if(header->imageData == NULL) { + std::string filepath = "fs:" + header->gamePath + META_PATH + "/iconTex.tga"; + uint8_t *buffer = NULL; + uint32_t bufferSize = 0; + int iResult = FSUtils::LoadFileToMem(filepath.c_str(), &buffer, &bufferSize); + if(iResult > 0) { + GuiImageData * imageData = new GuiImageData(buffer, bufferSize, GX2_TEX_CLAMP_MODE_MIRROR); + if(imageData) { + header->imageData = imageData; + } + + //! free original image buffer which is converted to texture now and not needed anymore + free(buffer); + } + } + DCFlushRange(header, sizeof(gameInfo)); + titleUpdated(header); + } + unlock(); + }); + return cnt; } diff --git a/src/game/GameList.h b/src/game/GameList.h index 52f3cf0..b7c469f 100644 --- a/src/game/GameList.h +++ b/src/game/GameList.h @@ -2,6 +2,7 @@ #define GAME_LIST_H_ #include +#include #include #include #include @@ -132,7 +133,7 @@ protected: std::vector filteredList; std::vector fullGameList; - CMutex _lock; + std::recursive_mutex _lock; }; #endif diff --git a/src/gui/GuiIconGrid.cpp b/src/gui/GuiIconGrid.cpp index 540e7f1..f585f76 100644 --- a/src/gui/GuiIconGrid.cpp +++ b/src/gui/GuiIconGrid.cpp @@ -113,8 +113,9 @@ uint64_t GuiIconGrid::getSelectedGame(void) { } void GuiIconGrid::OnGameTitleListUpdated(GameList * gameList) { - containerMutex.lock(); + gameList->lock(); + containerMutex.lock(); // At first delete the ones that were deleted; auto it = gameInfoContainers.begin(); while (it != gameInfoContainers.end()) { @@ -148,12 +149,14 @@ void GuiIconGrid::OnGameTitleListUpdated(GameList * gameList) { } } + if(container == NULL) { OnGameTitleAdded(info); } } - gameList->unlock(); containerMutex.unlock(); + + gameList->unlock(); bUpdatePositions = true; } @@ -249,11 +252,11 @@ void GuiIconGrid::OnGameTitleUpdated(gameInfo * info) { break; } } + containerMutex.unlock(); if(container != NULL) { container->updateImageData(); } - containerMutex.unlock(); bUpdatePositions = true; } diff --git a/src/gui/GuiIconGrid.h b/src/gui/GuiIconGrid.h index 557683c..08ed1ee 100644 --- a/src/gui/GuiIconGrid.h +++ b/src/gui/GuiIconGrid.h @@ -120,6 +120,6 @@ private: GuiButton * button; }; - CMutex containerMutex; + std::recursive_mutex containerMutex; std::map gameInfoContainers; }; diff --git a/src/menu/MainWindow.cpp b/src/menu/MainWindow.cpp index 8391f1e..18a3eb2 100644 --- a/src/menu/MainWindow.cpp +++ b/src/menu/MainWindow.cpp @@ -138,7 +138,6 @@ void MainWindow::OnGameTitleUpdated(gameInfo * info) { } void MainWindow::OnGameTitleAdded(gameInfo * info) { - currentTvFrame->OnGameTitleAdded(info); if(currentTvFrame != currentDrcFrame) { currentDrcFrame->OnGameTitleAdded(info); diff --git a/src/menu/MainWindow.h b/src/menu/MainWindow.h index f18d94d..e1a24e8 100644 --- a/src/menu/MainWindow.h +++ b/src/menu/MainWindow.h @@ -21,7 +21,6 @@ #include #include #include "game/GameList.h" -#include "system/CMutex.h" #include "KeyboardHelper.h" #include "gui/GuiTitleBrowser.h" #include "MainDrcButtonsFrame.h" @@ -147,7 +146,7 @@ private: GameList gameList; - CMutex guiMutex; + std::recursive_mutex guiMutex; KeyboardHelper * keyboardInstance = NULL; }; diff --git a/src/system/CMutex.h b/src/system/CMutex.h deleted file mode 100644 index b1ec2a7..0000000 --- a/src/system/CMutex.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** - * Copyright (C) 2015 Dimok - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - ****************************************************************************/ -#ifndef _CMUTEX_H_ -#define _CMUTEX_H_ - -#include -#include - -class CMutex { -public: - CMutex() { - pMutex = (OSMutex*) malloc(sizeof(OSMutex)); - if(!pMutex) - return; - - OSInitMutex(pMutex); - } - virtual ~CMutex() { - if(pMutex) - free(pMutex); - } - - void lock(void) { - if(pMutex) - OSLockMutex(pMutex); - } - void unlock(void) { - if(pMutex) - OSUnlockMutex(pMutex); - } - bool tryLock(void) { - if(!pMutex) - return false; - - return (OSTryLockMutex(pMutex) != 0); - } -private: - OSMutex *pMutex; -}; - -class CMutexLock { -public: - CMutexLock() { - mutex.lock(); - } - virtual ~CMutexLock() { - mutex.unlock(); - } -private: - CMutex mutex; -}; - -#endif // _CMUTEX_H_ diff --git a/src/utils/AsyncExecutor.h b/src/utils/AsyncExecutor.h index 702c65d..845f6c9 100644 --- a/src/utils/AsyncExecutor.h +++ b/src/utils/AsyncExecutor.h @@ -6,7 +6,6 @@ #include #include #include -#include #include #include "utils/logger.h" @@ -32,7 +31,7 @@ private: DCFlushRange((void*)&exitThread, sizeof(exitThread)); } - CMutex mutex; + std::recursive_mutex mutex; std::thread * thread; volatile bool exitThread = false;