*Added an internal image resource manager for the GuiImageData class so that one image is reused as many times as it is needed with using only one space in memory. Image is freed when the "in use counter" is 0. This should save quite some memory.

This commit is contained in:
dimok321 2010-09-26 09:25:11 +00:00
parent 8bec876889
commit 0358aaac72
6 changed files with 233 additions and 8 deletions

View File

@ -2,8 +2,8 @@
<app version="1">
<name> USB Loader GX</name>
<coder>USB Loader GX Team</coder>
<version>1.0 r976</version>
<release_date>201009251926</release_date>
<version>1.0 r977</version>
<release_date>201009260906</release_date>
<short_description>Loads games from USB-devices</short_description>
<long_description>USB Loader GX is a libwiigui based USB iso loader with a wii-like GUI. You can install games to your HDDs and boot them with shorter loading times.
The interactive GUI is completely controllable with WiiMote, Classic Controller or GC Controller.

View File

@ -27,6 +27,7 @@
#include "ImageOperations/TextureConverter.h"
#include "ImageOperations/TplImage.h"
#include "FileOperations/fileops.h"
#include "utils/ResourceManager.h"
#define ALIGN32(x) (((x) + 31) & ~31)
@ -59,7 +60,19 @@ GuiImageData::GuiImageData(const u8 * img, int imgSize)
height = 0;
format = GX_TF_RGBA8;
LoadImage(img, imgSize);
if(ResourceManager::Exists(img, imgSize) == true)
{
GuiImageData * Image = ResourceManager::GetImageData(img, imgSize);
data = Image->GetImage();
width = Image->GetWidth();
height = Image->GetHeight();
format = Image->GetTextureFormat();
}
else
{
LoadImage(img, imgSize);
}
}
/**
@ -67,11 +80,8 @@ GuiImageData::GuiImageData(const u8 * img, int imgSize)
*/
GuiImageData::~GuiImageData()
{
if(data)
{
free(data);
data = NULL;
}
if(data)
ResourceManager::Remove(data);
}
void GuiImageData::LoadImage(const u8 * img, int imgSize)

View File

@ -4,6 +4,7 @@
#include "mload/mload.h"
#include "settings/CSettings.h"
#include "utils/ResourceManager.h"
#include "audio.h"
#include "fatmounter.h"
#include "lstub.h"
@ -54,6 +55,8 @@ static void _ExitApp()
StopGX();
ShutdownAudio();
ResourceManager::DestroyInstance();
UnmountNTFS();
SDCard_deInit();
USBDevice_deInit();

View File

@ -141,6 +141,7 @@ CTheme::CTheme()
CTheme::~CTheme()
{
Resources::Clear();
}
void CTheme::SetDefault()

View File

@ -0,0 +1,153 @@
/***************************************************************************
* Copyright (C) 2010
* by Dimok
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
***************************************************************************/
#include "ResourceManager.h"
ResourceManager * ResourceManager::instance = NULL;
ResourceManager * ResourceManager::Instance()
{
if (instance == NULL)
{
instance = new ResourceManager();
}
return instance;
}
void ResourceManager::DestroyInstance()
{
if (instance != NULL)
{
delete instance;
instance = NULL;
}
}
ResourceManager::~ResourceManager()
{
// Delete all images...
std::map<const u8 *, GuiImageData *>::iterator imgitr;
for (imgitr = images.begin(); imgitr != images.end(); imgitr++)
{
delete imgitr->second;
}
images.clear();
imageCount.clear();
}
bool ResourceManager::Exists(const u8 *img, u32 imgSize)
{
return ResourceManager::Instance()->InternalExists(img, imgSize);
}
bool ResourceManager::InternalExists(const u8 *img, u32 imgSize)
{
std::map<const u8 *, GuiImageData *>::iterator itr = images.find(img);
return (itr != images.end());
}
GuiImageData * ResourceManager::GetImageData(const u8 *img, u32 imgSize)
{
return ResourceManager::Instance()->InternalGetImageData(img, imgSize);
}
void ResourceManager::Remove(GuiImageData *img)
{
if(!img)
return;
ResourceManager::Instance()->InternalRemoveImageData(img->GetImage());
}
void ResourceManager::Remove(u8 *img)
{
ResourceManager::Instance()->InternalRemoveImageData(img);
}
GuiImageData * ResourceManager::InternalGetImageData(const u8 *img, u32 imgSize)
{
std::map<const u8 *, GuiImageData *>::iterator itr = images.find(img);
if (itr == images.end())
{
// Not found, create a new one
GuiImageData *d = new GuiImageData(img, imgSize);
images[img] = d;
imageCount[d->GetImage()] = 1;
return d;
}
imageCount[itr->second->GetImage()]++;
return itr->second;
}
void ResourceManager::InternalRemoveImageData(u8 * img)
{
std::map<u8 *, int>::iterator itr = imageCount.find(img);
if (itr != imageCount.end())
{
itr->second--;
if (itr->second == 0) // Remove the resource
{
imageCount.erase(itr);
std::map<const u8 *, GuiImageData *>::iterator iitr;
for (iitr = images.begin(); iitr != images.end(); iitr++)
{
if (iitr->second->GetImage() == img)
{
delete iitr->second;
images.erase(iitr);
break;
}
}
}
}
}
void ResourceManager::InternalRemoveImageData(GuiImageData * img)
{
std::map<u8 *, int>::iterator itr = imageCount.find(img->GetImage());
if (itr != imageCount.end())
{
itr->second--;
if (itr->second == 0) // Remove the resource
{
imageCount.erase(itr);
std::map<const u8 *, GuiImageData *>::iterator iitr;
for (iitr = images.begin(); iitr != images.end(); iitr++)
{
if (iitr->second == img)
{
delete iitr->second;
images.erase(iitr);
break;
}
}
}
}
}

View File

@ -0,0 +1,58 @@
/***************************************************************************
* Copyright (C) 2010
* by Dimok
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any
* damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any
* purpose, including commercial applications, and to alter it and
* redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you
* must not claim that you wrote the original software. If you use
* this software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and
* must not be misrepresented as being the original software.
*
* 3. This notice may not be removed or altered from any source
* distribution.
***************************************************************************/
#ifndef _RESOURCE_MANAGER_H
#define _RESOURCE_MANAGER_H
#include <gccore.h>
#include "libwiigui/gui.h"
#include "filelist.h"
#include <map>
class ResourceManager
{
public:
static ResourceManager *Instance();
static void DestroyInstance();
static GuiImageData * GetImageData(const u8 *img, u32 imgSize);
static bool Exists(const u8 *img, u32 imgSize);
static void Remove(GuiImageData * img);
static void Remove(u8 * img);
private:
bool InternalExists(const u8 *img, u32 imgSize);
GuiImageData *InternalGetImageData(const u8 *img, u32 imgSize);
void InternalRemoveImageData(GuiImageData *img);
void InternalRemoveImageData(u8 *img);
~ResourceManager();
static ResourceManager *instance;
std::map<const u8 *, GuiImageData *> images;
std::map<u8 *, int> imageCount;
};
#endif //_ResourceManager_H