banshee r3942 - in trunk/banshee: . src/Extensions/Banshee.Podcasting src/Libraries/Migo src/Libraries/Migo/Migo/Migo.DownloadCore src/Libraries/Migo/Migo/Migo.Syndication src/Libraries/Migo/Migo/Migo.TaskCore src/Libraries/Migo/Migo/Migo.TaskCore/AsyncCommandQueue src/Libraries/Migo/Migo/Migo.TaskCore/Migo.TaskCore.Collections



Author: murbanski
Date: Wed May 21 20:38:19 2008
New Revision: 3942
URL: http://svn.gnome.org/viewvc/banshee?rev=3942&view=rev

Log:
2008-05-21  Mike Urbanski  <michael c urbanski gmail com>

	* src/Libraries/Migo/Makefile.am:
	* src/Libraries/Migo/Migo.mdp:
	* src/Libraries/Migo/Migo/Migo.TaskCore/AsyncCommandQueue/CommandQueueManager.cs:
	Added CommandQueueManager.

	* src/Libraries/Migo/Migo/Migo.TaskCore/GroupStatusManager.cs:
	* src/Libraries/Migo/Migo/Migo.TaskCore/GroupProgressManager.cs:
	* src/Libraries/Migo/Migo/Migo.TaskCore/AsyncCommandQueue/AsyncCommandQueue.cs:
	* src/Libraries/Migo/Migo/Migo.TaskCore/Migo.TaskCore.Collections/TaskCollection.cs:
	* src/Libraries/Migo/Migo/Migo.TaskCore/TaskGroup.cs:
	* src/Libraries/Migo/Migo/Migo.TaskCore/Task.cs:
	* src/Libraries/Migo/Migo/Migo.DownloadCore/DownloadManager.cs:
	* src/Libraries/Migo/Migo/Migo.DownloadCore/DownloadGroupStatusManager.cs:
	* src/Libraries/Migo/Migo/Migo.DownloadCore/HttpFileDownloadTask.cs:
	* src/Libraries/Migo/Migo/Migo.Syndication/FeedsManager.cs:
	Transparent architectural changes to promote looser coupling between
	TaskCore components (i.e.  removing hacketry.)


Added:
   trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/AsyncCommandQueue/CommandQueueManager.cs
Modified:
   trunk/banshee/ChangeLog
   trunk/banshee/src/Extensions/Banshee.Podcasting/Banshee.Podcasting.mdp
   trunk/banshee/src/Libraries/Migo/Makefile.am
   trunk/banshee/src/Libraries/Migo/Migo.mdp
   trunk/banshee/src/Libraries/Migo/Migo/Migo.DownloadCore/DownloadGroupStatusManager.cs
   trunk/banshee/src/Libraries/Migo/Migo/Migo.DownloadCore/DownloadManager.cs
   trunk/banshee/src/Libraries/Migo/Migo/Migo.DownloadCore/HttpFileDownloadTask.cs
   trunk/banshee/src/Libraries/Migo/Migo/Migo.Syndication/FeedsManager.cs
   trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/AsyncCommandQueue/AsyncCommandQueue.cs
   trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/GroupProgressManager.cs
   trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/GroupStatusManager.cs
   trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/Migo.TaskCore.Collections/TaskCollection.cs
   trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/Task.cs
   trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/TaskGroup.cs

Modified: trunk/banshee/src/Extensions/Banshee.Podcasting/Banshee.Podcasting.mdp
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.Podcasting/Banshee.Podcasting.mdp	(original)
+++ trunk/banshee/src/Extensions/Banshee.Podcasting/Banshee.Podcasting.mdp	Wed May 21 20:38:19 2008
@@ -1,4 +1,4 @@
-<Project name="Banshee.Podcasting" fileversion="2.0" UseParentDirectoryAsNamespace="True" language="C#" clr-version="Net_2_0" ctype="DotNetProject">
+<Project name="Banshee.Podcasting" fileversion="2.0" language="C#" clr-version="Net_2_0" UseParentDirectoryAsNamespace="True" ctype="DotNetProject">
   <Configurations active="Debug">
     <Configuration name="Debug" ctype="DotNetProjectConfiguration">
       <Output directory="../../../bin" assemblyKeyFile="." assembly="Banshee.Podcasting" />

Modified: trunk/banshee/src/Libraries/Migo/Makefile.am
==============================================================================
--- trunk/banshee/src/Libraries/Migo/Makefile.am	(original)
+++ trunk/banshee/src/Libraries/Migo/Makefile.am	Wed May 21 20:38:19 2008
@@ -42,6 +42,7 @@
 	Migo/Migo.Syndication/RssParser.cs \
 	Migo/Migo.TaskCore/AsyncCommandQueue/AsyncCommandQueue.cs \
 	Migo/Migo.TaskCore/AsyncCommandQueue/CommandDelegate.cs \
+	Migo/Migo.TaskCore/AsyncCommandQueue/CommandQueueManager.cs \	
 	Migo/Migo.TaskCore/AsyncCommandQueue/CommandWrapper.cs \
 	Migo/Migo.TaskCore/AsyncCommandQueue/EventWrapper.cs \
 	Migo/Migo.TaskCore/AsyncCommandQueue/ICommand.cs \

Modified: trunk/banshee/src/Libraries/Migo/Migo.mdp
==============================================================================
--- trunk/banshee/src/Libraries/Migo/Migo.mdp	(original)
+++ trunk/banshee/src/Libraries/Migo/Migo.mdp	Wed May 21 20:38:19 2008
@@ -1,4 +1,4 @@
-<Project name="Migo" fileversion="2.0" UseParentDirectoryAsNamespace="True" language="C#" clr-version="Net_2_0" ctype="DotNetProject">
+<Project name="Migo" fileversion="2.0" language="C#" clr-version="Net_2_0" UseParentDirectoryAsNamespace="True" ctype="DotNetProject">
   <Configurations active="Debug">
     <Configuration name="Debug" ctype="DotNetProjectConfiguration">
       <Output directory="../../../bin" assembly="Migo" />
@@ -75,6 +75,7 @@
     <File name="Migo/Migo.Syndication/OpmlParser.cs" subtype="Code" buildaction="Compile" />
     <File name="Migo/Migo.Syndication/Tests" subtype="Directory" buildaction="Compile" />
     <File name="Migo/Migo.Syndication/Tests/XmlTests.cs" subtype="Code" buildaction="Compile" />
+    <File name="Migo/Migo.TaskCore/AsyncCommandQueue/CommandQueueManager.cs" subtype="Code" buildaction="Compile" />
   </Contents>
   <References>
     <ProjectReference type="Gac" localcopy="True" refto="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />

Modified: trunk/banshee/src/Libraries/Migo/Migo/Migo.DownloadCore/DownloadGroupStatusManager.cs
==============================================================================
--- trunk/banshee/src/Libraries/Migo/Migo/Migo.DownloadCore/DownloadGroupStatusManager.cs	(original)
+++ trunk/banshee/src/Libraries/Migo/Migo/Migo.DownloadCore/DownloadGroupStatusManager.cs	Wed May 21 20:38:19 2008
@@ -34,7 +34,7 @@
 
 namespace Migo.DownloadCore
 {
-    public class DownloadGroupStatusManager : GroupStatusManager<HttpFileDownloadTask>
+    public class DownloadGroupStatusManager : GroupStatusManager
     {
         private long bytesPerSecond;    
                 

Modified: trunk/banshee/src/Libraries/Migo/Migo/Migo.DownloadCore/DownloadManager.cs
==============================================================================
--- trunk/banshee/src/Libraries/Migo/Migo/Migo.DownloadCore/DownloadManager.cs	(original)
+++ trunk/banshee/src/Libraries/Migo/Migo/Migo.DownloadCore/DownloadManager.cs	Wed May 21 20:38:19 2008
@@ -96,6 +96,11 @@
             dg.TaskAssociated += TaskAssociatedHandler;
         }
         
+        public HttpFileDownloadTask CreateDownloadTask (string url) 
+        {
+            return CreateDownloadTask (url, null);
+        }
+        
         public HttpFileDownloadTask CreateDownloadTask (string url, object userState)
         {
             Uri uri;

Modified: trunk/banshee/src/Libraries/Migo/Migo/Migo.DownloadCore/HttpFileDownloadTask.cs
==============================================================================
--- trunk/banshee/src/Libraries/Migo/Migo/Migo.DownloadCore/HttpFileDownloadTask.cs	(original)
+++ trunk/banshee/src/Libraries/Migo/Migo/Migo.DownloadCore/HttpFileDownloadTask.cs	Wed May 21 20:38:19 2008
@@ -119,7 +119,7 @@
 	    }
 	    
 	    public HttpFileDownloadTask (string remoteUri, string localPath, object userState) 
-            : base (String.Empty, null, userState)
+            : base (String.Empty, userState)
 	    {
 	        this.remoteUri = new Uri (remoteUri);
 	        this.localPath = localPath;	   

Modified: trunk/banshee/src/Libraries/Migo/Migo/Migo.Syndication/FeedsManager.cs
==============================================================================
--- trunk/banshee/src/Libraries/Migo/Migo/Migo.Syndication/FeedsManager.cs	(original)
+++ trunk/banshee/src/Libraries/Migo/Migo/Migo.Syndication/FeedsManager.cs	Wed May 21 20:38:19 2008
@@ -55,7 +55,7 @@
     {        
         private bool disposed;
 
-        private AsyncCommandQueue<ICommand> command_queue;
+        private AsyncCommandQueue command_queue;
         
         private FeedManager feed_manager;
         private EnclosureManager enclosure_manager;
@@ -73,7 +73,7 @@
         
         public static FeedsManager Instance;
         
-        internal AsyncCommandQueue<ICommand> CommandQueue {
+        internal AsyncCommandQueue CommandQueue {
             get { return command_queue; }
         }
         
@@ -138,7 +138,7 @@
             FeedItem.Init ();
             FeedEnclosure.Init ();
             
-            command_queue = new AsyncCommandQueue<ICommand> ();
+            command_queue = new AsyncCommandQueue ();
         }
         
 #endregion

Modified: trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/AsyncCommandQueue/AsyncCommandQueue.cs
==============================================================================
--- trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/AsyncCommandQueue/AsyncCommandQueue.cs	(original)
+++ trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/AsyncCommandQueue/AsyncCommandQueue.cs	Wed May 21 20:38:19 2008
@@ -34,12 +34,12 @@
 {        
     delegate void ExecuteCommand (ICommand command);
 
-    public class AsyncCommandQueue<T> : IDisposable where T : ICommand
+    public class AsyncCommandQueue : IDisposable
     {
         private bool disposed;
         private bool executing;
 
-        private Queue<T> eventQueue;
+        private Queue<ICommand> eventQueue;
         private RegisteredWaitHandle registeredHandle;
         private AutoResetEvent are = new AutoResetEvent (false);
         private ManualResetEvent executingHandle = new ManualResetEvent (true);
@@ -90,7 +90,7 @@
                 };                    
             }
             
-            eventQueue = new Queue<T> ();
+            eventQueue = new Queue<ICommand> ();
 
             registeredHandle = ThreadPool.RegisterWaitForSingleObject (
                 are, ProcessEventQueue, null, -1, false
@@ -122,7 +122,7 @@
             }
         }
     
-        public virtual bool Register (T command)
+        public virtual bool Register (ICommand command)
         {
             lock (sync) {   
                 if (disposed) {
@@ -133,7 +133,7 @@
             }
         }
         
-        protected virtual bool Register (T command, bool pumpQueue)
+        protected virtual bool Register (ICommand command, bool pumpQueue)
         {
             if (command == null) {
                 throw new ArgumentNullException ("command");
@@ -148,7 +148,7 @@
             return true;
         }
 
-        public virtual bool Register (IEnumerable<T> commands)
+        public virtual bool Register (IEnumerable<ICommand> commands)
         {
             if (commands == null) {
                 throw new ArgumentNullException ("commands");
@@ -159,7 +159,7 @@
                     return false;
                 }
                 
-                foreach (T c in commands) {
+                foreach (ICommand c in commands) {
                     Register (c, false);
                 }
                 
@@ -197,7 +197,7 @@
         
         protected virtual void ProcessEventQueue (object state, bool timedOut)
         {     
-            T e;
+            ICommand e;
             bool done = false;
            
             while (!done) {

Added: trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/AsyncCommandQueue/CommandQueueManager.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/AsyncCommandQueue/CommandQueueManager.cs	Wed May 21 20:38:19 2008
@@ -0,0 +1,72 @@
+/*************************************************************************** 
+ *  CommandQueueManager.cs
+ *
+ *  Copyright (C) 2008 Michael C. Urbanski
+ *  Written by Mike Urbanski <michael c urbanski gmail com>
+ ****************************************************************************/
+
+/*  THIS FILE IS LICENSED UNDER THE MIT LICENSE AS OUTLINED IMMEDIATELY BELOW: 
+ *
+ *  Permission is hereby granted, free of charge, to any person obtaining a
+ *  copy of this software and associated documentation files (the "Software"),  
+ *  to deal in the Software without restriction, including without limitation  
+ *  the rights to use, copy, modify, merge, publish, distribute, sublicense,  
+ *  and/or sell copies of the Software, and to permit persons to whom the  
+ *  Software is furnished to do so, subject to the following conditions:
+ *
+ *  The above copyright notice and this permission notice shall be included in 
+ *  all copies or substantial portions of the Software.
+ *
+ *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+ *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+ *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+ *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ *  DEALINGS IN THE SOFTWARE.
+ */
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Migo.TaskCore 
+{
+    public static class CommandQueueManager
+    {
+        private static readonly object sync;    
+        private static Dictionary<Guid,AsyncCommandQueue> queues;
+        
+        static CommandQueueManager ()
+        {
+            queues = new Dictionary<Guid,AsyncCommandQueue> ();
+            sync = ((ICollection)queues).SyncRoot;
+        }
+        
+        public static AsyncCommandQueue GetCommandQueue (Guid guid)
+        {
+            lock (sync) {
+                if (queues.ContainsKey (guid)) {
+                    return queues[guid];
+                }
+            }
+            
+            return null;
+        }
+        
+        public static Guid Register (AsyncCommandQueue queue)
+        {
+            if (queue == null) {
+                throw new ArgumentNullException ("queue");
+            }
+            
+            Guid guid = Guid.NewGuid ();
+            
+            lock (sync) {
+                queues.Add (guid, queue);        
+            }
+            
+            return guid;
+        }
+    }
+}
\ No newline at end of file

Modified: trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/GroupProgressManager.cs
==============================================================================
--- trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/GroupProgressManager.cs	(original)
+++ trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/GroupProgressManager.cs	Wed May 21 20:38:19 2008
@@ -39,15 +39,11 @@
 
         private int totalTicks;
         private int currentTicks;
+       
+        private Dictionary<T,int> progDict;
+        
+        public event EventHandler<ProgressChangedEventArgs> ProgressChanged;
         
-        private TaskGroup<T> group;        
-        internal Dictionary<T,int> progDict;
-
-        public virtual TaskGroup<T> Group {
-            get { return group; }
-            set { group = value; }
-        }
-
         public GroupProgressManager ()
         {
             progDict = new Dictionary<T,int> ();
@@ -173,13 +169,14 @@
             
             if (progress != oldProgress) {
                 oldProgress = progress;
-                TaskGroup<T> grp = group;
                 
-                if (grp != null) {
-                    grp.OnProgressChanged (
-                        new ProgressChangedEventArgs (progress, null)
+                EventHandler<ProgressChangedEventArgs> handler = ProgressChanged;                
+                
+                if (handler != null) {
+                    handler (
+                        this, new ProgressChangedEventArgs (progress, null) 
                     );
-                }                
+                }
             }
         }
     }

Modified: trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/GroupStatusManager.cs
==============================================================================
--- trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/GroupStatusManager.cs	(original)
+++ trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/GroupStatusManager.cs	Wed May 21 20:38:19 2008
@@ -31,7 +31,7 @@
  
 namespace Migo.TaskCore
  {
-    public class GroupStatusManager<T> : IDisposable where T : Task
+    public class GroupStatusManager : IDisposable
     {            
         private bool disposed;        
         private bool suspendUpdate;
@@ -41,13 +41,9 @@
         private int remainingTasks;
         private int maxRunningTasks = 0;
 
-        private ManualResetEvent mre;   
-        private TaskGroup<T> group;        
+        private ManualResetEvent mre;     
 
-        public virtual TaskGroup<T> Group {
-            get { return group; }
-            set { group = value; }
-        }
+        public event EventHandler<GroupStatusChangedEventArgs> StatusChanged;
 
         public virtual int CompletedTasks
         {
@@ -261,7 +257,6 @@
         public virtual void Wait ()
         {           
             CheckDisposed ();                
-            
             mre.WaitOne ();
         }
 
@@ -305,11 +300,11 @@
             if (suspendUpdate) {
                 return;
             }
+
+            EventHandler<GroupStatusChangedEventArgs> handler = StatusChanged;
             
-            TaskGroup<T> grp = group;            
-            
-            if (grp != null) {
-                grp.OnStatusChanged (e);
+            if (handler != null) {
+                handler (this, e);
             }
         }
 

Modified: trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/Migo.TaskCore.Collections/TaskCollection.cs
==============================================================================
--- trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/Migo.TaskCore.Collections/TaskCollection.cs	(original)
+++ trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/Migo.TaskCore.Collections/TaskCollection.cs	Wed May 21 20:38:19 2008
@@ -37,7 +37,7 @@
     public abstract class TaskCollection<T> : ICollection<T>
         where T : Task
     {
-        private AsyncCommandQueue<ICommand> commandQueue;        
+        private AsyncCommandQueue commandQueue;        
         
         public EventHandler<ReorderedEventArgs> Reordered;
     
@@ -49,7 +49,7 @@
             get; // is Move implemented
         }
     
-        public virtual AsyncCommandQueue<ICommand> CommandQueue
+        public virtual AsyncCommandQueue CommandQueue
         {
             get { return commandQueue; }
             set { commandQueue = value; } 

Modified: trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/Task.cs
==============================================================================
--- trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/Task.cs	(original)
+++ trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/Task.cs	Wed May 21 20:38:19 2008
@@ -38,7 +38,7 @@
         private int progress;        
         
         private Guid groupID;
-        private TaskEventPipeline pipeline;
+        private AsyncCommandQueue commandQueue;
         
         private TaskStatus status;
         
@@ -72,13 +72,7 @@
             get { return name; }
             set { name = value; }
         }
-        
-        public TaskEventPipeline EventPipeline
-        {
-            get { return pipeline; }
-            set { pipeline = value; }
-        }
-        
+
         public int Progress 
         {
             get { return progress; }
@@ -108,23 +102,29 @@
      
         internal Guid GroupID {
             get { return groupID; }
-            set { groupID = value; }
+            set { 
+                lock (syncRoot) {
+                    groupID = value;
+                    commandQueue = CommandQueueManager.GetCommandQueue (groupID);
+                }
+            }
         }
 
-        protected Task () : this (String.Empty, null, null) {}
-        protected Task (string name, TaskEventPipeline pipeline, object userState)
+        protected Task () : this (String.Empty, null) {}
+        protected Task (string name, object userState)
         {
-            this.pipeline = pipeline; 
-        
-            groupID = Guid.Empty;                                    
+            GroupID = Guid.Empty;                                    
+
             this.name = name;
-            progress = 0;
-            status = TaskStatus.Ready;
             this.userState = userState;
+            
+            progress = 0;
+            status = TaskStatus.Ready;            
         }     
         
         public abstract void CancelAsync ();
-        
+        public abstract void ExecuteAsync ();
+
         public virtual void Pause ()
         {
             throw new NotImplementedException ("Pause");
@@ -139,9 +139,6 @@
         {
             throw new NotImplementedException ("Stop");            
         }
-        
-        public abstract void ExecuteAsync ();
-
 
         public override string ToString ()
         {
@@ -185,19 +182,19 @@
 
         protected virtual void OnProgressChanged (ProgressChangedEventArgs e)
         {
-            TaskEventPipeline pipelineCpy = pipeline;
+            AsyncCommandQueue queue = commandQueue;
             EventHandler<ProgressChangedEventArgs> handler = ProgressChanged;
             
-            if (pipelineCpy != null) {
-                pipelineCpy.RegisterCommand (new CommandWrapper (delegate {     
-                    pipelineCpy.OnTaskProgressChanged (this, e);
-                    
+            if (queue != null) {
+                queue.Register (new CommandWrapper (delegate {     
                     if (handler != null) {
                         handler (this, e);                
                     }
                 }));                    
             } else if (handler != null) {
-                handler (this, e);
+                ThreadPool.QueueUserWorkItem (delegate {                            
+                    handler (this, e);
+                });
             }
         }
 
@@ -211,22 +208,20 @@
 
         protected virtual void OnStatusChanged (TaskStatusChangedInfo tsci)
         {
-            TaskEventPipeline pipelineCpy = pipeline;
+            AsyncCommandQueue queue = commandQueue;
             EventHandler<TaskStatusChangedEventArgs> handler = StatusChanged;
 
-            if (pipelineCpy != null) {
-                pipelineCpy.RegisterCommand (new CommandWrapper (delegate {            
-                    TaskStatusChangedEventArgs e = 
-                        new TaskStatusChangedEventArgs (tsci);
-                        
-                    pipelineCpy.OnTaskStatusChanged (e);
-                    
+            if (queue != null) {
+                queue.Register (new CommandWrapper (delegate {            
+                    TaskStatusChangedEventArgs e = new TaskStatusChangedEventArgs (tsci);                      
                     if (handler != null) {
                         handler (this, e);               
                     }
                 }));
             } else if (handler != null) {
-                handler (this, new TaskStatusChangedEventArgs (tsci));
+                ThreadPool.QueueUserWorkItem (delegate {            
+                    handler (this, new TaskStatusChangedEventArgs (tsci));
+                });
             }
         }
   
@@ -239,19 +234,19 @@
         
         protected virtual void OnTaskCompleted (TaskCompletedEventArgs e) 
         {
-            TaskEventPipeline pipelineCpy = pipeline;
+            AsyncCommandQueue queue = commandQueue;
             EventHandler<TaskCompletedEventArgs> handler = Completed;
 
-            if (pipelineCpy != null) {
-                pipelineCpy.RegisterCommand (new CommandWrapper (delegate {
-                    pipelineCpy.OnTaskCompleted (this, e);
-                    
+            if (queue != null) {
+                queue.Register (new CommandWrapper (delegate {
                     if (handler != null) {
                         handler (this, e);
                     }
                 }));
             } else if (handler != null) {
-                handler (this, e);
+                ThreadPool.QueueUserWorkItem (delegate {
+                    handler (this, e);
+                });
             }
         }  
     }

Modified: trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/TaskGroup.cs
==============================================================================
--- trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/TaskGroup.cs	(original)
+++ trunk/banshee/src/Libraries/Migo/Migo/Migo.TaskCore/TaskGroup.cs	Wed May 21 20:38:19 2008
@@ -35,7 +35,7 @@
 
 namespace Migo.TaskCore
 {        
-    public class TaskGroup<T> : TaskEventPipeline where T : Task
+    public class TaskGroup<T> where T : Task
     {         
         private bool disposed;
         private bool executing;
@@ -44,12 +44,12 @@
         private readonly Guid id;                      
         private readonly object sync;        
         
-        private AsyncCommandQueue<ICommand> commandQueue;        
+        private AsyncCommandQueue commandQueue;        
         
         private List<T> currentTasks;        
         private TaskCollection<T> tasks;            
            
-        private GroupStatusManager<T> gsm;
+        private GroupStatusManager gsm;
         private GroupProgressManager<T> gpm;
         
         // Used to notify user after stopped event has fired
@@ -151,11 +151,11 @@
             }
         }
 
-        protected GroupStatusManager<T> StatusManager 
+        protected GroupStatusManager StatusManager 
         {
             get { 
                 if (gsm == null) {
-                    SetStatusManager (new GroupStatusManager<T> ());
+                    SetStatusManager (new GroupStatusManager ());
                 }
                 
                 return gsm;
@@ -210,36 +210,48 @@
             }
         }
         
+        private bool IsDone
+        {
+            get {
+                return (Disposed || gsm.RemainingTasks == 0);
+            }
+        }        
+        
         public TaskGroup (int maxRunningTasks, TaskCollection<T> tasks)
             : this (maxRunningTasks, tasks, null, null)
         {
         }
 
-        public TaskGroup (int maxRunningTasks, TaskCollection<T> tasks, GroupStatusManager<T> statusManager) 
+        public TaskGroup (int maxRunningTasks, 
+                          TaskCollection<T> tasks, 
+                          GroupStatusManager statusManager)
             : this (maxRunningTasks, tasks, statusManager, null)
         {
         }
         
-        protected TaskGroup (int maxRunningTasks, TaskCollection<T> tasks,
-                                GroupStatusManager<T> statusManager, GroupProgressManager<T> progressManager) 
+        protected TaskGroup (int maxRunningTasks, 
+                             TaskCollection<T> tasks,
+                             GroupStatusManager statusManager, 
+                             GroupProgressManager<T> progressManager)
         {
             if (maxRunningTasks < 0) {
                 throw new ArgumentException ("maxRunningTasks must be >= 0");
             } else if (tasks == null) {
                 throw new ArgumentNullException ("tasks");
             }
-
-            id = Guid.NewGuid ();
+            
             sync = tasks.SyncRoot;
-            commandQueue = new AsyncCommandQueue<ICommand> ();
             currentTasks = new List<T> (maxRunningTasks);
+
+            commandQueue = new AsyncCommandQueue ();
+            id = CommandQueueManager.Register (commandQueue);
                      
             SetProgressManager (
                 progressManager ?? new GroupProgressManager<T> ()
             );            
                         
             SetStatusManager (
-                statusManager ?? new GroupStatusManager<T> ()
+                statusManager ?? new GroupStatusManager ()
             );  
                         
             try {
@@ -306,15 +318,10 @@
                         }                          
                     }    
                     
-                    if (gpm != null) {
-                        gpm.Group = null;
-                    }
-                    
-                    if (gsm != null) {                    
-                        gsm.Group = null;
-                    }                    
-                    
+                    gsm.StatusChanged -= OnStatusChangedHandler;
                     gsm.Dispose ();
+                    
+                    gpm.ProgressChanged -= OnProgressChangedHandler;
                     gpm.Reset ();
                 } finally {
                     gpm = null;
@@ -346,9 +353,9 @@
                     SpawnExecutionThread ();
                 } catch (Exception e) {
                     Hyena.Log.Exception (e);
+                    SetExecuting (false);                
+                    Reset ();                                                                        
                     OnStopped ();
-                    Reset ();                                                            
-                    SetExecuting (false);
                 }
             }
         }
@@ -398,29 +405,6 @@
             return false;
         }
 
-/*  May implement at some point        
-        protected virtual void HoldStatusUpdates ()
-        {
-            lock (sync) {
-                queueStatusUpdates = true;
-            }
-        }
-        
-        protected virtual void ProcessStatusUpdates ()
-        {
-            lock (sync) {
-                queueStatusUpdates = false;
-                
-                TaskStatusChangedInfo[] changeInfo = queuedStatusUpdates.ToArray ();
-                queuedStatusUpdates.Clear ();
-                
-                OnTaskStatusChanged (
-                    new TaskStatusChangedEventArgs (changeInfo)
-                );
-            }
-        }        
-*/        
-
         protected virtual void SetProgressManager (GroupProgressManager<T> progressManager) 
         {
             CheckDisposed ();        
@@ -432,10 +416,10 @@
             }
                                 
             gpm = progressManager;
-            gpm.Group = this;
+            gpm.ProgressChanged += OnProgressChangedHandler;
         }
         
-        protected virtual void SetStatusManager (GroupStatusManager<T> statusManager) 
+        protected virtual void SetStatusManager (GroupStatusManager statusManager) 
         {
             CheckDisposed ();
             
@@ -446,7 +430,7 @@
             }
             
             gsm = statusManager;
-            gsm.Group = this;
+            gsm.StatusChanged += OnStatusChangedHandler;
         }
         
         protected virtual void SetTaskCollection (TaskCollection<T> collection)
@@ -495,14 +479,17 @@
         {            
             CheckDisposed ();            
 
-            if (task.GroupID.CompareTo (Guid.Empty) != 0) {
+            if (task.GroupID != Guid.Empty) {
                 throw new ApplicationException (
                     "Task already associated with a group"
                 );
             }             
             
             task.GroupID = id;
-            task.EventPipeline = this;
+            
+            task.Completed += OnTaskCompletedHandler;
+            task.ProgressChanged += OnTaskProgressChangedHandler;
+            task.StatusChanged += OnTaskStatusChangedHandler;
 
             if (addToProgressGroup) {
                 gpm.Add (task);
@@ -511,7 +498,7 @@
 
         protected virtual bool CheckID (T task)
         {
-            return (task.GroupID.CompareTo (id) == 0); 
+            return (task.GroupID == id); 
         }
 
         protected virtual void Disassociate (IEnumerable<T> tasks)
@@ -533,20 +520,18 @@
         protected virtual void Disassociate (T task, bool removeFromProgressGroup)
         {
             if (CheckID (task)) {
-                if (removeFromProgressGroup && gpm != null) {       
-                    gpm.Remove (task);
-                }
-                
                 task.GroupID = Guid.Empty;
-                task.EventPipeline = null;
+                
+                task.Completed -= OnTaskCompletedHandler;
+                task.ProgressChanged -= OnTaskProgressChangedHandler;
+                task.StatusChanged -= OnTaskStatusChangedHandler;  
+                
+                if (removeFromProgressGroup && gpm != null) {
+                    gpm.Remove (task);
+                }              
             }
         }    
 
-        private bool Done ()
-        {
-            return (Disposed || gsm.RemainingTasks == 0) ? true : false;
-        }
-
         protected virtual void Reset ()
         {
             lock (sync) {
@@ -589,8 +574,8 @@
                 OnTaskEvent (task, TaskStopped);
             }
         }
-        
-        protected internal virtual void OnStatusChanged (GroupStatusChangedEventArgs e)        
+
+        protected virtual void OnStatusChangedHandler (object sender, GroupStatusChangedEventArgs e)
         {
             lock (sync) {
                 if (!cancelRequested) {
@@ -607,23 +592,7 @@
             }
         }
 
-        protected internal virtual void OnStatusChanged (object sender, 
-                                                         GroupStatusChangedEventArgs e)
-        {
-            OnStatusChanged (e);
-        }
-
-        protected internal override void RegisterCommand (ICommand command)
-        {
-            AsyncCommandQueue<ICommand> cmdQCpy = commandQueue;
-            
-            if (cmdQCpy != null && command != null) {
-            	cmdQCpy.Register (command);
-            }
-        }
-
-        protected internal override void OnTaskCompleted (object sender, 
-                                                          TaskCompletedEventArgs e)
+        protected virtual void OnTaskCompletedHandler (object sender, TaskCompletedEventArgs e)
         {   
             lock (sync) {
                 T t = sender as T;
@@ -652,8 +621,7 @@
             }
         }       
         
-        protected internal override void OnTaskProgressChanged (object sender, 
-                                                                ProgressChangedEventArgs e)
+        protected virtual void OnTaskProgressChangedHandler (object sender, ProgressChangedEventArgs e)
         {     
             EventHandler<ProgressChangedEventArgs> handler = TaskProgressChanged;                
                 
@@ -668,7 +636,7 @@
             }                           
         }        
         
-        protected internal override void OnTaskStatusChanged (TaskStatusChangedEventArgs e)
+        protected virtual void OnTaskStatusChangedHandler (object sender, TaskStatusChangedEventArgs e)
         {         
             EventHandler<TaskStatusChangedEventArgs> handler = TaskStatusChanged;                
                 
@@ -679,8 +647,7 @@
             gsm.Evaluate ();       
         } 
         
-        protected virtual void OnTaskAddedHandler (object sender, 
-                                                   TaskAddedEventArgs<T> e)
+        protected virtual void OnTaskAddedHandler (object sender, TaskAddedEventArgs<T> e)
         {        
             lock (sync) {
                 if (e.Task != null) {
@@ -695,8 +662,7 @@
             }
         }        
         
-        protected virtual void OnTaskRemovedHandler (object sender, 
-                                                     TaskRemovedEventArgs<T> e)
+        protected virtual void OnTaskRemovedHandler (object sender, TaskRemovedEventArgs<T> e)
         {
             lock (sync) {
                 if (e.Index != -1 && e.Task != null) {
@@ -732,12 +698,18 @@
             }
         }
 
-        protected internal virtual void OnProgressChanged (ProgressChangedEventArgs e)
+        protected virtual void OnProgressChangedHandler (object sender, ProgressChangedEventArgs e)
         {
-            EventHandler<ProgressChangedEventArgs> handler = ProgressChanged;
-            
-            if (handler != null) {
-                handler (this, e);   
+            lock (sync) {
+                if (!cancelRequested) {        
+                    EventHandler<ProgressChangedEventArgs> handler = ProgressChanged;
+                    
+                    if (handler != null) {
+                    	commandQueue.Register (
+                    	    new EventWrapper<ProgressChangedEventArgs> (handler, this, e)
+                    	);            
+                    }
+                }
             }
         }
 
@@ -773,8 +745,7 @@
             }                         
         }
 
-        private void OnTaskEvent (IEnumerable<T> tasks, 
-                                  EventHandler<TaskEventArgs<T>> eventHandler)
+        private void OnTaskEvent (IEnumerable<T> tasks, EventHandler<TaskEventArgs<T>> eventHandler)
         {
             EventHandler<TaskEventArgs<T>> handler = eventHandler;
         
@@ -810,7 +781,7 @@
                 lock (sync) {
                     gsm.ResetWait ();     
                     
-                    if (Done ()) {
+                    if (IsDone) {
                         executingHandle.Set ();                                                
                         return;
                     } else if (cancelRequested) {
@@ -862,24 +833,4 @@
             t.Start ();       
         }        
     }
-    
-    // This is retarded, I know.  But there is no fucking way to do 
-    // a clean implementation because of generic inheritance.  
-    // I.E.  There is no way for a task to hold a reference to its group
-    // w\o this.  If you know of a way, please tell me.
-    public abstract class TaskEventPipeline
-    {
-        protected internal abstract void RegisterCommand (ICommand command);
-    
-        protected internal abstract void OnTaskCompleted (
-            object sender, TaskCompletedEventArgs e
-        );    
-        
-        protected internal abstract void OnTaskProgressChanged (
-            object sender, ProgressChangedEventArgs e
-        );
-        
-        protected internal abstract void OnTaskStatusChanged (TaskStatusChangedEventArgs e);        
-    }
-    
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]