From c4ffa3622ae02f56168a1e93b978987981f3b68d Mon Sep 17 00:00:00 2001 From: aap Date: Sat, 25 Apr 2020 00:37:49 +0200 Subject: [PATCH] fixed more leaks --- src/anim.cpp | 13 +++++-- src/camera.cpp | 2 +- src/charset.cpp | 5 ++- src/clump.cpp | 4 +-- src/d3d/d3ddevice.cpp | 4 +++ src/d3d/d3dimmed.cpp | 1 + src/engine.cpp | 19 +++++----- src/frame.cpp | 2 +- src/geometry.cpp | 4 +-- src/hanim.cpp | 8 ++++- src/light.cpp | 2 +- src/plg.cpp | 80 +++++++++++++++++++++++++++++++------------ src/rwanim.h | 1 + src/rwplg.h | 44 ++++++++++++++---------- src/texture.cpp | 6 ++-- src/world.cpp | 2 +- 16 files changed, 131 insertions(+), 66 deletions(-) diff --git a/src/anim.cpp b/src/anim.cpp index 4141e88..bbf1fa6 100644 --- a/src/anim.cpp +++ b/src/anim.cpp @@ -24,8 +24,6 @@ namespace rw { static AnimInterpolatorInfo *interpInfoList[MAXINTERPINFO]; -// TODO MEMORY: also clean it up again - void AnimInterpolatorInfo::registerInterp(AnimInterpolatorInfo *interpInfo) { @@ -37,6 +35,17 @@ AnimInterpolatorInfo::registerInterp(AnimInterpolatorInfo *interpInfo) assert(0 && "no room for interpolatorInfo"); } +void +AnimInterpolatorInfo::unregisterInterp(AnimInterpolatorInfo *interpInfo) +{ + for(int32 i = 0; i < MAXINTERPINFO; i++) + if(interpInfoList[i] == interpInfo){ + rwFree(interpInfoList[i]); + interpInfoList[i] = nil; + return; + } +} + AnimInterpolatorInfo* AnimInterpolatorInfo::find(int32 id) { diff --git a/src/camera.cpp b/src/camera.cpp index 66e2fbe..4031e1e 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -15,7 +15,7 @@ namespace rw { int32 Camera::numAllocated; -PluginList Camera::s_plglist = { sizeof(Camera), sizeof(Camera), nil, nil }; +PluginList Camera::s_plglist(sizeof(Camera)); void defaultBeginUpdateCB(Camera *cam) diff --git a/src/charset.cpp b/src/charset.cpp index 1ca88fc..e08d423 100644 --- a/src/charset.cpp +++ b/src/charset.cpp @@ -109,10 +109,9 @@ Charset::setColors(const RGBA *foreground, const RGBA *background) img->palette[7] = foreground->alpha; Raster *newRaster = Raster::createFromImage(img); - if(newRaster == nil){ - img->destroy(); + img->destroy(); + if(newRaster == nil) return nil; - } if(this->raster) this->raster->destroy(); this->raster = newRaster; diff --git a/src/clump.cpp b/src/clump.cpp index 8ccc990..578fb26 100644 --- a/src/clump.cpp +++ b/src/clump.cpp @@ -17,8 +17,8 @@ namespace rw { int32 Clump::numAllocated; int32 Atomic::numAllocated; -PluginList Clump::s_plglist = { sizeof(Clump), sizeof(Clump), nil, nil }; -PluginList Atomic::s_plglist = { sizeof(Atomic), sizeof(Atomic), nil, nil }; +PluginList Clump::s_plglist(sizeof(Clump)); +PluginList Atomic::s_plglist(sizeof(Atomic)); // // Clump diff --git a/src/d3d/d3ddevice.cpp b/src/d3d/d3ddevice.cpp index c05ba33..99ff50e 100644 --- a/src/d3d/d3ddevice.cpp +++ b/src/d3d/d3ddevice.cpp @@ -1207,6 +1207,10 @@ closeD3D(void) if(ref != 0) printf("IDirect3D9_Release did not destroy\n"); d3d9Globals.d3d9 = nil; + rwFree(d3d9Globals.modes); + d3d9Globals.modes = nil; + d3d9Globals.numModes = 0; + d3d9Globals.currentMode = 0; return 1; } diff --git a/src/d3d/d3dimmed.cpp b/src/d3d/d3dimmed.cpp index 61f6112..7a5e47b 100644 --- a/src/d3d/d3dimmed.cpp +++ b/src/d3d/d3dimmed.cpp @@ -240,6 +240,7 @@ closeIm3D(void) destroyVertexBuffer(im3dvertbuf); im3dvertbuf = nil; + removeDynamicIB(&im3dindbuf); destroyIndexBuffer(im3dindbuf); im3dindbuf = nil; } diff --git a/src/engine.cpp b/src/engine.cpp index 5cd0e78..052dab6 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "rwbase.h" #include "rwerror.h" @@ -29,7 +30,7 @@ namespace rw { Engine *engine; -PluginList Engine::s_plglist; +PluginList Engine::s_plglist(sizeof(Engine)); Engine::State Engine::state = Dead; MemoryFunctions Engine::memfuncs; PluginList Driver::s_plglist[NUM_PLATFORMS]; @@ -128,7 +129,7 @@ free_managed(void *p) void *mustmalloc_h(size_t sz, uint32 hint) { void *ret; - ret = rwMalloc(sz, hint); + ret = Engine::memfuncs.rwmalloc(sz, hint); if(ret || sz == 0) return ret; fprintf(stderr, "Error: out of memory\n"); @@ -138,7 +139,7 @@ void *mustmalloc_h(size_t sz, uint32 hint) void *mustrealloc_h(void *p, size_t sz, uint32 hint) { void *ret; - ret = rwRealloc(p, sz, hint); + ret = Engine::memfuncs.rwrealloc(p, sz, hint); if(ret || sz == 0) return ret; fprintf(stderr, "Error: out of memory\n"); @@ -174,13 +175,10 @@ Engine::init(void) memfuncs.rwmustmalloc = mustmalloc_h; memfuncs.rwmustrealloc = mustrealloc_h; - PluginList init = { sizeof(Driver), sizeof(Driver), nil, nil }; + PluginList::open(); + for(uint i = 0; i < NUM_PLATFORMS; i++) - Driver::s_plglist[i] = init; - Engine::s_plglist.size = sizeof(Engine); - Engine::s_plglist.defaultSize = sizeof(Engine); - Engine::s_plglist.first = nil; - Engine::s_plglist.last = nil; + new (&Driver::s_plglist[i]) PluginList(sizeof(Driver)); // core plugin attach here Frame::registerModule(); @@ -288,12 +286,13 @@ Engine::start(void) void Engine::term(void) { - // TODO if(engine || Engine::state != Initialized){ RWERROR((ERR_GENERAL)); return; } + PluginList::close(); + #ifdef TRACK_ALLOCATIONS FORLIST(lnk, allocations){ MemoryBlock *mem = LLLinkGetData(lnk, MemoryBlock, inAllocList); diff --git a/src/frame.cpp b/src/frame.cpp index b3794be..e2c8d25 100644 --- a/src/frame.cpp +++ b/src/frame.cpp @@ -14,7 +14,7 @@ namespace rw { int32 Frame::numAllocated; -PluginList Frame::s_plglist = { sizeof(Frame), sizeof(Frame), nil, nil }; +PluginList Frame::s_plglist(sizeof(Frame)); static void *frameOpen(void *object, int32 offset, int32 size) { engine->frameDirtyList.init(); return object; } static void *frameClose(void *object, int32 offset, int32 size) { return object; } diff --git a/src/geometry.cpp b/src/geometry.cpp index 12dc4ee..e5994c7 100644 --- a/src/geometry.cpp +++ b/src/geometry.cpp @@ -18,8 +18,8 @@ namespace rw { int32 Geometry::numAllocated; int32 Material::numAllocated; -PluginList Geometry::s_plglist = { sizeof(Geometry), sizeof(Geometry), nil, nil }; -PluginList Material::s_plglist = { sizeof(Material), sizeof(Material), nil, nil }; +PluginList Geometry::s_plglist(sizeof(Geometry)); +PluginList Material::s_plglist(sizeof(Material)); static SurfaceProperties defaultSurfaceProps = { 1.0f, 1.0f, 1.0f }; diff --git a/src/hanim.cpp b/src/hanim.cpp index e3893c4..26351de 100644 --- a/src/hanim.cpp +++ b/src/hanim.cpp @@ -383,7 +383,13 @@ hanimOpen(void *object, int32 offset, int32 size) AnimInterpolatorInfo::registerInterp(info); return object; } -static void *hanimClose(void *object, int32 offset, int32 size) { return object; } + +static void* +hanimClose(void *object, int32 offset, int32 size) +{ + AnimInterpolatorInfo::unregisterInterp(AnimInterpolatorInfo::find(1)); + return object; +} void diff --git a/src/light.cpp b/src/light.cpp index b61362d..cfed8dc 100644 --- a/src/light.cpp +++ b/src/light.cpp @@ -15,7 +15,7 @@ namespace rw { int32 Light::numAllocated; -PluginList Light::s_plglist = { sizeof(Light), sizeof(Light), nil, nil }; +PluginList Light::s_plglist(sizeof(Light)); static void lightSync(ObjectWithFrame*) diff --git a/src/plg.cpp b/src/plg.cpp index 6f47bbd..1412a63 100644 --- a/src/plg.cpp +++ b/src/plg.cpp @@ -18,25 +18,58 @@ static void *defCtor(void *object, int32, int32) { return object; } static void *defDtor(void *object, int32, int32) { return object; } static void *defCopy(void *dst, void*, int32, int32) { return dst; } +static LinkList allPlugins; + +#define PLG(lnk) LLLinkGetData(lnk, Plugin, inParentList) + +void +PluginList::open(void) +{ + allPlugins.init(); +} + +void +PluginList::close(void) +{ + PluginList *l; + Plugin *p; + FORLIST(lnk, allPlugins){ + p = LLLinkGetData(lnk, Plugin, inGlobalList); + l = p->parentList; + p->inParentList.remove(); + p->inGlobalList.remove(); + rwFree(p); + if(l->plugins.isEmpty()) + l->size = l->defaultSize; + } + assert(allPlugins.isEmpty()); +} + void PluginList::construct(void *object) { - for(Plugin *p = this->first; p; p = p->next) + FORLIST(lnk, this->plugins){ + Plugin *p = PLG(lnk); p->constructor(object, p->offset, p->size); + } } void PluginList::destruct(void *object) { - for(Plugin *p = this->first; p; p = p->next) + FORLIST(lnk, this->plugins){ + Plugin *p = PLG(lnk); p->destructor(object, p->offset, p->size); + } } void PluginList::copy(void *dst, void *src) { - for(Plugin *p = this->first; p; p = p->next) + FORLIST(lnk, this->plugins){ + Plugin *p = PLG(lnk); p->copy(dst, src, p->offset, p->size); + } } bool @@ -50,12 +83,14 @@ PluginList::streamRead(Stream *stream, void *object) if(!readChunkHeaderInfo(stream, &header)) return false; length -= 12; - for(Plugin *p = this->first; p; p = p->next) + FORLIST(lnk, this->plugins){ + Plugin *p = PLG(lnk); if(p->id == header.type && p->read){ p->read(stream, header.length, object, p->offset, p->size); goto cont; } + } stream->seek(header.length); cont: length -= header.length; @@ -68,7 +103,8 @@ PluginList::streamWrite(Stream *stream, void *object) { int size = this->streamGetSize(object); writeChunkHeader(stream, ID_EXTENSION, size); - for(Plugin *p = this->first; p; p = p->next){ + FORLIST(lnk, this->plugins){ + Plugin *p = PLG(lnk); if(p->getSize == nil || (size = p->getSize(object, p->offset, p->size)) <= 0) continue; @@ -82,10 +118,12 @@ PluginList::streamGetSize(void *object) { int32 size = 0; int32 plgsize; - for(Plugin *p = this->first; p; p = p->next) + FORLIST(lnk, this->plugins){ + Plugin *p = PLG(lnk); if(p->getSize && (plgsize = p->getSize(object, p->offset, p->size)) > 0) size += 12 + plgsize; + } return size; } @@ -107,13 +145,15 @@ PluginList::streamSkip(Stream *stream) void PluginList::assertRights(void *object, uint32 pluginID, uint32 data) { - for(Plugin *p = this->first; p; p = p->next) + FORLIST(lnk, this->plugins){ + Plugin *p = PLG(lnk); if(p->id == pluginID){ if(p->rightsCallback) p->rightsCallback(object, p->offset, p->size, data); return; } + } } @@ -136,17 +176,9 @@ PluginList::registerPlugin(int32 size, uint32 id, p->write = nil; p->getSize = nil; p->rightsCallback = nil; - p->next = nil; - p->prev = nil; - - if(this->first == nil){ - this->first = p; - this->last = p; - }else{ - this->last->next = p; - p->prev = this->last; - this->last = p; - } + p->parentList = this; + this->plugins.add(&p->inParentList); + allPlugins.add(&p->inGlobalList); return p->offset; } @@ -154,33 +186,39 @@ int32 PluginList::registerStream(uint32 id, StreamRead read, StreamWrite write, StreamGetSize getSize) { - for(Plugin *p = this->first; p; p = p->next) + FORLIST(lnk, this->plugins){ + Plugin *p = PLG(lnk); if(p->id == id){ p->read = read; p->write = write; p->getSize = getSize; return p->offset; } + } return -1; } int32 PluginList::setStreamRightsCallback(uint32 id, RightsCallback cb) { - for(Plugin *p = this->first; p; p = p->next) + FORLIST(lnk, this->plugins){ + Plugin *p = PLG(lnk); if(p->id == id){ p->rightsCallback = cb; return p->offset; } + } return -1; } int32 PluginList::getPluginOffset(uint32 id) { - for(Plugin *p = this->first; p; p = p->next) + FORLIST(lnk, this->plugins){ + Plugin *p = PLG(lnk); if(p->id == id) return p->offset; + } return -1; } diff --git a/src/rwanim.h b/src/rwanim.h index c24786b..8967ea7 100644 --- a/src/rwanim.h +++ b/src/rwanim.h @@ -46,6 +46,7 @@ struct AnimInterpolatorInfo uint32 (*streamGetSize)(Animation *anim); static void registerInterp(AnimInterpolatorInfo *interpInfo); + static void unregisterInterp(AnimInterpolatorInfo *interpInfo); static AnimInterpolatorInfo *find(int32 id); }; diff --git a/src/rwplg.h b/src/rwplg.h index bfa8223..69e0f5c 100644 --- a/src/rwplg.h +++ b/src/rwplg.h @@ -11,28 +11,19 @@ typedef Stream *(*StreamWrite)(Stream *stream, int32 length, void *object, int32 typedef int32 (*StreamGetSize)(void *object, int32 offset, int32 size); typedef void (*RightsCallback)(void *object, int32 offset, int32 size, uint32 data); -struct Plugin -{ - int32 offset; - int32 size; - uint32 id; - Constructor constructor; - Destructor destructor; - CopyConstructor copy; - StreamRead read; - StreamWrite write; - StreamGetSize getSize; - RightsCallback rightsCallback; - Plugin *next; - Plugin *prev; -}; - struct PluginList { int32 size; int32 defaultSize; - Plugin *first; - Plugin *last; + LinkList plugins; + + PluginList(void) {} + PluginList(int32 defSize) + : size(defSize), defaultSize(defSize) + { plugins.init(); } + + static void open(void); + static void close(void); void construct(void *); void destruct(void *); @@ -50,6 +41,23 @@ struct PluginList int32 getPluginOffset(uint32 id); }; +struct Plugin +{ + int32 offset; + int32 size; + uint32 id; + Constructor constructor; + Destructor destructor; + CopyConstructor copy; + StreamRead read; + StreamWrite write; + StreamGetSize getSize; + RightsCallback rightsCallback; + PluginList *parentList; + LLLink inParentList; + LLLink inGlobalList; +}; + #define PLUGINBASE \ static PluginList s_plglist; \ static int32 registerPlugin(int32 size, uint32 id, Constructor ctor, \ diff --git a/src/texture.cpp b/src/texture.cpp index 6e89239..fe52097 100644 --- a/src/texture.cpp +++ b/src/texture.cpp @@ -22,9 +22,9 @@ namespace rw { int32 Texture::numAllocated; int32 TexDictionary::numAllocated; -PluginList TexDictionary::s_plglist = { sizeof(TexDictionary), sizeof(TexDictionary), nil, nil }; -PluginList Texture::s_plglist = { sizeof(Texture), sizeof(Texture), nil, nil }; -PluginList Raster::s_plglist = { sizeof(Raster), sizeof(Raster), nil, nil }; +PluginList TexDictionary::s_plglist(sizeof(TexDictionary)); +PluginList Texture::s_plglist(sizeof(Texture)); +PluginList Raster::s_plglist(sizeof(Raster)); struct TextureGlobals { diff --git a/src/world.cpp b/src/world.cpp index 8327e0d..9c0f1cd 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -16,7 +16,7 @@ namespace rw { int32 World::numAllocated = 0; -PluginList World::s_plglist = { sizeof(World), sizeof(World), nil, nil }; +PluginList World::s_plglist(sizeof(World)); World* World::create(void)