mirror of
https://github.com/wiiu-env/launchiine.git
synced 2025-02-16 16:19:12 +01:00
- The AsyncExeuctor does now clean itself in 50ms intervals (still could produce dead locks which sucks)
- Only allow a maximum of 10 "tasks" at the same time. - Increase the stack size of the "Application" which hopefully improves stability?
This commit is contained in:
parent
d97d5ed325
commit
358f368462
@ -41,7 +41,7 @@ bool Application::exitApplication = false;
|
|||||||
bool Application::quitRequest = false;
|
bool Application::quitRequest = false;
|
||||||
|
|
||||||
Application::Application()
|
Application::Application()
|
||||||
: CThread(CThread::eAttributeAffCore1 | CThread::eAttributePinnedAff, 0, 0x20000)
|
: CThread(CThread::eAttributeAffCore1 | CThread::eAttributePinnedAff, 0, 0x800000)
|
||||||
, bgMusic(NULL)
|
, bgMusic(NULL)
|
||||||
, video(NULL)
|
, video(NULL)
|
||||||
, mainWindow(NULL)
|
, mainWindow(NULL)
|
||||||
@ -59,6 +59,8 @@ Application::Application()
|
|||||||
bgMusic->Play();
|
bgMusic->Play();
|
||||||
bgMusic->SetVolume(50);
|
bgMusic->SetVolume(50);
|
||||||
|
|
||||||
|
AsyncExecutor::execute([] {DEBUG_FUNCTION_LINE("Hello\n");});
|
||||||
|
|
||||||
exitApplication = false;
|
exitApplication = false;
|
||||||
|
|
||||||
uint64_t titleID = OSGetTitleID();
|
uint64_t titleID = OSGetTitleID();
|
||||||
|
@ -13,12 +13,12 @@
|
|||||||
#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() {
|
||||||
for (auto const& x : fullGameList) {
|
for (auto const& x : fullGameList) {
|
||||||
if(x != NULL) {
|
if(x != NULL) {
|
||||||
if(x->imageData != NULL) {
|
if(x->imageData != NULL) {
|
||||||
DEBUG_FUNCTION_LINE("Delete the image data\n");
|
|
||||||
delete x->imageData;
|
delete x->imageData;
|
||||||
x->imageData = NULL;
|
x->imageData = NULL;
|
||||||
}
|
}
|
||||||
@ -80,8 +80,10 @@ int32_t GameList::readGameList() {
|
|||||||
titles.resize(realTitleCount);
|
titles.resize(realTitleCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CMutex extraInfoMutex;
|
||||||
|
|
||||||
for (auto title_candidate : titles) {
|
for (auto title_candidate : titles) {
|
||||||
if(true || (title_candidate.titleId & 0xFFFFFFFF00000000L) == 0x0005000000000000L) {
|
if((title_candidate.titleId & 0xFFFFFFFF00000000L) == 0x0005000000000000L) {
|
||||||
gameInfo* newGameInfo = new gameInfo;
|
gameInfo* newGameInfo = new gameInfo;
|
||||||
newGameInfo->titleId = title_candidate.titleId;
|
newGameInfo->titleId = title_candidate.titleId;
|
||||||
newGameInfo->gamePath = title_candidate.path;
|
newGameInfo->gamePath = title_candidate.path;
|
||||||
@ -91,6 +93,39 @@ 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();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,10 +124,7 @@ void MainWindow::OnGameTitleUpdated(gameInfo * info) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::OnGameTitleAdded(gameInfo * info) {
|
void MainWindow::OnGameTitleAdded(gameInfo * info) {
|
||||||
DEBUG_FUNCTION_LINE("%08X\n", info);
|
|
||||||
if(info == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
currentTvFrame->OnGameTitleAdded(info);
|
currentTvFrame->OnGameTitleAdded(info);
|
||||||
if(currentTvFrame != currentDrcFrame) {
|
if(currentTvFrame != currentDrcFrame) {
|
||||||
currentDrcFrame->OnGameTitleAdded(info);
|
currentDrcFrame->OnGameTitleAdded(info);
|
||||||
|
@ -6,15 +6,39 @@ AsyncExecutor * AsyncExecutor::instance = NULL;
|
|||||||
void AsyncExecutor::pushForDelete(GuiElement * ptr) {
|
void AsyncExecutor::pushForDelete(GuiElement * ptr) {
|
||||||
execute([ptr] {delete ptr;});
|
execute([ptr] {delete ptr;});
|
||||||
}
|
}
|
||||||
|
AsyncExecutor::AsyncExecutor() {
|
||||||
|
thread = new std::thread([&]() {
|
||||||
|
while(!exitThread) {
|
||||||
|
instance->mutex.lock();
|
||||||
|
auto it = instance->elements.begin();
|
||||||
|
while (it != instance->elements.end()) {
|
||||||
|
auto future = it;
|
||||||
|
auto status = future->wait_for(std::chrono::seconds(0));
|
||||||
|
if (status == std::future_status::ready) {
|
||||||
|
it = instance->elements.erase(it);
|
||||||
|
} else {
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
instance->mutex.unlock();
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||||
|
DCFlushRange((void*)&exitThread, sizeof(exitThread));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
thread->detach();
|
||||||
|
}
|
||||||
|
|
||||||
void AsyncExecutor::execute(std::function<void()> func) {
|
void AsyncExecutor::execute(std::function<void()> func) {
|
||||||
if(!instance) {
|
if(!instance) {
|
||||||
instance = new AsyncExecutor();
|
instance = new AsyncExecutor();
|
||||||
}
|
}
|
||||||
instance->elements.push(std::async(std::launch::async,func));
|
|
||||||
if(instance->elements.size() >= 25){
|
while(instance->elements.size() > 10) {
|
||||||
//DEBUG_FUNCTION_LINE("Wait on queue %d\n",instance->elements.size());
|
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||||
instance->elements.front().get();
|
|
||||||
instance->elements.pop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
instance->mutex.lock();
|
||||||
|
instance->elements.push_back(std::async(std::launch::async,func));
|
||||||
|
instance->mutex.unlock();
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
#pragma once
|
#ifndef ___ASYNCEXECUTER_H_
|
||||||
|
#define ___ASYNCEXECUTER_H_
|
||||||
|
|
||||||
#include <queue>
|
|
||||||
|
#include <vector>
|
||||||
#include <future>
|
#include <future>
|
||||||
|
#include <thread>
|
||||||
#include <gui/GuiElement.h>
|
#include <gui/GuiElement.h>
|
||||||
|
#include <system/CMutex.h>
|
||||||
|
#include <coreinit/cache.h>
|
||||||
|
#include "utils/logger.h"
|
||||||
|
|
||||||
class AsyncExecutor {
|
class AsyncExecutor {
|
||||||
public:
|
public:
|
||||||
@ -19,8 +25,17 @@ public:
|
|||||||
private:
|
private:
|
||||||
static AsyncExecutor *instance;
|
static AsyncExecutor *instance;
|
||||||
|
|
||||||
AsyncExecutor() {}
|
AsyncExecutor();
|
||||||
~AsyncExecutor() {}
|
|
||||||
|
|
||||||
std::queue<std::future<void>> elements;
|
~AsyncExecutor() {
|
||||||
|
exitThread = true;
|
||||||
|
DCFlushRange((void*)&exitThread, sizeof(exitThread));
|
||||||
|
}
|
||||||
|
|
||||||
|
CMutex mutex;
|
||||||
|
std::thread * thread;
|
||||||
|
volatile bool exitThread = false;
|
||||||
|
|
||||||
|
std::vector<std::future<void>> elements;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user