[Marble-commits] KDE/kdeedu/marble/src/lib
Jens-Michael Hoffmann
jensmh at gmx.de
Tue Mar 23 10:46:16 CET 2010
SVN commit 1106571 by jmhoffmann:
Fix memory management of TextureTiles.
TextureTiles are created by the TileLoader, which might need to hold a
reference to the TextureTile in case of an outdated tile until the update
arrives. The TextureTiles referenced by TileLoader (using m_waitingForUpdate)
had to be protected from destruction in ~StackedTile by checking the state of
the tile. Ownership of TextureTile was transferred from TileLoader to
StackedTile not after completion of TileLoader::loadTile, but after an
eventual update arrived.
This approach is complicated and error prone and a misuse of the tile state.
Besides it made improvements/fixes in the reload functionality quite difficult.
Using QSharePointer here fixes all these issues and make improvements for
reload possible/more easy.
M +9 -17 StackedTile.cpp
M +2 -1 StackedTile.h
M +2 -1 StackedTileLoader.cpp
M +4 -3 StackedTile_p.h
M +5 -4 TileLoader.cpp
M +3 -2 TileLoader.h
--- trunk/KDE/kdeedu/marble/src/lib/StackedTile.cpp #1106570:1106571
@@ -70,14 +70,6 @@
{
delete [] jumpTable32;
delete [] jumpTable8;
-
- QVector<TextureTile*>::const_iterator pos = m_tiles.constBegin();
- QVector<TextureTile*>::const_iterator const end = m_tiles.constEnd();
- for (; pos != end; ++pos )
- // only delete tiles with stateUptodate as the other ones are managed
- // by the TileLoader until they are fully up to date.
- if ( (*pos)->state() == TextureTile::StateUptodate )
- delete *pos;
}
uint StackedTilePrivate::pixel( int x, int y ) const
@@ -212,12 +204,12 @@
return topLeftValue;
}
-inline void StackedTilePrivate::mergeCopyToResult( TextureTile const * const other )
+inline void StackedTilePrivate::mergeCopyToResult( QSharedPointer<TextureTile> const & other )
{
m_resultTile = other->image()->copy();
}
-void StackedTilePrivate::mergeMultiplyToResult( TextureTile const * const other )
+void StackedTilePrivate::mergeMultiplyToResult( QSharedPointer<TextureTile> const & other )
{
// for this operation we assume that the tiles have the same size
QImage const * const otherImage = other->image();
@@ -264,8 +256,8 @@
bool StackedTile::isExpired() const
{
bool result = false;
- QVector<TextureTile*>::const_iterator pos = d->m_tiles.constBegin();
- QVector<TextureTile*>::const_iterator const end = d->m_tiles.constEnd();
+ QVector<QSharedPointer<TextureTile> >::const_iterator pos = d->m_tiles.constBegin();
+ QVector<QSharedPointer<TextureTile> >::const_iterator const end = d->m_tiles.constEnd();
for (; pos != end; ++pos )
result |= (*pos)->isExpired();
return result;
@@ -281,7 +273,7 @@
d->m_forMergedLayerDecorator = true;
}
-void StackedTile::addTile( TextureTile * const tile )
+void StackedTile::addTile( QSharedPointer<TextureTile> const & tile )
{
d->m_tiles.append( tile );
deriveCompletionState();
@@ -290,8 +282,8 @@
void StackedTile::deriveCompletionState()
{
QMap<TextureTile::State, int> count;
- QVector<TextureTile*>::const_iterator pos = d->m_tiles.constBegin();
- QVector<TextureTile*>::const_iterator const end = d->m_tiles.constEnd();
+ QVector<QSharedPointer<TextureTile> >::const_iterator pos = d->m_tiles.constBegin();
+ QVector<QSharedPointer<TextureTile> >::const_iterator const end = d->m_tiles.constEnd();
for (; pos != end; ++pos )
++count[ (*pos)->state() ];
@@ -378,8 +370,8 @@
void StackedTile::initResultTile()
{
Q_ASSERT( hasTiles() );
- QVector<TextureTile*>::const_iterator pos = d->m_tiles.constBegin();
- QVector<TextureTile*>::const_iterator const end = d->m_tiles.constEnd();
+ QVector<QSharedPointer<TextureTile> >::const_iterator pos = d->m_tiles.constBegin();
+ QVector<QSharedPointer<TextureTile> >::const_iterator const end = d->m_tiles.constEnd();
for (; pos != end; ++pos )
if ( (*pos)->state() != TextureTile::StateEmpty )
switch ( (*pos)->mergeRule() ) {
--- trunk/KDE/kdeedu/marble/src/lib/StackedTile.h #1106570:1106571
@@ -17,6 +17,7 @@
#ifndef MARBLE_STACKED_TILE_H
#define MARBLE_STACKED_TILE_H
+#include <QtCore/QSharedPointer>
#include <QtGui/QColor>
#include "AbstractTile.h"
@@ -72,7 +73,7 @@
Q_DECLARE_PRIVATE( StackedTile )
Q_DISABLE_COPY( StackedTile )
- void addTile( TextureTile * const );
+ void addTile( QSharedPointer<TextureTile> const & );
void deriveCompletionState();
void initJumpTables();
bool hasTiles() const;
--- trunk/KDE/kdeedu/marble/src/lib/StackedTileLoader.cpp #1106570:1106571
@@ -191,7 +191,8 @@
stackedTileId.x(), stackedTileId.y() );
mDebug() << "StackedTileLoader::loadTile: tile" << textureLayer->sourceDir()
<< simpleTileId.toString();
- TextureTile * const simpleTile = d->m_tileLoader->loadTile( stackedTileId, simpleTileId );
+ QSharedPointer<TextureTile> const simpleTile = d->m_tileLoader->loadTile( stackedTileId,
+ simpleTileId );
// hack to try clouds, first tile is not handled here, MergeCopy is the default,
// the merge rule for following tiles is set to MergeMultiply here
if ( simpleTile && tile->hasTiles() )
--- trunk/KDE/kdeedu/marble/src/lib/StackedTile_p.h #1106570:1106571
@@ -20,6 +20,7 @@
#include "AbstractTile_p.h"
+#include <QtCore/QSharedPointer>
#include <QtCore/QVector>
#include <QtGui/QImage>
@@ -35,7 +36,7 @@
uchar **jumpTable8;
uint **jumpTable32;
- QVector<TextureTile*> m_tiles;
+ QVector<QSharedPointer<TextureTile> > m_tiles;
QImage m_resultTile;
int m_depth;
@@ -47,8 +48,8 @@
inline uint pixel( int x, int y ) const;
inline uint pixelF( qreal x, qreal y, const QRgb& pixel ) const;
- void mergeCopyToResult( TextureTile const * const tile );
- void mergeMultiplyToResult( TextureTile const * const tile );
+ void mergeCopyToResult( QSharedPointer<TextureTile> const & tile );
+ void mergeMultiplyToResult( QSharedPointer<TextureTile> const & tile );
};
}
--- trunk/KDE/kdeedu/marble/src/lib/TileLoader.cpp #1106570:1106571
@@ -42,7 +42,7 @@
// - if not expired: create TextureTile, set state to "uptodate", return it => done
// - if expired: create TextureTile, state is set to Expired by default, trigger dl,
-TextureTile * TileLoader::loadTile( TileId const & stackedTileId, TileId const & tileId )
+QSharedPointer<TextureTile> TileLoader::loadTile( TileId const & stackedTileId, TileId const & tileId )
{
QString const fileName = tileFileName( tileId );
QFileInfo const fileInfo( fileName );
@@ -50,7 +50,7 @@
// file is there, so create and return a tile object in any case,
// but check if an update should be triggered
GeoSceneTexture const * const textureLayer = findTextureLayer( tileId );
- TextureTile * const tile = new TextureTile( tileId, fileName );
+ QSharedPointer<TextureTile> const tile( new TextureTile( tileId, fileName ));
tile->setStackedTileId( stackedTileId );
tile->setLastModified( fileInfo.lastModified() );
tile->setExpireSecs( textureLayer->expire() );
@@ -68,7 +68,7 @@
// tile was not locally available => trigger download and look for tiles in other levels
// for scaling
- TextureTile * const tile = new TextureTile( tileId );
+ QSharedPointer<TextureTile> const tile( new TextureTile( tileId ));
tile->setStackedTileId( stackedTileId );
m_waitingForUpdate.insert( tileId, tile );
triggerDownload( tileId );
@@ -86,7 +86,8 @@
void TileLoader::updateTile( QByteArray const & data, QString const & tileId )
{
TileId const id = TileId::fromString( tileId );
- TextureTile * const tile = m_waitingForUpdate.value( id, 0 );
+ QSharedPointer<TextureTile> const tile =
+ m_waitingForUpdate.value( id, QSharedPointer<TextureTile>() );
// preliminary fix for reload map crash
// TODO: fix properly
if ( !tile )
--- trunk/KDE/kdeedu/marble/src/lib/TileLoader.h #1106570:1106571
@@ -18,6 +18,7 @@
#include <QtCore/QHash>
#include <QtCore/QObject>
+#include <QtCore/QSharedPointer>
#include <QtCore/QString>
#include "TileId.h"
@@ -41,7 +42,7 @@
public:
TileLoader( MapThemeManager const * const, HttpDownloadManager * const );
- TextureTile * loadTile( TileId const & stackedTileId, TileId const & tileId );
+ QSharedPointer<TextureTile> loadTile( TileId const & stackedTileId, TileId const & tileId );
void setTextureLayers( QHash<uint, GeoSceneTexture*> const & );
public Q_SLOTS:
@@ -67,7 +68,7 @@
// contains tiles, for which a download has been triggered
// because the tile was not there at all or is expired.
- QHash<TileId, TextureTile*> m_waitingForUpdate;
+ QHash<TileId, QSharedPointer<TextureTile> > m_waitingForUpdate;
};
inline void TileLoader::setTextureLayers( QHash<uint, GeoSceneTexture*> const & layers )
More information about the Marble-commits
mailing list