Commit c0de954b authored by Ralf Engels's avatar Ralf Engels
Browse files

Prevent FavoredRandomTrackNavigator choosing files chosen very recently

Author: Brendon Higgins

BUG: 244442
FIXED-IN: 2.6
REVIEW: 101836
parent 9e50989a
......@@ -26,6 +26,7 @@ Version 2.6-Beta 1
"1.2 GB free" is shown instead of "85% used"; thicker capacity bar.
BUGFIXES:
* Fix favored random track playing picking recent played songs (BR 244442)
* Fix crashes with Bookmarks (BR 283753) thanks to Charles Reiss
* Fix memory leaks in USB Mass Storage collection where track objects were
never freed due to circular references.
......
......@@ -37,9 +37,18 @@ Playlist::FavoredRandomTrackNavigator::planOne()
{
DEBUG_BLOCK
if ( m_plannedItems.isEmpty() )
if ( m_plannedItems.isEmpty() && !allItemsList().isEmpty() )
{
QList<qreal> weights = rowWeights();
int avoidRecentlyPlayedSize = AVOID_RECENTLY_PLAYED_MAX; // Start with being very picky.
// Don't over-constrain ourself:
// - Keep enough headroom to be unpredictable.
// - Make sure that 'chooseRandomItem()' doesn't need to find a needle in a haystack.
avoidRecentlyPlayedSize = qMin( avoidRecentlyPlayedSize, allItemsList().size() / 2 );
QSet<quint64> avoidSet = getRecentHistory( avoidRecentlyPlayedSize );
QList<qreal> weights = rowWeights( avoidSet );
// Choose a weighed random row.
if( !weights.isEmpty() )
......@@ -61,7 +70,7 @@ Playlist::FavoredRandomTrackNavigator::planOne()
}
QList<qreal>
Playlist::FavoredRandomTrackNavigator::rowWeights()
Playlist::FavoredRandomTrackNavigator::rowWeights( QSet<quint64> avoidSet )
{
QList<qreal> weights;
......@@ -70,36 +79,39 @@ Playlist::FavoredRandomTrackNavigator::rowWeights()
for( int row = 0; row < rowCount; row++ )
{
qreal weight;
qreal weight = 0.0;
switch( favorType )
if ( !avoidSet.contains( m_model->idAt( row ) ) )
{
case AmarokConfig::EnumFavorTracks::HigherScores:
switch( favorType )
{
int score = m_model->trackAt( row )->score();
weight = score ? score : 50.0; // "Unknown" weight: in the middle, 50%
break;
}
case AmarokConfig::EnumFavorTracks::HigherScores:
{
int score = m_model->trackAt( row )->score();
weight = score ? score : 50.0; // "Unknown" weight: in the middle, 50%
break;
}
case AmarokConfig::EnumFavorTracks::HigherRatings:
{
int rating = m_model->trackAt( row )->rating();
weight = rating ? rating : 5.0;
break;
}
case AmarokConfig::EnumFavorTracks::HigherRatings:
{
int rating = m_model->trackAt( row )->rating();
weight = rating ? rating : 5.0;
break;
}
case AmarokConfig::EnumFavorTracks::LessRecentlyPlayed:
{
QDateTime lastPlayed = m_model->trackAt( row )->lastPlayed();
if( lastPlayed.isValid() )
case AmarokConfig::EnumFavorTracks::LessRecentlyPlayed:
{
weight = lastPlayed.secsTo( QDateTime::currentDateTime() );
if ( weight < 0 ) // If 'lastPlayed()' is nonsense, or the system clock has been set back:
weight = 1 * 60 * 60; // "Nonsense" weight: 1 hour.
QDateTime lastPlayed = m_model->trackAt( row )->lastPlayed();
if ( lastPlayed.isValid() )
{
weight = lastPlayed.secsTo( QDateTime::currentDateTime() );
if ( weight < 0 ) // If 'lastPlayed()' is nonsense, or the system clock has been set back:
weight = 1 * 60 * 60; // "Nonsense" weight: 1 hour.
}
else
weight = 365 * 24 * 60 * 60; // "Never" weight: 1 year.
break;
}
else
weight = 365 * 24 * 60 * 60; // "Never" weight: 1 year.
break;
}
}
......@@ -108,3 +120,20 @@ Playlist::FavoredRandomTrackNavigator::rowWeights()
return weights;
}
QSet<quint64>
Playlist::FavoredRandomTrackNavigator::getRecentHistory( int size )
{
QList<quint64> allHistory = historyItems();
QSet<quint64> recentHistory;
if ( size > 0 ) { // If '== 0', we even need to consider playing the same item again.
recentHistory.insert( currentItem() ); // Might be '0'
size--;
}
for ( int i = allHistory.size() - 1; ( i >= 0 ) && ( i >= allHistory.size() - size ); i-- )
recentHistory.insert( allHistory.at( i ) );
return recentHistory;
}
......@@ -30,13 +30,16 @@ namespace Playlist
public:
FavoredRandomTrackNavigator();
static const int AVOID_RECENTLY_PLAYED_MAX = 512; //!< Try to avoid the 'N' most recently played items.
private:
//! Override from 'NonlinearTrackNavigator'
void planOne();
void notifyItemsInserted( const QSet<quint64> &insertedItems ) { Q_UNUSED( insertedItems ); }
void notifyItemsRemoved( const QSet<quint64> &removedItems ) { Q_UNUSED( removedItems ); }
QList<qreal> rowWeights();
QList<qreal> rowWeights( QSet<quint64> avoidSet );
QSet<quint64> getRecentHistory( int size );
};
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment