mirror of
https://github.com/wiiu-env/Flappy-Bird_GX2.git
synced 2024-11-27 01:54:16 +01:00
Fix compiling, use AsyncExecutor instead of AsyncDeleter, fix warnings
This commit is contained in:
parent
62c4c726ff
commit
1cffbbf2b8
12
Makefile
12
Makefile
@ -61,7 +61,6 @@ LIBDIRS := $(PORTLIBS) $(WUT_ROOT) $(WUT_ROOT)/usr
|
||||
ifneq ($(BUILD),$(notdir $(CURDIR)))
|
||||
#-------------------------------------------------------------------------------
|
||||
FILELIST := $(shell bash ./filelist.sh)
|
||||
|
||||
export OUTPUT := $(CURDIR)/$(TARGET)
|
||||
export TOPDIR := $(CURDIR)
|
||||
|
||||
@ -141,17 +140,22 @@ $(OFILES_SRC) : $(HFILES_BIN)
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
%.ogg.o %_ogg.h : %.ogg
|
||||
%.jpg.o %_jpg.h : %.jpg
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
%.ogg.o %_ogg.h : %.ogg
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
|
||||
%.mp3.o %_mp3.h : %.mp3
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
@$(bin2o)
|
||||
|
||||
%.ttf.o %_ttf.h : %.ttf
|
||||
@echo $(notdir $<)
|
||||
@$(bin2o)
|
||||
@$(bin2o)
|
||||
|
||||
|
||||
-include $(DEPENDS)
|
||||
|
||||
|
@ -32,7 +32,7 @@ then
|
||||
echo "Generating filelist.h for $count files." >&2
|
||||
cat <<EOF > $outFile
|
||||
/****************************************************************************
|
||||
* Loadiine resource files.
|
||||
* Resource files.
|
||||
* This file is generated automatically.
|
||||
* Includes $count files.
|
||||
*
|
||||
@ -57,11 +57,10 @@ for i in ${files[@]}
|
||||
do
|
||||
filename=${i%.*}
|
||||
extension=${i##*.}
|
||||
echo 'extern const unsigned char '$filename'_'$extension'[];' >> $outFile
|
||||
echo 'extern const unsigned int '$filename'_'$extension'_size;' >> $outFile
|
||||
echo '' >> $outFile
|
||||
echo '#include "'$filename'_'$extension'.h"' >> $outFile
|
||||
done
|
||||
|
||||
echo '' >> $outFile
|
||||
echo 'static RecourceFile RecourceList[] =' >> $outFile
|
||||
echo '{' >> $outFile
|
||||
|
||||
|
@ -19,14 +19,14 @@
|
||||
#include <proc_ui/procui.h>
|
||||
#include <sysapp/launch.h>
|
||||
#include "Application.h"
|
||||
#include "gui/FreeTypeGX.h"
|
||||
#include "gui/VPadController.h"
|
||||
#include "gui/WPadController.h"
|
||||
#include <gui/FreeTypeGX.h>
|
||||
#include <gui/VPadController.h>
|
||||
#include <gui/WPadController.h>
|
||||
#include "resources/Resources.h"
|
||||
#include "gui/sounds/SoundHandler.hpp"
|
||||
#include <gui/sounds/SoundHandler.hpp>
|
||||
#include "system/memory.h"
|
||||
#include "system/AsyncDeleter.h"
|
||||
#include "utils/logger.h"
|
||||
#include "utils/AsyncExecutor.h"
|
||||
|
||||
Application *Application::applicationInstance = NULL;
|
||||
bool Application::exitApplication = false;
|
||||
@ -61,8 +61,8 @@ Application::~Application() {
|
||||
for (int i = 0; i < 5; i++)
|
||||
delete controller[i];
|
||||
|
||||
AsyncDeleter::destroyInstance();
|
||||
DEBUG_FUNCTION_LINE("Destroy async deleter");
|
||||
AsyncExecutor::destroyInstance();
|
||||
|
||||
DEBUG_FUNCTION_LINE("Clear resources");
|
||||
Resources::Clear();
|
||||
@ -240,11 +240,6 @@ void Application::executeThread(void) {
|
||||
mainWindow->updateEffects();
|
||||
|
||||
video->waitForVSync();
|
||||
|
||||
//! transfer elements to real delete list here after all processes are finished
|
||||
//! the elements are transfered to another list to delete the elements in a separate thread
|
||||
//! and avoid blocking the GUI thread
|
||||
AsyncDeleter::triggerDeleteProcess();
|
||||
}
|
||||
|
||||
//! in case we exit to a homebrew let's smoothly fade out
|
||||
|
@ -23,7 +23,7 @@
|
||||
* Constructor for the GuiButton class.
|
||||
*/
|
||||
|
||||
Background::Background(char *picture, float scroll_speed) {
|
||||
Background::Background(const char *picture, float scroll_speed) {
|
||||
loc_x = 0.0f;
|
||||
|
||||
bgImg = Resources::GetImageData(picture);
|
||||
|
@ -27,7 +27,7 @@
|
||||
//!Display, manage, and manipulate buttons in the GUI. Buttons can have images, icons, text, and sound set (all of which are optional)
|
||||
class Background : public GuiElement {
|
||||
public:
|
||||
Background(char *picture, float scroll_speed);
|
||||
Background(const char *picture, float scroll_speed);
|
||||
|
||||
virtual ~Background();
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "utils/StringTools.h"
|
||||
#include "utils/logger.h"
|
||||
#include "resources/Resources.h"
|
||||
#include "system/AsyncDeleter.h"
|
||||
#include "utils/AsyncExecutor.h"
|
||||
|
||||
MainWindow::MainWindow(int w, int h)
|
||||
: width(w), height(h) {
|
||||
@ -184,5 +184,5 @@ void MainWindow::OnOpenEffectFinish(GuiElement *element) {
|
||||
void MainWindow::OnCloseEffectFinish(GuiElement *element) {
|
||||
//! remove element from draw list and push to delete queue
|
||||
remove(element);
|
||||
AsyncDeleter::pushForDelete(element);
|
||||
AsyncExecutor::pushForDelete(element);
|
||||
}
|
||||
|
@ -1,44 +1,52 @@
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include "Resources.h"
|
||||
#include "filelist.h"
|
||||
#include "system/AsyncDeleter.h"
|
||||
#include <gui/GuiSound.h>
|
||||
#include <gui/GuiImageData.h>
|
||||
#include "fs/FSUtils.h"
|
||||
#include "gui/GuiImageAsync.h"
|
||||
#include "gui/GuiSound.h"
|
||||
#include "utils/AsyncExecutor.h"
|
||||
|
||||
Resources *Resources::instance = NULL;
|
||||
#include <chrono>
|
||||
#include <future>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include <strings.h>
|
||||
|
||||
|
||||
Resources * Resources::instance = NULL;
|
||||
|
||||
void Resources::Clear() {
|
||||
for (int i = 0; RecourceList[i].filename != NULL; ++i) {
|
||||
if (RecourceList[i].CustomFile) {
|
||||
for(int32_t i = 0; RecourceList[i].filename != NULL; ++i) {
|
||||
if(RecourceList[i].CustomFile) {
|
||||
free(RecourceList[i].CustomFile);
|
||||
RecourceList[i].CustomFile = NULL;
|
||||
}
|
||||
|
||||
if (RecourceList[i].CustomFileSize != 0)
|
||||
if(RecourceList[i].CustomFileSize != 0)
|
||||
RecourceList[i].CustomFileSize = 0;
|
||||
}
|
||||
|
||||
if (instance)
|
||||
if(instance)
|
||||
delete instance;
|
||||
|
||||
instance = NULL;
|
||||
}
|
||||
|
||||
bool Resources::LoadFiles(const char *path) {
|
||||
if (!path)
|
||||
bool Resources::LoadFiles(const char * path) {
|
||||
if(!path)
|
||||
return false;
|
||||
|
||||
bool result = false;
|
||||
Clear();
|
||||
|
||||
for (int i = 0; RecourceList[i].filename != NULL; ++i) {
|
||||
for(int32_t i = 0; RecourceList[i].filename != NULL; ++i) {
|
||||
std::string fullpath(path);
|
||||
fullpath += "/";
|
||||
fullpath += RecourceList[i].filename;
|
||||
|
||||
uint8_t *buffer = NULL;
|
||||
uint8_t * buffer = NULL;
|
||||
uint32_t filesize = 0;
|
||||
|
||||
FSUtils::LoadFileToMem(fullpath.c_str(), &buffer, &filesize);
|
||||
@ -51,9 +59,9 @@ bool Resources::LoadFiles(const char *path) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const uint8_t *Resources::GetFile(const char *filename) {
|
||||
for (int i = 0; RecourceList[i].filename != NULL; ++i) {
|
||||
if (strcasecmp(filename, RecourceList[i].filename) == 0) {
|
||||
const uint8_t * Resources::GetFile(const char * filename) {
|
||||
for(int32_t i = 0; RecourceList[i].filename != NULL; ++i) {
|
||||
if(strcasecmp(filename, RecourceList[i].filename) == 0) {
|
||||
return (RecourceList[i].CustomFile ? RecourceList[i].CustomFile : RecourceList[i].DefaultFile);
|
||||
}
|
||||
}
|
||||
@ -61,34 +69,34 @@ const uint8_t *Resources::GetFile(const char *filename) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint32_t Resources::GetFileSize(const char *filename) {
|
||||
for (int i = 0; RecourceList[i].filename != NULL; ++i) {
|
||||
if (strcasecmp(filename, RecourceList[i].filename) == 0) {
|
||||
uint32_t Resources::GetFileSize(const char * filename) {
|
||||
for(int32_t i = 0; RecourceList[i].filename != NULL; ++i) {
|
||||
if(strcasecmp(filename, RecourceList[i].filename) == 0) {
|
||||
return (RecourceList[i].CustomFile ? RecourceList[i].CustomFileSize : RecourceList[i].DefaultFileSize);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
GuiImageData *Resources::GetImageData(const char *filename) {
|
||||
if (!instance)
|
||||
GuiImageData * Resources::GetImageData(const char * filename) {
|
||||
if(!instance)
|
||||
instance = new Resources;
|
||||
|
||||
std::map<std::string, std::pair<unsigned int, GuiImageData *> >::iterator itr = instance->imageDataMap.find(std::string(filename));
|
||||
if (itr != instance->imageDataMap.end()) {
|
||||
std::map<std::string, std::pair<uint32_t, GuiImageData *> >::iterator itr = instance->imageDataMap.find(std::string(filename));
|
||||
if(itr != instance->imageDataMap.end()) {
|
||||
itr->second.first++;
|
||||
return itr->second.second;
|
||||
}
|
||||
|
||||
for (int i = 0; RecourceList[i].filename != NULL; ++i) {
|
||||
if (strcasecmp(filename, RecourceList[i].filename) == 0) {
|
||||
const uint8_t *buff = RecourceList[i].CustomFile ? RecourceList[i].CustomFile : RecourceList[i].DefaultFile;
|
||||
for(int32_t i = 0; RecourceList[i].filename != NULL; ++i) {
|
||||
if(strcasecmp(filename, RecourceList[i].filename) == 0) {
|
||||
const uint8_t * buff = RecourceList[i].CustomFile ? RecourceList[i].CustomFile : RecourceList[i].DefaultFile;
|
||||
const uint32_t size = RecourceList[i].CustomFile ? RecourceList[i].CustomFileSize : RecourceList[i].DefaultFileSize;
|
||||
|
||||
if (buff == NULL)
|
||||
if(buff == NULL)
|
||||
return NULL;
|
||||
|
||||
GuiImageData *image = new GuiImageData(buff, size);
|
||||
GuiImageData * image = new GuiImageData(buff, size);
|
||||
instance->imageDataMap[std::string(filename)].first = 1;
|
||||
instance->imageDataMap[std::string(filename)].second = image;
|
||||
|
||||
@ -99,15 +107,16 @@ GuiImageData *Resources::GetImageData(const char *filename) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Resources::RemoveImageData(GuiImageData *image) {
|
||||
std::map<std::string, std::pair<unsigned int, GuiImageData *> >::iterator itr;
|
||||
void Resources::RemoveImageData(GuiImageData * image) {
|
||||
std::map<std::string, std::pair<uint32_t, GuiImageData *> >::iterator itr;
|
||||
|
||||
for (itr = instance->imageDataMap.begin(); itr != instance->imageDataMap.end(); itr++) {
|
||||
if (itr->second.second == image) {
|
||||
for(itr = instance->imageDataMap.begin(); itr != instance->imageDataMap.end(); itr++) {
|
||||
if(itr->second.second == image) {
|
||||
itr->second.first--;
|
||||
|
||||
if (itr->second.first == 0) {
|
||||
AsyncDeleter::pushForDelete(itr->second.second);
|
||||
if(itr->second.first == 0) {
|
||||
AsyncExecutor::pushForDelete(itr->second.second);
|
||||
|
||||
instance->imageDataMap.erase(itr);
|
||||
}
|
||||
break;
|
||||
@ -115,25 +124,25 @@ void Resources::RemoveImageData(GuiImageData *image) {
|
||||
}
|
||||
}
|
||||
|
||||
GuiSound *Resources::GetSound(const char *filename) {
|
||||
if (!instance)
|
||||
GuiSound * Resources::GetSound(const char * filename) {
|
||||
if(!instance)
|
||||
instance = new Resources;
|
||||
|
||||
std::map<std::string, std::pair<unsigned int, GuiSound *> >::iterator itr = instance->soundDataMap.find(std::string(filename));
|
||||
if (itr != instance->soundDataMap.end()) {
|
||||
std::map<std::string, std::pair<uint32_t, GuiSound *> >::iterator itr = instance->soundDataMap.find(std::string(filename));
|
||||
if(itr != instance->soundDataMap.end()) {
|
||||
itr->second.first++;
|
||||
return itr->second.second;
|
||||
}
|
||||
|
||||
for (int i = 0; RecourceList[i].filename != NULL; ++i) {
|
||||
if (strcasecmp(filename, RecourceList[i].filename) == 0) {
|
||||
const uint8_t *buff = RecourceList[i].CustomFile ? RecourceList[i].CustomFile : RecourceList[i].DefaultFile;
|
||||
for(int32_t i = 0; RecourceList[i].filename != NULL; ++i) {
|
||||
if(strcasecmp(filename, RecourceList[i].filename) == 0) {
|
||||
const uint8_t * buff = RecourceList[i].CustomFile ? RecourceList[i].CustomFile : RecourceList[i].DefaultFile;
|
||||
const uint32_t size = RecourceList[i].CustomFile ? RecourceList[i].CustomFileSize : RecourceList[i].DefaultFileSize;
|
||||
|
||||
if (buff == NULL)
|
||||
if(buff == NULL)
|
||||
return NULL;
|
||||
|
||||
GuiSound *sound = new GuiSound(buff, size);
|
||||
GuiSound * sound = new GuiSound(buff, size);
|
||||
instance->soundDataMap[std::string(filename)].first = 1;
|
||||
instance->soundDataMap[std::string(filename)].second = sound;
|
||||
|
||||
@ -144,15 +153,15 @@ GuiSound *Resources::GetSound(const char *filename) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Resources::RemoveSound(GuiSound *sound) {
|
||||
std::map<std::string, std::pair<unsigned int, GuiSound *> >::iterator itr;
|
||||
void Resources::RemoveSound(GuiSound * sound) {
|
||||
std::map<std::string, std::pair<uint32_t, GuiSound *> >::iterator itr;
|
||||
|
||||
for (itr = instance->soundDataMap.begin(); itr != instance->soundDataMap.end(); itr++) {
|
||||
if (itr->second.second == sound) {
|
||||
for(itr = instance->soundDataMap.begin(); itr != instance->soundDataMap.end(); itr++) {
|
||||
if(itr->second.second == sound) {
|
||||
itr->second.first--;
|
||||
|
||||
if (itr->second.first == 0) {
|
||||
AsyncDeleter::pushForDelete(itr->second.second);
|
||||
if(itr->second.first == 0) {
|
||||
AsyncExecutor::pushForDelete(itr->second.second);
|
||||
instance->soundDataMap.erase(itr);
|
||||
}
|
||||
break;
|
||||
|
@ -1,40 +1,30 @@
|
||||
#ifndef RECOURCES_H_
|
||||
#define RECOURCES_H_
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
#include <stdint.h>
|
||||
|
||||
//! forward declaration
|
||||
class GuiImageData;
|
||||
|
||||
class GuiSound;
|
||||
|
||||
class Resources {
|
||||
public:
|
||||
static void Clear();
|
||||
static bool LoadFiles(const char * path);
|
||||
static const uint8_t * GetFile(const char * filename);
|
||||
static uint32_t GetFileSize(const char * filename);
|
||||
|
||||
static bool LoadFiles(const char *path);
|
||||
|
||||
static const uint8_t *GetFile(const char *filename);
|
||||
|
||||
static uint32_t GetFileSize(const char *filename);
|
||||
|
||||
static GuiImageData *GetImageData(const char *filename);
|
||||
|
||||
static void RemoveImageData(GuiImageData *image);
|
||||
|
||||
static GuiSound *GetSound(const char *filename);
|
||||
|
||||
static void RemoveSound(GuiSound *sound);
|
||||
static GuiImageData * GetImageData(const char * filename);
|
||||
static void RemoveImageData(GuiImageData * image);
|
||||
|
||||
static GuiSound * GetSound(const char * filename);
|
||||
static void RemoveSound(GuiSound * sound);
|
||||
private:
|
||||
static Resources *instance;
|
||||
|
||||
Resources() {}
|
||||
|
||||
~Resources() {}
|
||||
|
||||
std::map<std::string, std::pair<unsigned int, GuiImageData *> > imageDataMap;
|
||||
std::map<std::string, std::pair<unsigned int, GuiSound *> > soundDataMap;
|
||||
};
|
||||
|
||||
#endif
|
||||
std::map<std::string, std::pair<uint32_t, GuiImageData *> > imageDataMap;
|
||||
std::map<std::string, std::pair<uint32_t, GuiSound *> > soundDataMap;
|
||||
};
|
@ -1,62 +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/>.
|
||||
****************************************************************************/
|
||||
#include "AsyncDeleter.h"
|
||||
|
||||
AsyncDeleter *AsyncDeleter::deleterInstance = NULL;
|
||||
|
||||
AsyncDeleter::AsyncDeleter()
|
||||
: CThread(CThread::eAttributeAffCore1 | CThread::eAttributePinnedAff), exitApplication(false) {
|
||||
}
|
||||
|
||||
AsyncDeleter::~AsyncDeleter() {
|
||||
exitApplication = true;
|
||||
}
|
||||
|
||||
void AsyncDeleter::triggerDeleteProcess(void) {
|
||||
if (!deleterInstance)
|
||||
deleterInstance = new AsyncDeleter;
|
||||
|
||||
//! to trigger the event after GUI process is finished execution
|
||||
//! this function is used to swap elements from one to next array
|
||||
if (!deleterInstance->deleteElements.empty()) {
|
||||
deleterInstance->deleteMutex.lock();
|
||||
while (!deleterInstance->deleteElements.empty()) {
|
||||
deleterInstance->realDeleteElements.push(deleterInstance->deleteElements.front());
|
||||
deleterInstance->deleteElements.pop();
|
||||
}
|
||||
deleterInstance->deleteMutex.unlock();
|
||||
deleterInstance->resumeThread();
|
||||
}
|
||||
}
|
||||
|
||||
void AsyncDeleter::executeThread(void) {
|
||||
while (!exitApplication) {
|
||||
suspendThread();
|
||||
|
||||
//! delete elements that require post process deleting
|
||||
//! because otherwise they would block or do invalid access on GUI thread
|
||||
while (!realDeleteElements.empty()) {
|
||||
deleteMutex.lock();
|
||||
GuiElement *element = realDeleteElements.front();
|
||||
realDeleteElements.pop();
|
||||
deleteMutex.unlock();
|
||||
|
||||
delete element;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,63 +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 _ASYNC_DELETER_H
|
||||
#define _ASYNC_DELETER_H
|
||||
|
||||
#include <queue>
|
||||
#include <gui/gui.h>
|
||||
#include "CThread.h"
|
||||
#include "CMutex.h"
|
||||
|
||||
class AsyncDeleter : public CThread {
|
||||
public:
|
||||
static void destroyInstance() {
|
||||
delete deleterInstance;
|
||||
deleterInstance = NULL;
|
||||
}
|
||||
|
||||
class Element {
|
||||
public:
|
||||
Element() {}
|
||||
|
||||
virtual ~Element() {}
|
||||
};
|
||||
|
||||
static void pushForDelete(GuiElement *e) {
|
||||
if (!deleterInstance)
|
||||
deleterInstance = new AsyncDeleter;
|
||||
|
||||
deleterInstance->deleteElements.push(e);
|
||||
}
|
||||
|
||||
static void triggerDeleteProcess(void);
|
||||
|
||||
private:
|
||||
AsyncDeleter();
|
||||
|
||||
virtual ~AsyncDeleter();
|
||||
|
||||
static AsyncDeleter *deleterInstance;
|
||||
|
||||
void executeThread(void);
|
||||
|
||||
bool exitApplication;
|
||||
std::queue<GuiElement *> deleteElements;
|
||||
std::queue<GuiElement *> realDeleteElements;
|
||||
CMutex deleteMutex;
|
||||
};
|
||||
|
||||
#endif // _ASYNC_DELETER_H
|
59
src/utils/AsyncExecutor.cpp
Normal file
59
src/utils/AsyncExecutor.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
#include "AsyncExecutor.h"
|
||||
#include "utils/logger.h"
|
||||
|
||||
AsyncExecutor *AsyncExecutor::instance = NULL;
|
||||
|
||||
void AsyncExecutor::pushForDeleteInternal(GuiElement *ptr) {
|
||||
deleteListMutex.lock();
|
||||
deleteList.push(ptr);
|
||||
deleteListMutex.unlock();
|
||||
}
|
||||
|
||||
AsyncExecutor::AsyncExecutor() {
|
||||
thread = new std::thread([&]() {
|
||||
while (!exitThread) {
|
||||
mutex.lock();
|
||||
bool emptyList = elements.empty();
|
||||
auto it = elements.begin();
|
||||
while (it != elements.end()) {
|
||||
auto future = it;
|
||||
auto status = future->wait_for(std::chrono::seconds(0));
|
||||
if (status == std::future_status::ready) {
|
||||
it = elements.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
if (!emptyList && elements.empty()) {
|
||||
DEBUG_FUNCTION_LINE("All tasks are done");
|
||||
}
|
||||
mutex.unlock();
|
||||
deleteListMutex.lock();
|
||||
while (!deleteList.empty()) {
|
||||
GuiElement *ptr = deleteList.front();
|
||||
deleteList.pop();
|
||||
delete ptr;
|
||||
}
|
||||
deleteListMutex.unlock();
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(16));
|
||||
DCFlushRange((void *) &exitThread, sizeof(exitThread));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
AsyncExecutor::~AsyncExecutor() {
|
||||
exitThread = true;
|
||||
DCFlushRange((void *) &exitThread, sizeof(exitThread));
|
||||
thread->join();
|
||||
}
|
||||
|
||||
void AsyncExecutor::executeInternal(std::function<void()> func) {
|
||||
if (elements.size() > 10) {
|
||||
DEBUG_FUNCTION_LINE("Warning, many tasks running currently");
|
||||
//std::this_thread::sleep_for(std::chrono::milliseconds(16));
|
||||
}
|
||||
mutex.lock();
|
||||
elements.push_back(std::async(std::launch::async, func));
|
||||
mutex.unlock();
|
||||
}
|
53
src/utils/AsyncExecutor.h
Normal file
53
src/utils/AsyncExecutor.h
Normal file
@ -0,0 +1,53 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <future>
|
||||
#include <thread>
|
||||
#include <queue>
|
||||
#include <gui/GuiElement.h>
|
||||
#include <coreinit/cache.h>
|
||||
#include "utils/logger.h"
|
||||
|
||||
class AsyncExecutor {
|
||||
public:
|
||||
static void pushForDelete(GuiElement *element) {
|
||||
if (!instance) {
|
||||
instance = new AsyncExecutor();
|
||||
}
|
||||
instance->pushForDeleteInternal(element);
|
||||
}
|
||||
|
||||
static void execute(std::function<void()> func) {
|
||||
if (!instance) {
|
||||
instance = new AsyncExecutor();
|
||||
}
|
||||
instance->executeInternal(func);
|
||||
}
|
||||
|
||||
static void destroyInstance() {
|
||||
if (instance) {
|
||||
delete instance;
|
||||
instance = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static AsyncExecutor *instance;
|
||||
|
||||
AsyncExecutor();
|
||||
|
||||
~AsyncExecutor();
|
||||
|
||||
void pushForDeleteInternal(GuiElement *element);
|
||||
|
||||
void executeInternal(std::function<void()> func);
|
||||
|
||||
std::recursive_mutex mutex;
|
||||
std::thread *thread;
|
||||
volatile bool exitThread = false;
|
||||
|
||||
std::vector<std::future<void>> elements;
|
||||
|
||||
std::recursive_mutex deleteListMutex;
|
||||
std::queue<GuiElement *> deleteList;
|
||||
};
|
@ -37,7 +37,8 @@
|
||||
|
||||
|
||||
BOOL StringTools::EndsWith(const std::string &a, const std::string &b) {
|
||||
if (b.size() > a.size()) return false;
|
||||
if (b.size() > a.size())
|
||||
return false;
|
||||
return std::equal(a.begin() + a.size() - b.size(), a.end(), b.begin());
|
||||
}
|
||||
|
||||
@ -95,7 +96,7 @@ const wchar_t *StringTools::wfmt(const char *format, ...) {
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
if ((vsprintf(tmp, format, va) >= 0)) {
|
||||
int bt;
|
||||
int32_t bt;
|
||||
int32_t strlength = strlen(tmp);
|
||||
bt = mbstowcs(strWChar, tmp, (strlength < 512) ? strlength : 512);
|
||||
|
||||
@ -144,7 +145,7 @@ BOOL StringTools::char2wchar_t(const char *strChar, wchar_t *dest) {
|
||||
if (!strChar || !dest)
|
||||
return false;
|
||||
|
||||
int bt;
|
||||
int32_t bt;
|
||||
bt = mbstowcs(dest, strChar, strlen(strChar));
|
||||
if (bt > 0) {
|
||||
dest[bt] = 0;
|
||||
@ -208,3 +209,12 @@ std::vector<std::string> StringTools::stringSplit(const std::string &inValue, co
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool StringTools::findStringIC(const std::string &strHaystack, const std::string &strNeedle) {
|
||||
auto it = std::search(
|
||||
strHaystack.begin(), strHaystack.end(),
|
||||
strNeedle.begin(), strNeedle.end(),
|
||||
[](char ch1, char ch2) { return std::toupper(ch1) == std::toupper(ch2); }
|
||||
);
|
||||
return (it != strHaystack.end());
|
||||
}
|
||||
|
@ -23,12 +23,13 @@
|
||||
*
|
||||
* for WiiXplorer 2010
|
||||
***************************************************************************/
|
||||
#ifndef __STRING_TOOLS_H
|
||||
#define __STRING_TOOLS_H
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <wut_types.h>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
|
||||
class StringTools {
|
||||
public:
|
||||
@ -53,7 +54,8 @@ public:
|
||||
static int32_t strextcmp(const char *string, const char *extension, char seperator);
|
||||
|
||||
static const char *FullpathToFilename(const char *path) {
|
||||
if (!path) return path;
|
||||
if (!path)
|
||||
return path;
|
||||
|
||||
const char *ptr = path;
|
||||
const char *Filename = ptr;
|
||||
@ -82,7 +84,7 @@ public:
|
||||
}
|
||||
|
||||
static std::vector<std::string> stringSplit(const std::string &value, const std::string &splitter);
|
||||
|
||||
// https://stackoverflow.com/a/19839371
|
||||
static bool findStringIC(const std::string &strHaystack, const std::string &strNeedle);
|
||||
};
|
||||
|
||||
#endif /* __STRING_TOOLS_H */
|
||||
|
||||
|
@ -1,10 +1,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <malloc.h>
|
||||
#include <utils/logger.h>
|
||||
#include <whb/log.h>
|
||||
#include "utils/logger.h"
|
||||
|
||||
// https://gist.github.com/ccbrown/9722406
|
||||
void dumpHex(const void *data, size_t size) {
|
||||
@ -13,28 +10,28 @@ void dumpHex(const void *data, size_t size) {
|
||||
ascii[16] = '\0';
|
||||
DEBUG_FUNCTION_LINE("0x%08X (0x0000): ", data);
|
||||
for (i = 0; i < size; ++i) {
|
||||
log_printf("%02X ", ((unsigned char *) data)[i]);
|
||||
WHBLogWritef("%02X ", ((unsigned char *) data)[i]);
|
||||
if (((unsigned char *) data)[i] >= ' ' && ((unsigned char *) data)[i] <= '~') {
|
||||
ascii[i % 16] = ((unsigned char *) data)[i];
|
||||
} else {
|
||||
ascii[i % 16] = '.';
|
||||
}
|
||||
if ((i + 1) % 8 == 0 || i + 1 == size) {
|
||||
log_printf(" ");
|
||||
WHBLogWritef(" ");
|
||||
if ((i + 1) % 16 == 0) {
|
||||
log_printf("| %s \n", ascii);
|
||||
WHBLogPrintf("| %s ", ascii);
|
||||
if (i + 1 < size) {
|
||||
DEBUG_FUNCTION_LINE("0x%08X (0x%04X); ", data + i + 1, i + 1);
|
||||
}
|
||||
} else if (i + 1 == size) {
|
||||
ascii[(i + 1) % 16] = '\0';
|
||||
if ((i + 1) % 16 <= 8) {
|
||||
log_printf(" ");
|
||||
WHBLogWritef(" ");
|
||||
}
|
||||
for (j = (i + 1) % 16; j < 16; ++j) {
|
||||
log_printf(" ");
|
||||
WHBLogWritef(" ");
|
||||
}
|
||||
log_printf("| %s \n", ascii);
|
||||
WHBLogPrintf("| %s ", ascii);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,4 @@
|
||||
#ifndef __UTILS_H_
|
||||
#define __UTILS_H_
|
||||
#pragma once
|
||||
|
||||
#include <malloc.h>
|
||||
|
||||
@ -21,6 +20,11 @@ extern "C" {
|
||||
#define ALIGN4(x) (((x) + 3) & ~3)
|
||||
#define ALIGN32(x) (((x) + 31) & ~31)
|
||||
|
||||
// those work only in powers of 2
|
||||
#define ROUNDDOWN(val, align) ((val) & ~(align-1))
|
||||
#define ROUNDUP(val, align) ROUNDDOWN(((val) + (align-1)), align)
|
||||
|
||||
|
||||
#define le16(i) ((((uint16_t) ((i) & 0xFF)) << 8) | ((uint16_t) (((i) & 0xFF00) >> 8)))
|
||||
#define le32(i) ((((uint32_t)le16((i) & 0xFFFF)) << 16) | ((uint32_t)le16(((i) & 0xFFFF0000) >> 16)))
|
||||
#define le64(i) ((((uint64_t)le32((i) & 0xFFFFFFFFLL)) << 32) | ((uint64_t)le32(((i) & 0xFFFFFFFF00000000LL) >> 32)))
|
||||
@ -30,6 +34,4 @@ void dumpHex(const void *data, size_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __UTILS_H_
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user