File indexing completed on 2024-05-19 04:49:26
0001 /**************************************************************************************** 0002 * Copyright (c) 2009 Maximilian Kossick <maximilian.kossick@googlemail.com> * 0003 * Copyright (c) 2012 Matěj Lait <matej@laitl.cz> * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify it under * 0006 * the terms of the GNU General Public License as published by the Free Software * 0007 * Foundation; either version 2 of the License, or (at your option) any later * 0008 * version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0011 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0012 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0013 * * 0014 * You should have received a copy of the GNU General Public License along with * 0015 * this program. If not, see <http://www.gnu.org/licenses/>. * 0016 ****************************************************************************************/ 0017 0018 #ifndef PERSISTENTSTATISTICSSTORE_H 0019 #define PERSISTENTSTATISTICSSTORE_H 0020 0021 #include "amarok_export.h" 0022 #include "core/meta/Observer.h" 0023 #include "core/meta/Statistics.h" 0024 0025 #include <QDateTime> 0026 #include <QReadWriteLock> 0027 0028 /** 0029 * Base class for all permanent statistics storage providers. Use one of the subclassed if 0030 * your collection cannot store statistics (rating, play count..) natively, but you still 0031 * want to provide the functionality. 0032 * 0033 * All subclasses automatically call notifyObservers() on your track when the statistics 0034 * change. PersistentStatisticsStore uses some trickery not to hold reference to your 0035 * track to avoid circular reference counting. PersistentStatisticsStore can even deal 0036 * with your track being destroyed and is implemented in thread-safe way. You should 0037 * store is as StatisticsPtr (a AmarokSharedPointer) in your Track class. 0038 */ 0039 class AMAROK_EXPORT PersistentStatisticsStore : public Meta::Statistics, private Meta::Observer 0040 { 0041 public: 0042 /** 0043 * Create persistent statistics store of @param track statistics. @p track may 0044 * not be null. 0045 * 0046 * This methods takes plain pointer so that you can call it in the Track 0047 * constructor without AmarokSharedPointer deleting it right away. 0048 */ 0049 explicit PersistentStatisticsStore( Meta::Track *track ); 0050 ~PersistentStatisticsStore() override; 0051 0052 // Meta::Statistics methods 0053 double score() const override; 0054 void setScore( double newScore ) override; 0055 0056 int rating() const override; 0057 void setRating( int newRating ) override; 0058 0059 QDateTime lastPlayed() const override; 0060 void setLastPlayed( const QDateTime &dt ) override; 0061 0062 QDateTime firstPlayed() const override; 0063 void setFirstPlayed( const QDateTime &dt ) override; 0064 0065 int playCount() const override; 0066 void setPlayCount( int playCount ) override; 0067 0068 void beginUpdate() override; 0069 void endUpdate() override; 0070 0071 // Meta::Observer methods 0072 0073 /** 0074 * Notice that the linked track was destroyed. 0075 */ 0076 void entityDestroyed() override; 0077 0078 protected: 0079 virtual void save() = 0; // called with m_lock locked for writing! 0080 0081 static const QString s_sqlDateFormat; 0082 0083 Meta::Track *m_track; // plain pointer not to hold reference 0084 QDateTime m_lastPlayed; 0085 QDateTime m_firstPlayed; 0086 double m_score; 0087 int m_rating; 0088 int m_playCount; 0089 mutable QReadWriteLock m_lock; // lock protecting access to fields. 0090 0091 private: 0092 void commitIfInNonBatchUpdate(); // must be called with the m_lock locked for writing 0093 0094 /** 0095 * Number of current batch operations started by @see beginUpdate() and not 0096 * yet ended by @see endUpdate(). Must only be accessed with m_track held. 0097 */ 0098 int m_batch; 0099 }; 0100 0101 #endif // PERSISTENTSTATISTICSSTORE_H