From e2e5bc49205f09d70f04fd924e6552822b27304d Mon Sep 17 00:00:00 2001 From: AlexVinS Date: Tue, 30 Aug 2016 05:46:25 +0300 Subject: [PATCH] fixed fadeAnims memory leak --- client/mapHandler.cpp | 97 ++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 48 deletions(-) diff --git a/client/mapHandler.cpp b/client/mapHandler.cpp index 28ae41067..f859ea6e0 100644 --- a/client/mapHandler.cpp +++ b/client/mapHandler.cpp @@ -539,7 +539,7 @@ SDL_Surface * CMapHandler::CMapWorldViewBlitter::objectToIcon(Obj id, si32 subId { ownerIndex = PlayerColor::PLAYER_LIMIT.getNum() * 19; } - + switch(id) { case Obj::MONOLITH_ONE_WAY_ENTRANCE: @@ -558,8 +558,8 @@ SDL_Surface * CMapHandler::CMapWorldViewBlitter::objectToIcon(Obj id, si32 subId return info->iconsDef->ourImages[(int)EWorldViewIcon::MINE_WOOD + subId + ownerIndex].bitmap; case Obj::RESOURCE: return info->iconsDef->ourImages[(int)EWorldViewIcon::RES_WOOD + subId + ownerIndex].bitmap; - } - return nullptr; + } + return nullptr; } void CMapHandler::CMapWorldViewBlitter::calculateWorldViewCameraPos() @@ -660,7 +660,7 @@ void CMapHandler::CMapWorldViewBlitter::drawTileOverlay(SDL_Surface * targetSurf { const CGObjectInstance * obj = object.obj; - const bool sameLevel = obj->pos.z == pos.z; + const bool sameLevel = obj->pos.z == pos.z; const bool isVisible = (*info->visibilityMap)[pos.x][pos.y][pos.z]; const bool isVisitable = obj->visitableAt(pos.x, pos.y); @@ -673,31 +673,31 @@ void CMapHandler::CMapWorldViewBlitter::drawOverlayEx(SDL_Surface * targetSurf) { if(nullptr == info->additionalIcons) return; - + const int3 bottomRight = pos + tileCount; - + for(const ObjectPosInfo & iconInfo : *(info->additionalIcons)) { if( iconInfo.pos.z != pos.z) continue; - + if((iconInfo.pos.x < topTile.x) || (iconInfo.pos.y < topTile.y)) continue; - + if((iconInfo.pos.x > bottomRight.x) || (iconInfo.pos.y > bottomRight.y)) - continue; - + continue; + realPos.x = initPos.x + (iconInfo.pos.x - topTile.x) * tileSize; realPos.y = initPos.x + (iconInfo.pos.y - topTile.y) * tileSize; - - SDL_Surface * wvIcon = this->objectToIcon(iconInfo.id, iconInfo.subId, iconInfo.owner); - + + SDL_Surface * wvIcon = this->objectToIcon(iconInfo.id, iconInfo.subId, iconInfo.owner); + if (nullptr != wvIcon) { // centering icon on the object Rect destRect(realPos.x + tileSize / 2 - wvIcon->w / 2, realPos.y + tileSize / 2 - wvIcon->h / 2, wvIcon->w, wvIcon->h); CSDL_Ext::blitSurface(wvIcon, nullptr, targetSurf, &destRect); - } + } } } @@ -837,7 +837,7 @@ void CMapHandler::CMapBlitter::drawObjects(SDL_Surface * targetSurf, const Terra for(auto & object : objects) { if (object.fadeAnimKey >= 0) - { + { auto fadeIter = parent->fadeAnims.find(object.fadeAnimKey); if (fadeIter != parent->fadeAnims.end()) { @@ -850,14 +850,14 @@ void CMapHandler::CMapBlitter::drawObjects(SDL_Surface * targetSurf, const Terra logGlobal->errorStream() << "Fading map object with missing fade anim : " << object.fadeAnimKey; continue; } - + const CGObjectInstance * obj = object.obj; if (!obj) { logGlobal->errorStream() << "Stray map object that isn't fading"; continue; } - + if (!graphics->getDef(obj)) processDef(obj->appearance); if (!graphics->getDef(obj)) @@ -872,12 +872,12 @@ void CMapHandler::CMapBlitter::drawObjects(SDL_Surface * targetSurf, const Terra if (!canDrawObject(obj)) continue; - + auto objData = findObjectBitmap(obj, info->anim); if (objData.objBitmap) - { + { Rect srcRect(object.rect.x, object.rect.y, tileSize, tileSize); - + drawObject(targetSurf, objData.objBitmap, &srcRect, objData.isMoving); if (objData.flagBitmap) { @@ -890,7 +890,7 @@ void CMapHandler::CMapBlitter::drawObjects(SDL_Surface * targetSurf, const Terra else if (obj->pos.x == pos.x && obj->pos.y == pos.y) { Rect dstRect(realPos.x - 2 * tileSize, realPos.y - tileSize, 3 * tileSize, 2 * tileSize); - drawHeroFlag(targetSurf, objData.flagBitmap, nullptr, &dstRect, false); + drawHeroFlag(targetSurf, objData.flagBitmap, nullptr, &dstRect, false); } } } @@ -946,7 +946,7 @@ void CMapHandler::CMapBlitter::blit(SDL_Surface * targetSurf, const MapDrawingIn { if (pos.y < 0 || pos.y >= parent->sizes.y) continue; - + const bool isVisible = canDrawCurrentTile(); realTileRect.x = realPos.x; @@ -955,13 +955,13 @@ void CMapHandler::CMapBlitter::blit(SDL_Surface * targetSurf, const MapDrawingIn const TerrainTile2 & tile = parent->ttiles[pos.x][pos.y][pos.z]; const TerrainTile & tinfo = parent->map->getTile(pos); const TerrainTile * tinfoUpper = pos.y > 0 ? &parent->map->getTile(int3(pos.x, pos.y - 1, pos.z)) : nullptr; - + if(isVisible || info->showAllTerrain) { drawTileTerrain(targetSurf, tinfo, tile); if (tinfo.riverType) drawRiver(targetSurf, tinfo); - drawRoad(targetSurf, tinfo, tinfoUpper); + drawRoad(targetSurf, tinfo, tinfoUpper); } if(isVisible) @@ -1017,8 +1017,8 @@ void CMapHandler::CMapBlitter::blit(SDL_Surface * targetSurf, const MapDrawingIn } } } - - drawOverlayEx(targetSurf); + + drawOverlayEx(targetSurf); // drawDebugGrid() if (settings["session"]["showGrid"].Bool()) @@ -1091,10 +1091,10 @@ CMapHandler::AnimBitmapHolder CMapHandler::CMapBlitter::findBoatBitmap(const CGB } SDL_Surface * CMapHandler::CMapBlitter::findFlagBitmap(const CGHeroInstance * hero, int anim, const PlayerColor * color, int indexOffset) const -{ +{ if (!hero) return nullptr; - + if (hero->boat) return findBoatFlagBitmap(hero->boat, anim, color, indexOffset, hero->moveDir); return findHeroFlagBitmap(hero, anim, color, indexOffset); @@ -1121,8 +1121,8 @@ SDL_Surface * CMapHandler::CMapBlitter::findBoatFlagBitmap(const CGBoat * boat, SDL_Surface * CMapHandler::CMapBlitter::findFlagBitmapInternal(const CDefEssential * def, int anim, int indexOffset, ui8 dir, bool moving) const { if (moving) - return def->ourImages[indexOffset + anim % FRAMES_PER_MOVE_ANIM_GROUP].bitmap; - return def->ourImages[getHeroFrameNum(dir, false) * FRAMES_PER_MOVE_ANIM_GROUP + (anim / 4) % FRAMES_PER_MOVE_ANIM_GROUP].bitmap; + return def->ourImages[indexOffset + anim % FRAMES_PER_MOVE_ANIM_GROUP].bitmap; + return def->ourImages[getHeroFrameNum(dir, false) * FRAMES_PER_MOVE_ANIM_GROUP + (anim / 4) % FRAMES_PER_MOVE_ANIM_GROUP].bitmap; } int CMapHandler::CMapBlitter::findAnimIndexByGroup(const CDefEssential * def, int groupNum) const @@ -1141,9 +1141,9 @@ CMapHandler::AnimBitmapHolder CMapHandler::CMapBlitter::findObjectBitmap(const C return findHeroBitmap(static_cast(obj), anim); if (obj->ID == Obj::BOAT) return findBoatBitmap(static_cast(obj), anim); - - // normal object - + + // normal object + const std::vector &ourImages = graphics->getDef(obj)->ourImages; SDL_Surface *bitmap = ourImages[(anim + getPhaseShift(obj)) % ourImages.size()].bitmap; @@ -1214,14 +1214,14 @@ std::pair CMapHandler::CMapBlitter::getVisBitmap() const } bool CMapHandler::updateObjectsFade() -{ +{ for (auto iter = fadeAnims.begin(); iter != fadeAnims.end(); ) { int3 pos = (*iter).second.first; CFadeAnimation * anim = (*iter).second.second; - + anim->update(); - + if (anim->isFading()) ++iter; else // fade finished @@ -1230,7 +1230,7 @@ bool CMapHandler::updateObjectsFade() for (auto objIter = objs.begin(); objIter != objs.end(); ++objIter) { if ((*objIter).fadeAnimKey == (*iter).first) - { + { logAnim->traceStream() << "Fade anim finished for obj at " << pos << "; remaining: " << (fadeAnims.size() - 1); if (anim->fadingMode == CFadeAnimation::EMode::OUT) objs.erase(objIter); // if this was fadeout, remove the object from the map @@ -1239,10 +1239,11 @@ bool CMapHandler::updateObjectsFade() break; } } + delete (*iter).second.second; iter = fadeAnims.erase(iter); } } - + return !fadeAnims.empty(); } @@ -1250,7 +1251,7 @@ bool CMapHandler::startObjectFade(TerrainTileObject & obj, bool in, int3 pos) { SDL_Surface * fadeBitmap; assert(obj.obj); - + auto objData = normalBlitter->findObjectBitmap(obj.obj, 0); if (objData.objBitmap) { @@ -1259,7 +1260,7 @@ bool CMapHandler::startObjectFade(TerrainTileObject & obj, bool in, int3 pos) logAnim->debugStream() << "Ignoring fade of moving object"; return false; } - + fadeBitmap = CSDL_Ext::newSurface(32, 32); // TODO cache these bitmaps instead of creating new ones? Rect objSrcRect(obj.rect.x, obj.rect.y, 32, 32); CSDL_Ext::blit8bppAlphaTo24bpp(objData.objBitmap, &objSrcRect, fadeBitmap, nullptr); @@ -1275,12 +1276,12 @@ bool CMapHandler::startObjectFade(TerrainTileObject & obj, bool in, int3 pos) anim->init(in ? CFadeAnimation::EMode::IN : CFadeAnimation::EMode::OUT, fadeBitmap, true); fadeAnims[++fadeAnimCounter] = std::pair(pos, anim); obj.fadeAnimKey = fadeAnimCounter; - - logAnim->traceStream() << "Fade anim started for obj " << obj.obj->ID + + logAnim->traceStream() << "Fade anim started for obj " << obj.obj->ID << " at " << pos << "; anim count: " << fadeAnims.size(); return true; } - + return false; } @@ -1303,17 +1304,17 @@ bool CMapHandler::printObject(const CGObjectInstance *obj, bool fadein /* = fals cr.x = fx*32; cr.y = fy*32; TerrainTileObject toAdd(obj, cr); - + if((obj->pos.x + fx - tilesW+1)>=0 && (obj->pos.x + fx - tilesW+1)pos.y + fy - tilesH+1)>=0 && (obj->pos.y + fy - tilesH+1)pos.x + fx - tilesW + 1, obj->pos.y + fy - tilesH + 1, obj->pos.z); - TerrainTile2 & curt = ttiles[pos.x][pos.y][pos.z]; - + TerrainTile2 & curt = ttiles[pos.x][pos.y][pos.z]; + if (fadein && ADVOPT.objectFading) { startObjectFade(toAdd, true, pos); } - + auto i = curt.objects.begin(); for(; i != curt.objects.end(); i++) { @@ -1543,7 +1544,7 @@ CMapHandler::~CMapHandler() for(int j=0; j < elem.size(); ++j) SDL_FreeSurface(elem[j]); } - + for (auto & elem : fadeAnims) { delete elem.second.second;