Jeck - Cache fix, booster duplicate fix.

* Restored OptionItem saving fix.
 * Booster duplicate replacement was picking random cards from the wrong set. My fault, but I've fixed it :)
 * The problem with cache had nothing to do with memory fragmentation, but I've switched to an array rather than map<> just in case. The actual issue was that in GameStateDeckViewer, I'd given the cache unlimited space, thinking that AttemptNew would recover from any bad_allocs. Unfortunately, the image loading routines and similar stuff called by various implementations of WResource::Attempt() could fail halfway through, leaking memory. 

The temporary solution is to set a proper limit (8000000 px, more or less) and (in case we still run out of memory) test to make certain CACHE_SPACE_RESERVED can be malloc'd/free'd. The proper solution would be to keep byte-perfect records of memory used (right now we're kinda fuzzy-- we track pixels per image and bytes per sound, but not the space for jquads or other incidentals) instead of testing a malloc, and potentially cleaning up all calls inside of Attempt() so they fail without leaks. That's what I'm working on now.

Still, it's nice to have identified the problem. This version of the cache should be fully functional, it's just a bit inelegant.
This commit is contained in:
wagic.jeck
2009-09-19 21:11:35 +00:00
parent e0f5a81dad
commit 0d3686e65a
8 changed files with 411 additions and 416 deletions

View File

@@ -16,13 +16,16 @@ WResource::~WResource(){
return;
}
WResource::WResource(){
locks = WRES_UNLOCKED;
locks = WRES_TRASH;
lastTime = resources.nowTime();
loadedMode = 0;
}
bool WResource::isLocked(){
return (locks != WRES_UNLOCKED);
return (locks != WRES_UNLOCKED && locks != WRES_TRASH);
}
bool WResource::isTrash(){
return (locks == WRES_TRASH);
}
bool WResource::isPermanent(){
@@ -171,8 +174,10 @@ WTrackedQuad * WCachedTexture::GetTrackedQuad(float offX, float offY, float widt
tq = *gtq;
garbageTQs.erase(gtq);
}
else
else{
tq = NEW WTrackedQuad(resname);
tq->unlock(true);
}
}
if(tq == NULL)
@@ -244,6 +249,9 @@ unsigned long WCachedTexture::size(){
}
bool WCachedTexture::isGood(){
if(locks == WRES_TRASH)
return false;
if(!texture)
return false;
@@ -321,6 +329,9 @@ bool WCachedTexture::Attempt(string filename, int submode, int & error){
return false;
}
if(locks == WRES_TRASH)
locks = WRES_UNLOCKED;
error = CACHE_ERROR_NONE;
return true;
}
@@ -330,6 +341,11 @@ void WCachedTexture::Nullify(){
texture = NULL;
}
void WCachedTexture::Trash(){
id = "";
locks = WRES_TRASH;
#ifdef DEBUG_CACHE
OutputDebugString("WCachedTexture::Trash()\n");
#endif
SAFE_DELETE(texture);
vector<WTrackedQuad*>::iterator it;
@@ -355,6 +371,11 @@ void WCachedSample::Nullify(){
}
void WCachedSample::Trash(){
id = "";
locks = WRES_TRASH;
#ifdef DEBUG_CACHE
OutputDebugString("WCachedSample::Trash()\n");
#endif
SAFE_DELETE(sample);
}
@@ -388,6 +409,9 @@ unsigned long WCachedSample::size(){
}
bool WCachedSample::isGood(){
if(locks == WRES_TRASH)
return false;
if(!sample || !sample->mSample)
return false;
@@ -412,12 +436,18 @@ bool WCachedSample::Attempt(string filename, int submode, int & error){
return false;
}
if(locks == WRES_TRASH)
locks = WRES_UNLOCKED;
return true;
}
//WCachedParticles
bool WCachedParticles::isGood(){
if(locks == WRES_TRASH)
return false;
if(!particles)
return false;
return true;
@@ -463,6 +493,10 @@ bool WCachedParticles::Attempt(string filename, int submode, int & error){
particles->sprite=NULL;
error = CACHE_ERROR_NONE;
if(locks == WRES_TRASH)
locks = WRES_UNLOCKED;
return true;
}
@@ -489,6 +523,11 @@ void WCachedParticles::Nullify(){
}
void WCachedParticles::Trash(){
id = "";
locks = WRES_TRASH;
#ifdef DEBUG_CACHE
OutputDebugString("WCachedParticles::Trash()\n");
#endif
SAFE_DELETE(particles);
}
@@ -498,6 +537,11 @@ void WTrackedQuad::Nullify() {
}
void WTrackedQuad::Trash(){
id = "";
locks = WRES_TRASH;
#ifdef DEBUG_CACHE
OutputDebugString("WTrackedQuad::Trash()\n");
#endif
resname.clear();
SAFE_DELETE(quad);
}
@@ -510,6 +554,9 @@ unsigned long WTrackedQuad::size() {
return sizeof(JQuad);
}
bool WTrackedQuad::isGood(){
if(locks == WRES_TRASH)
return false;
return (quad != NULL);
}
WTrackedQuad::WTrackedQuad(string _resname) {