1 /**************************************************************************************** 2 * Copyright (c) 2012 Matěj Laitl <matej@laitl.cz> * 3 * * 4 * This program is free software; you can redistribute it and/or modify it under * 5 * the terms of the GNU General Public License as published by the Free Software * 6 * Foundation; either version 2 of the License, or (at your option) any later * 7 * version. * 8 * * 9 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 10 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 11 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 12 * * 13 * You should have received a copy of the GNU General Public License along with * 14 * this program. If not, see <http://www.gnu.org/licenses/>. * 15 ****************************************************************************************/ 16 17 #ifndef STATSYNCING_TRACKTUPLE_H 18 #define STATSYNCING_TRACKTUPLE_H 19 20 #include "statsyncing/Provider.h" 21 #include "statsyncing/Track.h" 22 23 #include <QMap> 24 25 namespace StatSyncing 26 { 27 class Options; 28 29 /** 30 * Smallest element of synchronization, a container for provider-to-one-track map with 31 * methods to perform statistics synchronization and querying methods. 32 */ 33 class TrackTuple 34 { 35 public: 36 /** 37 * Constructs an empty tuple. 38 */ 39 TrackTuple(); 40 41 /** 42 * Inserts a track into this tuple; if it already contains a track from 43 * provider, the old track si replaced with the new one. 44 * 45 * It does make sense to only add tracks that are in some sence equal to tracks 46 * already present in the tuple. 47 * 48 * @param provider the provider 49 * @param track the track 50 */ 51 void insert( ProviderPtr provider, const TrackPtr &track ); 52 53 /** 54 * Returns a list of providers that have tracks in this tuple. 55 */ 56 ProviderPtrList providers() const; 57 58 /** 59 * Returns provider of the i-th track in this tuple. If i is out of bounds, 60 * returns null. 61 */ 62 ProviderPtr provider( int i ) const; 63 64 /** 65 * Returns track associated with @p provider. Asserts that there's 66 * a track from @param provider 67 */ 68 TrackPtr track( const ProviderPtr &provider ) const; 69 70 /** 71 * Returns a number of tracks in this tuple. 72 */ 73 int count() const; 74 75 /** 76 * Returns true if there are no tracks in the tuple, false otherwise. 77 */ 78 bool isEmpty() const; 79 80 /** 81 * Return true if Meta::val* field @p field is going to be updated. 82 * If @p provider is null, returns true if at least one child track 83 * is going to be updated; otherwise works on a track from @p provider. 84 * 85 * @param field the field. 86 * @param options the options. 87 * @param provider the provider. 88 */ 89 bool fieldUpdated( qint64 field, const Options &options, ProviderPtr provider = ProviderPtr() ) const; 90 91 /** 92 * Return true if there's at least one field going to be updated. 93 */ 94 bool hasUpdate( const Options &options ) const; 95 96 /** 97 * Returns true if there's a (perhaps resolved) conflict in field &field 98 */ 99 bool fieldHasConflict( qint64 field, const Options &options, bool includeResolved = true ) const; 100 101 /** 102 * Return true if there's a (perhaps resolved) conflict in this tuple. 103 */ 104 bool hasConflict( const Options &options ) const; 105 106 /** 107 * Returns a provider whose track's rating will be used in case of conflict. 108 * Will be null if rating provider hasn't been explicitly set. 109 */ 110 ProviderPtr ratingProvider() const; 111 112 /** 113 * Sets the rating provider. Only accepts null provider or a provider of one 114 * track in this tuple. 115 */ 116 void setRatingProvider( const ProviderPtr &provider ); 117 118 /** 119 * Returns providers whose labels will be OR-ed together in case of conflict. 120 * Will be empty if no provider hasn't been explicitly set. 121 */ 122 ProviderPtrSet labelProviders() const; 123 124 /** 125 * Sets label providers. Only accepts empty set a or a set of providers that 126 * are contained in this tuple. 127 */ 128 void setLabelProviders( const ProviderPtrSet &providers ); 129 130 /** 131 * Return synchronized rating. Specifically, returns -1 if there's unsolved 132 * rating conflict. 133 */ 134 int syncedRating( const Options &options ) const; 135 QDateTime syncedFirstPlayed( const Options &options ) const; 136 QDateTime syncedLastPlayed( const Options &options ) const; 137 int syncedPlaycount( const Options &options ) const; 138 QSet<QString> syncedLabels( const Options &options ) const; 139 140 /** 141 * Perform actual synchronization. For each track, only sets fields that are 142 * in fieldUpdated( .., .., provider). Specifically this method does not write 143 * ratings or labels if there's unresolved rating/label conflict. Can only be 144 * called from non-main thread and may block for longer time. 145 * 146 * @return a set of providers that had their track updated 147 */ 148 ProviderPtrSet synchronize( const Options &options ) const; 149 150 private: 151 int syncedRating( const Options &options, ProviderPtr ratingProvider ) const; 152 // @param hasConflict is set to true or false 153 QSet<QString> syncedLabels( const Options &options, const ProviderPtrSet &labelProviders, 154 bool &hasConflict ) const; 155 156 static const QList<qint64> s_fields; /// list of Meta::val* fields capable of syncing 157 QMap<ProviderPtr, TrackPtr> m_map; 158 ProviderPtr m_ratingProvider; /// source of rating in the event of conflict 159 ProviderPtrSet m_labelProviders; /// sources of labels in the event of conflict 160 }; 161 162 } // namespace StatSyncing 163 164 #endif // STATSYNCING_TRACKTUPLE_H 165