File indexing completed on 2024-05-05 04:48:16

0001 /****************************************************************************************
0002  * Copyright (c) 2007 Maximilian Kossick <maximilian.kossick@googlemail.com>            *
0003  * Copyright (c) 2008 Mark Kretschmann <kretschmann@kde.org>                            *
0004  * Copyright (c) 2013 Matěj Laitl <matej@laitl.cz>                                      *
0005  *                                                                                      *
0006  * This program is free software; you can redistribute it and/or modify it under        *
0007  * the terms of the GNU General Public License as published by the Free Software        *
0008  * Foundation; either version 2 of the License, or (at your option) any later           *
0009  * version.                                                                             *
0010  *                                                                                      *
0011  * This program is distributed in the hope that it will be useful, but WITHOUT ANY      *
0012  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A      *
0013  * PARTICULAR PURPOSE. See the GNU General Public License for more details.             *
0014  *                                                                                      *
0015  * You should have received a copy of the GNU General Public License along with         *
0016  * this program.  If not, see <http://www.gnu.org/licenses/>.                           *
0017  ***************************************************************************************/
0018 
0019 #ifndef META_OBSERVER_H
0020 #define META_OBSERVER_H
0021 
0022 #include "core/amarokcore_export.h"
0023 #include "core/meta/forward_declarations.h"
0024 
0025 #include <QMutex>
0026 #include <QSet>
0027 
0028 class PersistentStatisticsStore;
0029 
0030 namespace Meta {
0031     /**
0032      * Subclass this class to be able to listen to changes of track, artist, album, genre,
0033      * composer and year metadata. Must useful just for tracks and albums though.
0034      *
0035      * If you want to override just one metadataChanged() and want to get rid of "method
0036      * hidden compiler warnings", use following pattern in your class declaration:
0037      *
0038      * using Observer::metadataChanged;
0039      * void metadataChanged( AlbumPtr album );
0040      *
0041      * This class is thread-safe.
0042      */
0043     class AMAROKCORE_EXPORT Observer
0044     {
0045         friend class Base; // so that it can call destroyedNotify()
0046 
0047         public:
0048             virtual ~Observer();
0049 
0050             /**
0051              * Subscribe to changes made by @param entity .
0052              *
0053              * Changed in 2.7: being subscribed to an entity no longer prevents its
0054              * destruction.
0055              */
0056             template <typename T>
0057             void subscribeTo( AmarokSharedPointer<T> entity ) { subscribeTo( entity.data() ); }
0058             template <typename T>
0059             void unsubscribeFrom( AmarokSharedPointer<T> entity ) { unsubscribeFrom( entity.data() ); }
0060 
0061             /**
0062              * This method is called when the metadata of a track has changed.
0063              * The called class may not cache the pointer.
0064              */
0065             virtual void metadataChanged( const TrackPtr &track );
0066             virtual void metadataChanged( const ArtistPtr &artist );
0067             virtual void metadataChanged( const AlbumPtr &album );
0068             virtual void metadataChanged( const GenrePtr &genre );
0069             virtual void metadataChanged( const ComposerPtr &composer );
0070             virtual void metadataChanged( const YearPtr &year );
0071 
0072             /**
0073              * One of the subscribed entities was destroyed. You don't get which one
0074              * because it is already invalid.
0075              */
0076             virtual void entityDestroyed();
0077 
0078         private:
0079             friend class ::PersistentStatisticsStore; // so that it can call AmarokSharedPointer-free subscribe:
0080             void subscribeTo( Base *ptr );
0081             void unsubscribeFrom( Base *ptr );
0082 
0083             /**
0084              * Called in Meta::Base destructor so that Observer doesn't have a stale pointer.
0085              */
0086             void destroyedNotify( Base *ptr );
0087 
0088             QSet<Base *> m_subscriptions;
0089             QMutex m_subscriptionsMutex; /// mutex guarding access to m_subscriptions
0090     };
0091 }
0092 
0093 #endif // META_OBSERVER_H