Take two
Index: src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/StationSource.cs
===================================================================
--- src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/StationSource.cs (revision
3358)
+++ src/Extensions/Banshee.Lastfm/Banshee.Lastfm.Radio/StationSource.cs (working
copy)
@@ -317,6 +317,10 @@
return (left < 0) ? 0 : left;
}
}
+
+ public bool HasDependancies {
+ get { return false; }
+ }
private bool refreshing = false;
public void Refresh ()
Index: src/Core/Banshee.Services/Banshee.Sources/ITrackModelSource.cs
===================================================================
--- src/Core/Banshee.Services/Banshee.Sources/ITrackModelSource.cs (revision
3358)
+++ src/Core/Banshee.Services/Banshee.Sources/ITrackModelSource.cs (working
copy)
@@ -42,6 +42,7 @@
ArtistListModel ArtistModel { get; }
void Reload ();
+ bool HasDependancies { get; }
void RemoveSelectedTracks ();
void DeleteSelectedTracks ();
Index: src/Core/Banshee.Services/Banshee.Sources/Source.cs
===================================================================
--- src/Core/Banshee.Services/Banshee.Sources/Source.cs (revision 3358)
+++ src/Core/Banshee.Services/Banshee.Sources/Source.cs (working copy)
@@ -31,6 +31,7 @@
using System.Text;
using System.Collections;
using System.Collections.Generic;
+using System.Collections.ObjectModel;
using Mono.Unix;
@@ -44,9 +45,10 @@
{
public abstract class Source : ISource
{
- private Source parent;
+ private Source parent;
private PropertyStore properties = new PropertyStore ();
private List<Source> child_sources = new List<Source> ();
+ private ReadOnlyCollection<Source> read_only_children;
public event EventHandler Updated;
public event EventHandler UserNotifyUpdated;
@@ -67,6 +69,7 @@
}
properties.PropertyChanged += OnPropertyChanged;
+ read_only_children = new ReadOnlyCollection<Source>
(child_sources);
}
protected void OnSetupComplete ()
@@ -132,7 +135,7 @@
public virtual void AddChildSource (Source child)
{
- lock (Children) {
+ lock (child_sources) {
child.SetParentSource (this);
child_sources.Add (child);
OnChildSourceAdded (child);
@@ -141,8 +144,8 @@
public virtual void RemoveChildSource (Source child)
{
- lock (Children) {
- if (child.Children.Count > 0) {
+ lock (child_sources) {
+ if (child.child_sources.Count > 0) {
child.ClearChildSources ();
}
@@ -158,7 +161,7 @@
public virtual void ClearChildSources ()
{
- lock (Children) {
+ lock (child_sources) {
while (child_sources.Count > 0) {
RemoveChildSource (child_sources[child_sources.Count - 1]);
}
@@ -183,7 +186,7 @@
public virtual void SortChildSources (IComparer<Source>
comparer, bool asc)
{
- lock (Children) {
+ lock (child_sources) {
child_sources.Sort (comparer);
if (!asc) {
child_sources.Reverse ();
@@ -249,8 +252,8 @@
#region Public Properties
- public ICollection<Source> Children {
- get { return child_sources; }
+ public ReadOnlyCollection<Source> Children {
+ get { return read_only_children; }
}
string [] ISource.Children {
Index: src/Core/Banshee.Services/Banshee.Sources/DatabaseSource.cs
===================================================================
--- src/Core/Banshee.Services/Banshee.Sources/DatabaseSource.cs (revision 3358)
+++ src/Core/Banshee.Services/Banshee.Sources/DatabaseSource.cs (working copy)
@@ -165,11 +165,16 @@
protected virtual void ReloadChildren ()
{
foreach (Source child in Children) {
- if (child is ITrackModelSource) {
- (child as ITrackModelSource).Reload ();
+ ITrackModelSource c = child as ITrackModelSource;
+ if (c != null && !c.HasDependancies) {
+ c.Reload ();
}
}
}
+
+ public virtual bool HasDependancies {
+ get { return false; }
+ }
public virtual void RemoveTrack (int index)
{
Index: src/Core/Banshee.Services/Banshee.SmartPlaylist/SmartPlaylistCore.cs
===================================================================
--- src/Core/Banshee.Services/Banshee.SmartPlaylist/SmartPlaylistCore.cs (revision
3358)
+++ src/Core/Banshee.Services/Banshee.SmartPlaylist/SmartPlaylistCore.cs (working
copy)
@@ -1,6 +1,5 @@
using System;
using System.Data;
-using System.Collections;
using System.Collections.Generic;
using Mono.Unix;
@@ -29,7 +28,7 @@
private readonly double RATE_LIMIT_CPU_MAX = 0.10;
private static int RATE_LIMIT_REFRESH = 5;
- private ArrayList playlists = new ArrayList();
+ private List<SmartPlaylistSource> playlists = new
List<SmartPlaylistSource> ();
private DateTime last_check = DateTime.MinValue;
private uint event_counter = 0;
@@ -76,12 +75,6 @@
//Console.WriteLine ("source added: {0}", args.Source.Name);
if (args.Source is PlaylistSource || args.Source is
SmartPlaylistSource) {
- foreach (SmartPlaylistSource pl in playlists) {
- if (pl.PlaylistDependent) {
- pl.ListenToPlaylists();
- }
- }
-
if (args.Source is PlaylistSource)
return;
}
@@ -278,6 +271,17 @@
public void SortPlaylists () {
playlists.Sort(new DependencyComparer());
}
+
+ public SmartPlaylistSource GetSmartPlaylistFromDbId (int dbId)
+ {
+ // TODO use a dictionary
+ foreach (SmartPlaylistSource sp in playlists) {
+ if (sp.DbId == dbId) {
+ return sp;
+ }
+ }
+ return null;
+ }
}
// Class used for timing different operations. Commented out for
normal operation.
@@ -330,15 +334,12 @@
}
}
- public class DependencyComparer : IComparer {
- public int Compare(object ao, object bo)
+ public class DependencyComparer : IComparer<SmartPlaylistSource> {
+ public int Compare(SmartPlaylistSource a, SmartPlaylistSource b)
{
- SmartPlaylistSource a = ao as SmartPlaylistSource;
- SmartPlaylistSource b = bo as SmartPlaylistSource;
-
- if (b.DependsOn(a)) {
+ if (b.DependsOn (a)) {
return -1;
- } else if (a.DependsOn(b)) {
+ } else if (a.DependsOn (b)) {
return 1;
} else {
return 0;
Index: src/Core/Banshee.Services/Banshee.SmartPlaylist/SmartPlaylistSource.cs
===================================================================
--- src/Core/Banshee.Services/Banshee.SmartPlaylist/SmartPlaylistSource.cs (revision
3358)
+++ src/Core/Banshee.Services/Banshee.SmartPlaylist/SmartPlaylistSource.cs (working
copy)
@@ -57,6 +57,8 @@
private QueryOrder query_order;
private QueryLimit limit;
private IntegerQueryValue limit_value;
+
+ private List<SmartPlaylistSource> dependencies = new
List<SmartPlaylistSource>();
#region Properties
@@ -139,10 +141,9 @@
return (Limit != null && LimitValue != null &&
!LimitValue.IsEmpty && QueryOrder != null);
}
}
-
- // FIXME scan ConditionTree for playlist fields
- public bool PlaylistDependent {
- get { return false; }
+
+ public override bool HasDependancies {
+ get { return dependencies.Count > 0; }
}
// FIXME scan ConditionTree for date fields
@@ -167,6 +168,7 @@
LimitValue = limit_value;
InstallProperties ();
+ ScanForDependencies ();
}
// For existing smart playlists that we're loading from the database
@@ -184,6 +186,7 @@
DbId = dbid;
InstallProperties ();
+ ScanForDependencies ();
//Globals.Library.TrackRemoved += OnLibraryTrackRemoved;
@@ -215,29 +218,70 @@
return DependsOn (source, ConditionTree);
}
+#endregion
+
+#region Private Methods
+
private bool DependsOn (SmartPlaylistSource source, QueryNode node)
{
if (node == null) {
return false;
}
+ foreach (int i in GetDependencies()) {
+ if (i == source.DbId) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private IEnumerable<int> GetDependencies ()
+ {
+ foreach(int i in GetDependencies (ConditionTree)) {
+ yield return i;
+ }
+ }
+
+ private IEnumerable<int> GetDependencies (QueryNode node)
+ {
if (node is QueryListNode) {
foreach (QueryNode child in (node as QueryListNode).Children) {
- if (DependsOn (source, child)) {
- return true;
+ foreach (int i in GetDependencies (child)) {
+ yield return i;
}
}
} else {
QueryTermNode term = node as QueryTermNode;
- if (term.Field == BansheeQuery.SmartPlaylistField) {
- if ((term.Value as IntegerQueryValue).IntValue ==
source.DbId)
- return true;
+ if (term != null && term.Field ==
BansheeQuery.SmartPlaylistField) {
+ yield return (int)(term.Value as
IntegerQueryValue).IntValue;
}
}
-
- return false;
}
-
+
+ private void ScanForDependencies ()
+ {
+ foreach (SmartPlaylistSource s in dependencies) {
+ s.Updated -= OnDependencyUpdated;
+ }
+
+ dependencies.Clear ();
+
+ // TODO make this a field
+ SmartPlaylistCore core =
Banshee.ServiceStack.ServiceManager.Get<SmartPlaylistCore>("SmartPlaylistCore");
+ foreach (int i in GetDependencies()) {
+ SmartPlaylistSource s = core.GetSmartPlaylistFromDbId (i);
+ s.Updated += OnDependencyUpdated;
+ dependencies.Add (s);
+ }
+ }
+
+ private void OnDependencyUpdated (object sender, EventArgs args)
+ {
+ RateLimitedReload ();
+ }
+
#endregion
#region AbstractPlaylist overrides
@@ -253,6 +297,7 @@
IsLimited ? LimitValue.ToSql () : null,
IsLimited ? Limit.Name : null
));
+ ScanForDependencies ();
}
protected override void Update ()
@@ -271,6 +316,7 @@
IsLimited ? Limit.Name : null,
DbId
));
+ ScanForDependencies ();
}
#endregion
@@ -279,6 +325,7 @@
public override void RateLimitedReload ()
{
+ Console.WriteLine(Name);
// Wipe the member list clean
ServiceManager.DbConnection.Execute (String.Format (
"DELETE FROM CoreSmartPlaylistEntries WHERE
SmartPlaylistID = {0}", DbId
Attachment:
patch
Description: Binary data