banshee r3749 - in trunk/banshee: . src/Core/Banshee.Services/Banshee.Collection src/Core/Banshee.Services/Banshee.Collection.Database src/Core/Banshee.Services/Banshee.MediaEngine src/Core/Banshee.Services/Banshee.PlaybackController src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue src/Libraries/Hyena/Hyena.Data.Sqlite
- From: gburt svn gnome org
- To: svn-commits-list gnome org
- Subject: banshee r3749 - in trunk/banshee: . src/Core/Banshee.Services/Banshee.Collection src/Core/Banshee.Services/Banshee.Collection.Database src/Core/Banshee.Services/Banshee.MediaEngine src/Core/Banshee.Services/Banshee.PlaybackController src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue src/Libraries/Hyena/Hyena.Data.Sqlite
- Date: Thu, 10 Apr 2008 09:50:53 +0100 (BST)
Author: gburt
Date: Thu Apr 10 09:50:53 2008
New Revision: 3749
URL: http://svn.gnome.org/viewvc/banshee?rev=3749&view=rev
Log:
2008-04-10 Gabriel Burt <gabriel burt gmail com>
* src/Core/Banshee.Services/Banshee.Collection/TrackListModel.cs:
* src/Core/Banshee.Services/Banshee.Collection/MemoryTrackListModel.cs:
* src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseTrackListModel.cs:
Implement GetRandom method, using SQL for DatabaseTrackListModel.
* src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngineService.cs:
Move IncrementPlay/SkipCount logic into public IncrementLastPlayed method.
* src/Core/Banshee.Services/Banshee.PlaybackController/PlaybackControllerService.cs:
Cann IncrementLastPlayed before getting the next song since that affects
the random query method. Fix repeat/restart in linear query. Change
QueryTrackRandom to call GetRandom on TrackModel.
* src/Core/Banshee.Services/Banshee.PlaybackController/IBasicPlaybackController.cs:
* src/Core/Banshee.Services/Banshee.PlaybackController/ICanonicalPlaybackController.cs:
* src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/PlayQueueSource.cs:
Add restart arg to Previous.
* src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelCache.cs: Add GetSingle
method that can be passed a condition/order by fragment and returns one
item.
Modified:
trunk/banshee/ChangeLog
trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseTrackListModel.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/MemoryTrackListModel.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/TrackListModel.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngineService.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.PlaybackController/IBasicPlaybackController.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.PlaybackController/ICanonicalPlaybackController.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.PlaybackController/PlaybackControllerService.cs
trunk/banshee/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/PlayQueueSource.cs
trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelCache.cs
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseTrackListModel.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseTrackListModel.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseTrackListModel.cs Thu Apr 10 09:50:53 2008
@@ -310,6 +310,28 @@
return (int) (db_track == null ? -1 : cache.IndexOf ((int)db_track.TrackId));
}
+ private DateTime random_began_at = DateTime.MinValue;
+ private DateTime last_random = DateTime.MinValue;
+ private static string random_fragment = "AND (LastPlayedStamp < ? OR LastPlayedStamp IS NULL) AND (LastSkippedStamp < ? OR LastSkippedStamp IS NULL) ORDER BY RANDOM()";
+ public override TrackInfo GetRandom (DateTime notPlayedSince, bool repeat)
+ {
+ if (Count == 0)
+ return null;
+
+ if (random_began_at < notPlayedSince)
+ random_began_at = last_random = notPlayedSince;
+
+ TrackInfo track = cache.GetSingle (random_fragment, random_began_at, random_began_at);
+
+ if (track == null && repeat) {
+ random_began_at = last_random;
+ track = cache.GetSingle (random_fragment, random_began_at, random_began_at);
+ }
+
+ last_random = DateTime.Now;
+ return track;
+ }
+
public override TrackInfo this[int index] {
get { return cache.GetValue (index); }
}
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/MemoryTrackListModel.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/MemoryTrackListModel.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/MemoryTrackListModel.cs Thu Apr 10 09:50:53 2008
@@ -35,6 +35,7 @@
{
public class MemoryTrackListModel : TrackListModel, IEnumerable<TrackInfo>
{
+ private static Random random = new Random ();
private List<TrackInfo> tracks = new List<TrackInfo> ();
public MemoryTrackListModel () : base ()
@@ -80,6 +81,14 @@
get { lock (this) { return (index >= 0 && index < tracks.Count) ? tracks[index] : null; } }
}
+ public override TrackInfo GetRandom (DateTime since, bool repeat)
+ {
+ if (Count == 0)
+ return null;
+
+ return this [random.Next (0, Count - 1)];
+ }
+
public override int Count {
get { lock (this) { return tracks.Count; } }
}
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/TrackListModel.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/TrackListModel.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/TrackListModel.cs Thu Apr 10 09:50:53 2008
@@ -53,6 +53,8 @@
{
throw new NotImplementedException();
}
+
+ public abstract TrackInfo GetRandom (DateTime notPlayedSince, bool repeat);
public virtual IEnumerable<ArtistInfo> ArtistInfoFilter {
set { throw new NotImplementedException(); }
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngineService.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngineService.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.MediaEngine/PlayerEngineService.cs Thu Apr 10 09:50:53 2008
@@ -314,23 +314,32 @@
} else {
return;
}
+
+ IncrementLastPlayed ();
FindSupportingEngine (uri);
CheckPending ();
- if (active_engine.CurrentTrack != null) {
+ if (track != null) {
+ active_engine.Open (track);
+ incremented_last_played = false;
+ } else if (uri != null) {
+ active_engine.Open (uri);
+ incremented_last_played = false;
+ }
+ }
+
+ private bool incremented_last_played = true;
+ public void IncrementLastPlayed ()
+ {
+ if (!incremented_last_played && active_engine.CurrentTrack != null) {
// If we're at least 50% done playing a song, mark it as played, otherwise as skipped
if (active_engine.Length > 0 && active_engine.Position >= active_engine.Length / 2) {
active_engine.CurrentTrack.IncrementPlayCount ();
} else {
active_engine.CurrentTrack.IncrementSkipCount ();
}
- }
-
- if (track != null) {
- active_engine.Open (track);
- } else if (uri != null) {
- active_engine.Open (uri);
+ incremented_last_played = true;
}
}
@@ -371,6 +380,7 @@
public void Close (bool fullShutdown)
{
+ IncrementLastPlayed ();
active_engine.Reset ();
active_engine.Close (fullShutdown);
}
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.PlaybackController/IBasicPlaybackController.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.PlaybackController/IBasicPlaybackController.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.PlaybackController/IBasicPlaybackController.cs Thu Apr 10 09:50:53 2008
@@ -32,6 +32,6 @@
{
void First ();
void Next (bool restart);
- void Previous ();
+ void Previous (bool restart);
}
}
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.PlaybackController/ICanonicalPlaybackController.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.PlaybackController/ICanonicalPlaybackController.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.PlaybackController/ICanonicalPlaybackController.cs Thu Apr 10 09:50:53 2008
@@ -32,6 +32,6 @@
{
new void First ();
new void Next (bool restart);
- new void Previous ();
+ new void Previous (bool restart);
}
}
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.PlaybackController/PlaybackControllerService.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.PlaybackController/PlaybackControllerService.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.PlaybackController/PlaybackControllerService.cs Thu Apr 10 09:50:53 2008
@@ -55,7 +55,7 @@
private bool raise_started_after_transition = false;
private bool transition_track_started = false;
- private Random random = new Random ();
+ //private Random random = new Random ();
private PlaybackShuffleMode shuffle_mode;
private PlaybackRepeatMode repeat_mode;
@@ -151,6 +151,8 @@
public void Next (bool restart)
{
raise_started_after_transition = true;
+
+ player_engine.IncrementLastPlayed ();
if (Source is IBasicPlaybackController) {
((IBasicPlaybackController)Source).Next (restart);
@@ -160,15 +162,22 @@
OnTransition ();
}
-
+
public void Previous ()
{
+ Previous (RepeatMode == PlaybackRepeatMode.RepeatAll);
+ }
+
+ public void Previous (bool restart)
+ {
raise_started_after_transition = true;
+
+ player_engine.IncrementLastPlayed ();
if (Source is IBasicPlaybackController) {
- ((IBasicPlaybackController)Source).Previous ();
+ ((IBasicPlaybackController)Source).Previous (restart);
} else {
- ((ICanonicalPlaybackController)this).Previous ();
+ ((ICanonicalPlaybackController)this).Previous (restart);
}
OnTransition ();
@@ -191,19 +200,11 @@
previous_stack.Push (tmp_track);
}
} else {
- TrackInfo next_track = QueryTrack (Direction.Next);
+ TrackInfo next_track = QueryTrack (Direction.Next, restart);
if (next_track != null) {
if (tmp_track != null) {
previous_stack.Push (tmp_track);
}
- } else if (restart && Source.Count > 0) {
- if (tmp_track != null) {
- previous_stack.Push (tmp_track);
- }
-
- CurrentTrack = Source.TrackModel[0];
- QueuePlayTrack ();
- return;
} else {
return;
}
@@ -214,7 +215,7 @@
QueuePlayTrack ();
}
- void ICanonicalPlaybackController.Previous ()
+ void ICanonicalPlaybackController.Previous (bool restart)
{
if (CurrentTrack != null && previous_stack.Count > 0) {
next_stack.Push (current_track);
@@ -223,30 +224,51 @@
if (previous_stack.Count > 0) {
CurrentTrack = previous_stack.Pop ();
} else {
- CurrentTrack = QueryTrack (Direction.Previous);
+ TrackInfo track = CurrentTrack = QueryTrack (Direction.Previous, restart);
+ if (track != null) {
+ CurrentTrack = track;
+ } else {
+ return;
+ }
}
QueuePlayTrack ();
}
- private TrackInfo QueryTrack (Direction direction)
+ private TrackInfo QueryTrack (Direction direction, bool restart)
{
Log.DebugFormat ("Querying model for track to play in {0}:{1} mode", ShuffleMode, direction);
return ShuffleMode == PlaybackShuffleMode.Linear
- ? QueryTrackLinear (direction)
- : QueryTrackRandom ();
+ ? QueryTrackLinear (direction, restart)
+ : QueryTrackRandom (restart);
}
- private TrackInfo QueryTrackLinear (Direction direction)
+ private TrackInfo QueryTrackLinear (Direction direction, bool restart)
{
+ if (Source.TrackModel.Count == 0)
+ return null;
+
int index = Source.TrackModel.IndexOf (CurrentTrack);
- return Source.TrackModel[index < 0 ? 0 : index + (direction == Direction.Next ? 1 : -1)];
+ if (index == -1) {
+ return Source.TrackModel[0];
+ } else {
+ index += (direction == Direction.Next ? 1 : -1);
+ if (index >= 0 && index < Source.TrackModel.Count) {
+ return Source.TrackModel[index];
+ } else if (!restart) {
+ return null;
+ } else if (index < 0) {
+ return Source.TrackModel[Source.TrackModel.Count - 1];
+ } else {
+ return Source.TrackModel[0];
+ }
+ }
}
- private TrackInfo QueryTrackRandom ()
+ private TrackInfo QueryTrackRandom (bool restart)
{
- // TODO let the TrackModel give us a random track
- return Source.TrackModel[random.Next (0, Source.TrackModel.Count - 1)];
+ return Source.TrackModel.GetRandom (source_set_at, restart);
+ //return Source.TrackModel[random.Next (0, Source.TrackModel.Count - 1)];
}
private void QueuePlayTrack ()
@@ -304,6 +326,7 @@
protected set { current_track = value; }
}
+ protected DateTime source_set_at;
public ITrackModelSource Source {
get {
if (source == null && ServiceManager.SourceManager.DefaultSource is ITrackModelSource) {
@@ -315,6 +338,7 @@
set {
if (source != value) {
source = value;
+ source_set_at = DateTime.Now;
OnSourceChanged ();
}
}
Modified: trunk/banshee/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/PlayQueueSource.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/PlayQueueSource.cs (original)
+++ trunk/banshee/src/Extensions/Banshee.PlayQueue/Banshee.PlayQueue/PlayQueueSource.cs Thu Apr 10 09:50:53 2008
@@ -226,7 +226,7 @@
ServiceManager.PlayerEngine.OpenPlay ((DatabaseTrackInfo)TrackModel[0]);
}
- void IBasicPlaybackController.Previous ()
+ void IBasicPlaybackController.Previous (bool restart)
{
}
Modified: trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelCache.cs
==============================================================================
--- trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelCache.cs (original)
+++ trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelCache.cs Thu Apr 10 09:50:53 2008
@@ -45,6 +45,7 @@
private HyenaSqliteCommand save_selection_command;
private HyenaSqliteCommand get_selection_command;
+ private string select_str;
private string reload_sql;
private long uid;
private long selection_uid;
@@ -100,23 +101,19 @@
}
if (model.CachesJoinTableEntries) {
- select_range_command = new HyenaSqliteCommand (
- String.Format (@"
- SELECT {0}, {5}.ItemID FROM {1}
- INNER JOIN {2}
- ON {3} = {2}.{4}
- INNER JOIN {5}
- ON {2}.{6} = {5}.ItemID
- WHERE
- {5}.ModelID = {7} {8}
- {9}
- LIMIT ?, ?",
- provider.Select, provider.From,
- model.JoinTable, provider.PrimaryKey, model.JoinColumn,
- CacheTableName, model.JoinPrimaryKey, uid,
- String.IsNullOrEmpty (provider.Where) ? null : "AND",
- provider.Where
- )
+ select_str = String.Format (
+ @"SELECT {0}, {5}.ItemID FROM {1}
+ INNER JOIN {2}
+ ON {3} = {2}.{4}
+ INNER JOIN {5}
+ ON {2}.{6} = {5}.ItemID
+ WHERE
+ {5}.ModelID = {7} {8} {9}",
+ provider.Select, provider.From,
+ model.JoinTable, provider.PrimaryKey, model.JoinColumn,
+ CacheTableName, model.JoinPrimaryKey, uid,
+ String.IsNullOrEmpty (provider.Where) ? null : "AND",
+ provider.Where
);
select_single_command = new HyenaSqliteCommand (
@@ -135,22 +132,18 @@
CacheTableName, uid, model.JoinPrimaryKey
);
} else {
- select_range_command = new HyenaSqliteCommand (
- String.Format (@"
- SELECT {0}, {2}.ItemID FROM {1}
- INNER JOIN {2}
- ON {3} = {2}.ItemID
- WHERE
- {2}.ModelID = {4} {5}
- {6}
- LIMIT ?, ?",
- provider.Select, provider.From, CacheTableName,
- provider.PrimaryKey, uid,
- String.IsNullOrEmpty (provider.Where) ? String.Empty : "AND",
- provider.Where
- )
+ select_str = String.Format (
+ @"SELECT {0}, {2}.ItemID FROM {1}
+ INNER JOIN {2}
+ ON {3} = {2}.ItemID
+ WHERE
+ {2}.ModelID = {4} {5} {6}",
+ provider.Select, provider.From, CacheTableName,
+ provider.PrimaryKey, uid,
+ String.IsNullOrEmpty (provider.Where) ? String.Empty : "AND",
+ provider.Where
);
-
+
select_single_command = new HyenaSqliteCommand (
String.Format (@"
SELECT OrderID FROM {0}
@@ -167,7 +160,11 @@
CacheTableName, uid, provider.PrimaryKey
);
}
-
+
+ select_range_command = new HyenaSqliteCommand (
+ String.Format ("{0} {1}", select_str, "LIMIT ?, ?")
+ );
+
select_first_command = new HyenaSqliteCommand (
String.Format (
"SELECT OrderID FROM {0} WHERE ModelID = {1} LIMIT 1",
@@ -244,6 +241,29 @@
}
}
+ private HyenaSqliteCommand get_single_command;
+ private string last_get_single_fragment;
+ public T GetSingle (string fragment, params object [] args)
+ {
+ if (fragment != last_get_single_fragment || get_single_command == null) {
+ last_get_single_fragment = fragment;
+ get_single_command = new HyenaSqliteCommand (
+ String.Format ("{0} {1} {2}", select_str, fragment, "LIMIT 1")
+ );
+ }
+
+ using (IDataReader reader = connection.Query (get_single_command, args)) {
+ if (reader.Read ()) {
+ T item = provider.Load (reader, 0);
+ item.CacheEntryId = Convert.ToInt64 (reader[reader.FieldCount - 1]);
+ item.CacheModelId = uid;
+ return item;
+ }
+ }
+ return default(T);
+ }
+
+
private HyenaSqliteCommand last_reload_command;
private string last_reload_fragment;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]