-rw-r--r-- | noncore/multimedia/opieplayer2/singleton.h | 49 | ||||
-rw-r--r-- | noncore/multimedia/opieplayer2/skin.cpp | 58 | ||||
-rw-r--r-- | noncore/multimedia/opieplayer2/skin.h | 52 |
3 files changed, 155 insertions, 4 deletions
diff --git a/noncore/multimedia/opieplayer2/singleton.h b/noncore/multimedia/opieplayer2/singleton.h new file mode 100644 index 0000000..35b3dff --- a/dev/null +++ b/noncore/multimedia/opieplayer2/singleton.h @@ -0,0 +1,49 @@ +#ifndef SINGLETON_H +#define SINGLETON_H + +template <class Product> +struct DefaultSingletonCreator +{ + static Product *create() { return new Product; } +}; + +template <class Product> +struct NullSingletonCreator +{ + static Product *create() { return 0; } +}; + +template +< + class T, + template <class> class Creator = DefaultSingletonCreator +> +class Singleton +{ +public: + static T &self() + { + if ( !s_self ) + s_self = Creator<T>::create(); + return *s_self; + } + +protected: + Singleton() + { s_self = static_cast<T *>( this ); } + ~Singleton() + { s_self = 0; } + +private: + Singleton( const Singleton<T, Creator> &rhs ); + Singleton<T, Creator> &operator=( const Singleton<T, Creator> &rhs ); + + static T *s_self; +}; + +template <class T, template <class> class Creator> +T *Singleton<T, Creator>::s_self = 0; + +#endif // SINGLETON_H +/* vim: et sw=4 ts=4 + */ diff --git a/noncore/multimedia/opieplayer2/skin.cpp b/noncore/multimedia/opieplayer2/skin.cpp index 8281b20..0de3023 100644 --- a/noncore/multimedia/opieplayer2/skin.cpp +++ b/noncore/multimedia/opieplayer2/skin.cpp @@ -3,8 +3,10 @@ #include <qpe/resource.h> #include <qpe/config.h> +#include <assert.h> + Skin::Skin( const QString &name, const QString &fileNameInfix ) : m_fileNameInfix( fileNameInfix ) { init( name ); @@ -31,23 +33,23 @@ void Skin::preload( const MediaWidget::SkinButtonInfo *skinButtonInfo, uint butt QImage Skin::backgroundImage() const { if ( m_backgroundImage.isNull() ) - m_backgroundImage = QImage( Resource::findPixmap( QString( "%1/background" ).arg( m_skinPath ) ) ); + m_backgroundImage = SkinCache::self().loadImage( QString( "%1/background" ).arg( m_skinPath ) ); return m_backgroundImage; } QImage Skin::buttonUpImage() const { if ( m_buttonUpImage.isNull() ) - m_buttonUpImage = QImage( Resource::findPixmap( QString( "%1/skin%2_up" ).arg( m_skinPath ).arg( m_fileNameInfix ) ) ); + m_buttonUpImage = SkinCache::self().loadImage( QString( "%1/skin%2_up" ).arg( m_skinPath ).arg( m_fileNameInfix ) ); return m_buttonUpImage; } QImage Skin::buttonDownImage() const { if ( m_buttonDownImage.isNull() ) - m_buttonDownImage = QImage( Resource::findPixmap( QString( "%1/skin%2_down" ).arg( m_skinPath ).arg( m_fileNameInfix ) ) ); + m_buttonDownImage = SkinCache::self().loadImage( QString( "%1/skin%2_down" ).arg( m_skinPath ).arg( m_fileNameInfix ) ); return m_buttonDownImage; } QImage Skin::buttonMask( const MediaWidget::SkinButtonInfo *skinButtonInfo, uint buttonCount ) const @@ -85,9 +87,9 @@ QImage Skin::buttonMaskImage( const QString &fileName ) const ButtonMaskImageMap::Iterator it = m_buttonMasks.find( fileName ); if ( it == m_buttonMasks.end() ) { QString prefix = m_skinPath + QString::fromLatin1( "/skin%1_mask_" ).arg( m_fileNameInfix ); QString path = prefix + fileName + ".png"; - it = m_buttonMasks.insert( fileName, QImage( Resource::findPixmap( path ) ) ); + it = m_buttonMasks.insert( fileName, SkinCache::self().loadImage( path ) ); } return *it; } @@ -97,6 +99,54 @@ QString Skin::defaultSkinName() cfg.setGroup( "Options" ); return cfg.readEntry( "Skin", "default" ); } +SkinCache::SkinCache() +{ + m_cache.setAutoDelete( true ); +} + +QImage SkinCache::loadImage( const QString &name ) +{ + ThreadUtil::AutoLock lock( m_cacheGuard ); + + QImage *image = m_cache.find( name ); + if ( image ) { + qDebug( "cache hit for %s", name.ascii() ); + return *image; + } + + image = new QImage( Resource::findPixmap( name ) ); + m_cache.insert( name, image ); + return *image; +} + +SkinLoader::SkinLoader() +{ +} + +void SkinLoader::schedule( const QString &skinName, const QString &fileNameInfix, + const MediaWidget::SkinButtonInfo *skinButtonInfo, const uint buttonCount ) +{ + assert( isRunning() == false ); + + pendingSkins << Info( skinName, fileNameInfix, skinButtonInfo, buttonCount ); +} + +void SkinLoader::run() +{ + qDebug( "SkinLoader::run()" ); + for ( InfoList::ConstIterator it = pendingSkins.begin(); it != pendingSkins.end(); ++it ) + load( *it ); + qDebug( "SkinLoader is done." ); +} + +void SkinLoader::load( const Info &nfo ) +{ + qDebug( "preloading %s with infix %s", nfo.skinName.ascii(), nfo.fileNameInfix.ascii() ); + + Skin skin( nfo.skinName, nfo.fileNameInfix ); + skin.preload( nfo.skinButtonInfo, nfo.buttonCount ); +} + /* vim: et sw=4 ts=4 */ diff --git a/noncore/multimedia/opieplayer2/skin.h b/noncore/multimedia/opieplayer2/skin.h index 58f1849..c15d9dc 100644 --- a/noncore/multimedia/opieplayer2/skin.h +++ b/noncore/multimedia/opieplayer2/skin.h @@ -3,10 +3,13 @@ #include <qstring.h> #include <qimage.h> #include <qmap.h> +#include <qdict.h> #include "mediawidget.h" +#include "threadutil.h" +#include "singleton.h" class Skin { public: @@ -44,7 +47,56 @@ private: Skin( const Skin & ); Skin &operator=( const Skin & ); }; +class SkinCache : public Singleton<SkinCache> +{ +public: + SkinCache(); + + QImage loadImage( const QString &name ); + +private: + typedef QDict<QImage> ImageCache; + + ImageCache m_cache; + + ThreadUtil::Mutex m_cacheGuard; +}; + +class SkinLoader : public ThreadUtil::Thread +{ +public: + SkinLoader(); + + void schedule( const QString &skinName, const QString &fileNameInfix, + const MediaWidget::SkinButtonInfo *skinButtonInfo, const uint buttonCount ); + +protected: + virtual void run(); + +private: + struct Info + { + Info() : skinButtonInfo( 0 ), buttonCount( 0 ) {} + Info( const QString &_skinName, const QString &_fileNameInfix, + const MediaWidget::SkinButtonInfo *_skinButtonInfo, const uint _buttonCount ) + : skinName( _skinName ), fileNameInfix( _fileNameInfix ), + skinButtonInfo( _skinButtonInfo ), buttonCount( _buttonCount ) + {} + + const QString skinName; + const QString fileNameInfix; + const MediaWidget::SkinButtonInfo *skinButtonInfo; + const uint buttonCount; + }; + typedef QValueList<Info> InfoList; + + void load( const Info &nfo ); + + InfoList pendingSkins; + ThreadUtil::Mutex guard; +}; + #endif // SKIN_H /* vim: et sw=4 ts=4 */ |