mirror of
https://github.com/wiiu-env/launchiine.git
synced 2024-11-25 11:16:51 +01:00
- 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
This commit is contained in:
parent
72bb786fa2
commit
b4f5393906
@ -13,14 +13,13 @@
|
|||||||
#include "fs/FSUtils.h"
|
#include "fs/FSUtils.h"
|
||||||
#include "utils/logger.h"
|
#include "utils/logger.h"
|
||||||
#include "utils/StringTools.h"
|
#include "utils/StringTools.h"
|
||||||
#include "system/CMutex.h"
|
|
||||||
|
|
||||||
void GameList::clear() {
|
void GameList::clear() {
|
||||||
lock();
|
lock();
|
||||||
for (auto const& x : fullGameList) {
|
for (auto const& x : fullGameList) {
|
||||||
if(x != NULL) {
|
if(x != NULL) {
|
||||||
if(x->imageData != NULL) {
|
if(x->imageData != NULL) {
|
||||||
delete x->imageData;
|
AsyncExecutor::pushForDelete(x->imageData);
|
||||||
x->imageData = NULL;
|
x->imageData = NULL;
|
||||||
}
|
}
|
||||||
delete x;
|
delete x;
|
||||||
@ -37,7 +36,6 @@ void GameList::clear() {
|
|||||||
titleListChanged(this);
|
titleListChanged(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
gameInfo * GameList::getGameInfo(uint64_t titleId) const {
|
gameInfo * GameList::getGameInfo(uint64_t titleId) const {
|
||||||
for (uint32_t i = 0; i < filteredList.size(); ++i) {
|
for (uint32_t i = 0; i < filteredList.size(); ++i) {
|
||||||
if(titleId == filteredList[i]->titleId)
|
if(titleId == filteredList[i]->titleId)
|
||||||
@ -83,8 +81,6 @@ int32_t GameList::readGameList() {
|
|||||||
titles.resize(realTitleCount);
|
titles.resize(realTitleCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
CMutex extraInfoMutex;
|
|
||||||
|
|
||||||
for (auto title_candidate : titles) {
|
for (auto title_candidate : titles) {
|
||||||
if((title_candidate.titleId & 0xFFFFFFFF00000000L) == 0x0005000000000000L) {
|
if((title_candidate.titleId & 0xFFFFFFFF00000000L) == 0x0005000000000000L) {
|
||||||
gameInfo* newGameInfo = new gameInfo;
|
gameInfo* newGameInfo = new gameInfo;
|
||||||
@ -97,42 +93,45 @@ int32_t GameList::readGameList() {
|
|||||||
fullGameList.push_back(newGameInfo);
|
fullGameList.push_back(newGameInfo);
|
||||||
titleAdded(newGameInfo);
|
titleAdded(newGameInfo);
|
||||||
cnt++;
|
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;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define GAME_LIST_H_
|
#define GAME_LIST_H_
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <mutex>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <coreinit/mcp.h>
|
#include <coreinit/mcp.h>
|
||||||
#include <gui/sigslot.h>
|
#include <gui/sigslot.h>
|
||||||
@ -132,7 +133,7 @@ protected:
|
|||||||
std::vector<gameInfo *> filteredList;
|
std::vector<gameInfo *> filteredList;
|
||||||
std::vector<gameInfo *> fullGameList;
|
std::vector<gameInfo *> fullGameList;
|
||||||
|
|
||||||
CMutex _lock;
|
std::recursive_mutex _lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -113,8 +113,9 @@ uint64_t GuiIconGrid::getSelectedGame(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GuiIconGrid::OnGameTitleListUpdated(GameList * gameList) {
|
void GuiIconGrid::OnGameTitleListUpdated(GameList * gameList) {
|
||||||
containerMutex.lock();
|
|
||||||
gameList->lock();
|
gameList->lock();
|
||||||
|
containerMutex.lock();
|
||||||
// At first delete the ones that were deleted;
|
// At first delete the ones that were deleted;
|
||||||
auto it = gameInfoContainers.begin();
|
auto it = gameInfoContainers.begin();
|
||||||
while (it != gameInfoContainers.end()) {
|
while (it != gameInfoContainers.end()) {
|
||||||
@ -148,12 +149,14 @@ void GuiIconGrid::OnGameTitleListUpdated(GameList * gameList) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(container == NULL) {
|
if(container == NULL) {
|
||||||
OnGameTitleAdded(info);
|
OnGameTitleAdded(info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gameList->unlock();
|
|
||||||
containerMutex.unlock();
|
containerMutex.unlock();
|
||||||
|
|
||||||
|
gameList->unlock();
|
||||||
bUpdatePositions = true;
|
bUpdatePositions = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -249,11 +252,11 @@ void GuiIconGrid::OnGameTitleUpdated(gameInfo * info) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
containerMutex.unlock();
|
||||||
|
|
||||||
if(container != NULL) {
|
if(container != NULL) {
|
||||||
container->updateImageData();
|
container->updateImageData();
|
||||||
}
|
}
|
||||||
containerMutex.unlock();
|
|
||||||
bUpdatePositions = true;
|
bUpdatePositions = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,6 +120,6 @@ private:
|
|||||||
GuiButton * button;
|
GuiButton * button;
|
||||||
};
|
};
|
||||||
|
|
||||||
CMutex containerMutex;
|
std::recursive_mutex containerMutex;
|
||||||
std::map<uint64_t, GameInfoContainer *> gameInfoContainers;
|
std::map<uint64_t, GameInfoContainer *> gameInfoContainers;
|
||||||
};
|
};
|
||||||
|
@ -138,7 +138,6 @@ void MainWindow::OnGameTitleUpdated(gameInfo * info) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::OnGameTitleAdded(gameInfo * info) {
|
void MainWindow::OnGameTitleAdded(gameInfo * info) {
|
||||||
|
|
||||||
currentTvFrame->OnGameTitleAdded(info);
|
currentTvFrame->OnGameTitleAdded(info);
|
||||||
if(currentTvFrame != currentDrcFrame) {
|
if(currentTvFrame != currentDrcFrame) {
|
||||||
currentDrcFrame->OnGameTitleAdded(info);
|
currentDrcFrame->OnGameTitleAdded(info);
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
#include <queue>
|
#include <queue>
|
||||||
#include <gui/Gui.h>
|
#include <gui/Gui.h>
|
||||||
#include "game/GameList.h"
|
#include "game/GameList.h"
|
||||||
#include "system/CMutex.h"
|
|
||||||
#include "KeyboardHelper.h"
|
#include "KeyboardHelper.h"
|
||||||
#include "gui/GuiTitleBrowser.h"
|
#include "gui/GuiTitleBrowser.h"
|
||||||
#include "MainDrcButtonsFrame.h"
|
#include "MainDrcButtonsFrame.h"
|
||||||
@ -147,7 +146,7 @@ private:
|
|||||||
|
|
||||||
GameList gameList;
|
GameList gameList;
|
||||||
|
|
||||||
CMutex guiMutex;
|
std::recursive_mutex guiMutex;
|
||||||
KeyboardHelper * keyboardInstance = NULL;
|
KeyboardHelper * keyboardInstance = 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 <http://www.gnu.org/licenses/>.
|
|
||||||
****************************************************************************/
|
|
||||||
#ifndef _CMUTEX_H_
|
|
||||||
#define _CMUTEX_H_
|
|
||||||
|
|
||||||
#include <malloc.h>
|
|
||||||
#include <coreinit/mutex.h>
|
|
||||||
|
|
||||||
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_
|
|
@ -6,7 +6,6 @@
|
|||||||
#include <future>
|
#include <future>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <gui/GuiElement.h>
|
#include <gui/GuiElement.h>
|
||||||
#include <system/CMutex.h>
|
|
||||||
#include <coreinit/cache.h>
|
#include <coreinit/cache.h>
|
||||||
#include "utils/logger.h"
|
#include "utils/logger.h"
|
||||||
|
|
||||||
@ -32,7 +31,7 @@ private:
|
|||||||
DCFlushRange((void*)&exitThread, sizeof(exitThread));
|
DCFlushRange((void*)&exitThread, sizeof(exitThread));
|
||||||
}
|
}
|
||||||
|
|
||||||
CMutex mutex;
|
std::recursive_mutex mutex;
|
||||||
std::thread * thread;
|
std::thread * thread;
|
||||||
volatile bool exitThread = false;
|
volatile bool exitThread = false;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user