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