[mistelix] TaskDispatcher infrastructure. Remove also dead releated code



commit 4bdcb37c08745d3a531e9d4a6e3ff1becea2b597
Author: Jordi Mas <jmas softcatala org>
Date:   Sun Aug 2 14:50:45 2009 +0200

    TaskDispatcher infrastructure. Remove also dead releated code

 src/Backends/ThumbnailCache/Provider.cs            |    3 +-
 .../BackgroundTask.cs => Core/TaskDispatcher.cs}   |   54 ++++++----
 src/DataModel/BackgroundTaskCollection.cs          |  111 --------------------
 src/DataModel/{BackgroundTask.cs => Task.cs}       |   48 ++++++---
 src/Makefile.am                                    |    6 +-
 src/Widgets/FileView.cs                            |   36 ++++++-
 src/Widgets/ImagesFileView.cs                      |   53 ++++------
 src/Widgets/SlideShowImageView.cs                  |   80 +++++++++------
 src/Widgets/VideosFileView.cs                      |   45 ++++-----
 9 files changed, 193 insertions(+), 243 deletions(-)
---
diff --git a/src/Backends/ThumbnailCache/Provider.cs b/src/Backends/ThumbnailCache/Provider.cs
index d39fe6f..2fae6f8 100644
--- a/src/Backends/ThumbnailCache/Provider.cs
+++ b/src/Backends/ThumbnailCache/Provider.cs
@@ -22,7 +22,6 @@
 //
 
 using System;
-using System.Runtime.InteropServices;
 using Gdk;
 
 namespace Mistelix.Backends.ThumbnailCache
@@ -35,7 +34,7 @@ namespace Mistelix.Backends.ThumbnailCache
 		public abstract bool Installed {get;}
 
 		// Get a thumbnail. Returns null if not possible to get a thumbnail
-		// The call does not guaranty that the thumbnail will match the request width & height
+		// The call does not guarantee that the thumbnail will match the requested width & height
 		public abstract Gdk.Pixbuf GetThumbnail (string filename, int width, int height);
 		public abstract void StoreThumbnail (string filename, Gdk.Pixbuf pixbuf);
 	}
diff --git a/src/DataModel/BackgroundTask.cs b/src/Core/TaskDispatcher.cs
similarity index 60%
copy from src/DataModel/BackgroundTask.cs
copy to src/Core/TaskDispatcher.cs
index 2d31f6a..bdf7a7d 100644
--- a/src/DataModel/BackgroundTask.cs
+++ b/src/Core/TaskDispatcher.cs
@@ -1,5 +1,5 @@
 //
-// Copyright (C) 2008 Jordi Mas i Hernandez, jmas softcatala org
+// Copyright (C) 2009 Jordi Mas i Hernandez, jmas softcatala org
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -21,33 +21,47 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-
 using System;
-using System.ComponentModel;
-
-using Mistelix;
+using System.Collections.Generic;
 
+using Mistelix.DataModel;
 
-namespace Mistelix.DataModel
+namespace Mistelix.Core
 {
-	// A tasks that 
-	public class BackgroundTask : BackgroundWorker
+	//
+	// Contains a thread safe list of tasks to do. Every time we do a GetNextTask
+	// the first task is pulled and remove it from the list
+	// 
+	public class TaskDispatcher
 	{
-		public BackgroundTask () {}
+		List <Task> tasks;
 
-		virtual public int Priority {
-			get { return 1; }
+		public TaskDispatcher ()
+		{
+			tasks = new List <Task> ();
 		}
 
-        
-		/*public static void ProxyToMain (InvokeHandler handler)
+		public void AddTask (Task task)
 		{
-			Application.Invoke (handler);
-		}*/
+			lock (tasks) {
+				tasks.Add (task);
+			}
+		}
+		
+		// Get's the next tasks to do a removes it from the list
+		public Task GetNextTask ()
+		{
+			Task task;
+
+			lock (tasks) {
+				if (tasks.Count > 0) {
+					task = tasks [0];
+					tasks.RemoveAt (0);
+				}
+				else
+					task = null;
+			}
+			return task;
+		}
 	}
-	
 }
-
-
-
-
diff --git a/src/DataModel/BackgroundTask.cs b/src/DataModel/Task.cs
similarity index 60%
rename from src/DataModel/BackgroundTask.cs
rename to src/DataModel/Task.cs
index 2d31f6a..67648b4 100644
--- a/src/DataModel/BackgroundTask.cs
+++ b/src/DataModel/Task.cs
@@ -1,5 +1,5 @@
 //
-// Copyright (C) 2008 Jordi Mas i Hernandez, jmas softcatala org
+// Copyright (C) 2009 Jordi Mas i Hernandez, jmas softcatala org
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -23,31 +23,45 @@
 
 
 using System;
-using System.ComponentModel;
-
-using Mistelix;
-
 
 namespace Mistelix.DataModel
 {
-	// A tasks that 
-	public class BackgroundTask : BackgroundWorker
+	//
+	// Encapsulates a task that has to be performed
+	//	* First firing an event to execute it
+	//	* Second firing an event to notify completion
+	// 
+	public class Task
 	{
-		public BackgroundTask () {}
+		object obj;
 
-		virtual public int Priority {
-			get { return 1; }
-		}
+		public virtual event EventHandler DoEventHandler;
+		public virtual event EventHandler CompletedEventHandler;
 
-        
-		/*public static void ProxyToMain (InvokeHandler handler)
+		public Task ()
 		{
-			Application.Invoke (handler);
-		}*/
-	}
 	
-}
+		}
+
+		public Task (object obj)
+		{
+			this.obj = obj;	
+		}
 
+		public object Data {
+			get {return obj; }
+			set {obj = value; }
+		}
 
+		public void Do ()
+		{
+			if (DoEventHandler == null)
+				throw new InvalidOperationException ("DoEventHandler is null");
 
+			DoEventHandler (this, EventArgs.Empty);
 
+			if (CompletedEventHandler != null)
+				CompletedEventHandler (this, EventArgs.Empty);				
+		}
+	}
+}
diff --git a/src/Makefile.am b/src/Makefile.am
index bd51e77..15ffd23 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -13,8 +13,6 @@ MISTELIX_CSDISTFILES =				\
 	$(srcdir)/DataModel/ProjectElement.cs	\
 	$(srcdir)/DataModel/SlideShowProjectElement.cs	\
 	$(srcdir)/DataModel/VideoProjectElement.cs	\
-	$(srcdir)/DataModel/BackgroundTaskCollection.cs 	\
-	$(srcdir)/DataModel/BackgroundTask.cs 	\
 	$(srcdir)/DataModel/Theme.cs	\
 	$(srcdir)/DataModel/ProjectBuilder.cs	\
 	$(srcdir)/Widgets/DirectoryView.cs 	\
@@ -82,7 +80,9 @@ MISTELIX_CSDISTFILES =				\
 	$(srcdir)/Backends/ThumbnailCache/Factory.cs \
 	$(srcdir)/Backends/ThumbnailCache/Gnome.cs \
 	$(srcdir)/Backends/ThumbnailCache/None.cs \
-	$(srcdir)/Widgets/DataMenuItem.cs
+	$(srcdir)/Widgets/DataMenuItem.cs \
+	$(srcdir)/DataModel/Task.cs \
+	$(srcdir)/Core/TaskDispatcher.cs
 
 ASSEMBLIES = \
 	 $(MISTELIX_LIBS)    		\
diff --git a/src/Widgets/FileView.cs b/src/Widgets/FileView.cs
index 35f1bf8..aa22ceb 100644
--- a/src/Widgets/FileView.cs
+++ b/src/Widgets/FileView.cs
@@ -41,7 +41,7 @@ namespace Mistelix.Widgets
 	{
 		virtual public void OnDirChanged (string new_dir) {}
 		virtual public bool IsValidExtension (string filename) {return false;}
-		virtual public void DoWork (object sender, DoWorkEventArgs e) {}
+		virtual public void DoThumbnail (object sender, EventArgs e) {}
 		
 		protected ListStore store;
 		protected BackgroundWorker thumbnailing;
@@ -56,9 +56,12 @@ namespace Mistelix.Widgets
 
 		protected int thumbnail_height;
 		protected int thumbnail_width;
+
+		TaskDispatcher dispatcher;
 			
 		protected FileView ()
 		{
+			dispatcher = new TaskDispatcher ();
 			store = CreateStore ();
 			SelectionMode = SelectionMode.Multiple;
 
@@ -140,10 +143,17 @@ namespace Mistelix.Widgets
 			// TODO: Optimize for directories with images videos
 			foreach (FileInfo di in parent.GetFiles ())
 			{
+				Task task;
+				Gtk.TreeIter iter;
+
 				if (di.Name.StartsWith (".") || IsValidExtension (di.Name) == false)
 					continue;
 
-				store.AppendValues (di.FullName, di.Name, def_image, true);
+				iter = store.AppendValues (di.FullName, di.Name, def_image, true);
+
+				task = new Task (iter);
+				task.DoEventHandler += DoThumbnail;
+				dispatcher.AddTask (task);
 			}
 
 			thumbnailing.RunWorkerAsync (store);
@@ -162,6 +172,28 @@ namespace Mistelix.Widgets
 			store.Clear ();
 		}
 
+		void DoWork (object sender, DoWorkEventArgs e)
+        	{
+			Task task;
+
+			Logger.Debug ("FileView.Dowork start");
+
+			while (true) {
+
+				if (thumbnailing.CancellationPending)
+					break;
+
+				task = dispatcher.GetNextTask ();
+
+				if (task == null)
+					break;
+
+				task.Do ();
+			}
+
+			Logger.Debug ("FileView.Dowork end");
+		}
+
 		void CreateDefaultImage ()
 		{
 			const int channels = 4;
diff --git a/src/Widgets/ImagesFileView.cs b/src/Widgets/ImagesFileView.cs
index 5feabfc..1d35f17 100644
--- a/src/Widgets/ImagesFileView.cs
+++ b/src/Widgets/ImagesFileView.cs
@@ -119,38 +119,31 @@ namespace Mistelix.Widgets
 			return false;
 		}
 
-		public override void DoWork (object sender, DoWorkEventArgs e)
+		public override void DoThumbnail (object sender, EventArgs e)
         	{   
-			ListStore store = (ListStore) e.Argument;
+			Gtk.TreeIter iter;
 			
-			store.Foreach (delegate (TreeModel model, TreePath path, TreeIter iter)  
-			{
-				try {		
-					if (thumbnailing.CancellationPending)
-						return true;
-
-					string file = (string) store.GetValue (iter, COL_PATH);
-					Gdk.Pixbuf im = Backends.ThumbnailCache.Factory.Provider.GetThumbnail (file, thumbnail_width, thumbnail_height);
-
-					if (im == null)
-						im = new Gdk.Pixbuf (file);
-
-					int max = Math.Max (im.Width, im.Height);
-					Gdk.Pixbuf scaled = im.ScaleSimple (thumbnail_width * im.Width / max, thumbnail_height * im.Height / max, InterpType.Nearest);
-
-					Application.Invoke (delegate {
-							store.SetValue (iter, COL_PIXBUF, scaled);
-						} );
-
-					im.Dispose ();
-					return false;
-				}
-
-				catch (Exception ex) {
-					Logger.Error ("ImagesFileView.Dork. Exception: " + ex.Message);
-					return false;
-				}
-			});
+			try {		
+				iter = (Gtk.TreeIter) ((Task)sender).Data;
+				string file = (string) store.GetValue (iter, COL_PATH);
+				Gdk.Pixbuf im = Backends.ThumbnailCache.Factory.Provider.GetThumbnail (file, thumbnail_width, thumbnail_height);
+
+				if (im == null)
+					im = new Gdk.Pixbuf (file);
+
+				int max = Math.Max (im.Width, im.Height);
+				Gdk.Pixbuf scaled = im.ScaleSimple (thumbnail_width * im.Width / max, thumbnail_height * im.Height / max, InterpType.Nearest);
+
+				Application.Invoke (delegate {
+						store.SetValue (iter, COL_PIXBUF, scaled);
+					} );
+
+				im.Dispose ();
+			}
+
+			catch (Exception ex) {
+				Logger.Error ("ImagesFileView.DoThumbnail. Exception: " + ex.Message);
+			}
 		}
 	}
 }
diff --git a/src/Widgets/SlideShowImageView.cs b/src/Widgets/SlideShowImageView.cs
index 4fa072d..7e26ae3 100644
--- a/src/Widgets/SlideShowImageView.cs
+++ b/src/Widgets/SlideShowImageView.cs
@@ -86,12 +86,12 @@ namespace Mistelix.Widgets
 
 		public ShowImageSelectionEventHandler 		ChangeEvent;
 		public ShowImageUpdatedElementsEventHandler	UpdatedElements;
-		List <Gtk.TreeIter> iters_list;
+		TaskDispatcher dispatcher;
 
 		public SlideShowImageView ()
 		{
 			Model = store = CreateStore ();
-			iters_list = new List <Gtk.TreeIter> ();
+			dispatcher = new TaskDispatcher ();
 
 			notitle = Catalog.GetString ("<No title>");
 	
@@ -106,6 +106,7 @@ namespace Mistelix.Widgets
 
 			CursorChanged += OnCursorChanged;
 			thumbnailing = new BackgroundWorker ();
+			thumbnailing.WorkerSupportsCancellation = true;
 			thumbnailing.DoWork += new DoWorkEventHandler (DoWork);
 			ButtonPressEvent += new ButtonPressEventHandler (OnButtonPressed);
 			KeyPressEvent += OnKeyPressed;
@@ -141,7 +142,10 @@ namespace Mistelix.Widgets
 				return false;
 			});
 			Logger.Debug ("SlideShowImageView.Disposed");
+
+			thumbnailing.CancelAsync ();
 			thumbnailing.Dispose ();
+
 			((IDisposable)def_image).Dispose ();
 		}
 
@@ -209,9 +213,12 @@ namespace Mistelix.Widgets
 
 		void RequestThumbnail (object sender, RequestThumbnailEventArgs args)
 		{
-			lock (iters_list) {
-				iters_list.Add (args.Iter);
-			}
+			Task task;
+	
+			task = new Task (args.Iter);
+			task.DoEventHandler += DoThumbnail;
+
+			dispatcher.AddTask (task);
 	
 			if (thumbnailing.IsBusy == false)
 				thumbnailing.RunWorkerAsync (store);
@@ -343,41 +350,50 @@ namespace Mistelix.Widgets
 			return false;
 		}
 
-		void DoWork (object sender, DoWorkEventArgs e)
-        	{
-			Logger.Debug ("SlideShowImageView.Dowork start");
+		// Task event to create the thumbnail 
+		void DoThumbnail (object sender, EventArgs e)
+		{
+			SlideImage image;
+			string filename;
+			DataImageSurface prev_image;
+			DataImageSurface cairo_image;
+			Gtk.TreeIter iter;
 
-			while (true) {
-	
-				Gtk.TreeIter iter;
+			iter = (Gtk.TreeIter) ((Task)sender).Data;
 
-				lock (iters_list) {
-					if (iters_list.Count == 0) 
-						break;
+			prev_image = (DataImageSurface) store.GetValue (iter, COL_CAIROIMAGE);
 
-					iter = iters_list [0];
-					iters_list.RemoveAt (0);
-				}
+			if (prev_image != null) {
+				return;
+			}
 
-				SlideImage image;
-				string filename;
-				DataImageSurface prev_image;
-				DataImageSurface cairo_image;
+			// Discard not visible items
+			if (IsIterVisible (iter) == false)
+				return;
 
-				prev_image = (DataImageSurface) store.GetValue (iter, COL_CAIROIMAGE);
+			image = (SlideImage) store.GetValue (iter, COL_OBJECT);
+			filename = image.image;
+			cairo_image = image.GetThumbnail (thumbnail_width, thumbnail_height);
+			Application.Invoke (delegate { store.SetValue (iter, COL_CAIROIMAGE, cairo_image); });
+		}
 
-				if (prev_image != null) {
-					continue;
-				}
+		void DoWork (object sender, DoWorkEventArgs e)
+        	{
+			Task task;
 
-				// Discard not visible items
-				if (IsIterVisible (iter) == false)
-					continue;
+			Logger.Debug ("SlideShowImageView.Dowork start");
+			
+			while (true) {
 
-				image = (SlideImage) store.GetValue (iter, COL_OBJECT);
-				filename = image.image;
-				cairo_image = image.GetThumbnail (thumbnail_width, thumbnail_height);
-				Application.Invoke (delegate { store.SetValue (iter, COL_CAIROIMAGE, cairo_image); });
+				if (thumbnailing.CancellationPending)
+					break;
+
+				task = dispatcher.GetNextTask ();
+
+				if (task == null)
+					break;
+
+				task.Do ();
 			}
 
 			Logger.Debug ("SlideShowImageView.Dowork end");
diff --git a/src/Widgets/VideosFileView.cs b/src/Widgets/VideosFileView.cs
index 16200c5..620abbe 100644
--- a/src/Widgets/VideosFileView.cs
+++ b/src/Widgets/VideosFileView.cs
@@ -65,40 +65,33 @@ namespace Mistelix.Widgets
 			return false;
 		}
 
-		public override void DoWork (object sender, DoWorkEventArgs e)
+		public override void DoThumbnail (object sender, EventArgs e)
         	{   
-			ListStore store = (ListStore) e.Argument;
-			Logger.Debug ("VideosFileView.Dowork start");
-			store.Foreach (delegate (TreeModel model, TreePath path, TreeIter iter)  
-			{
-				if (thumbnailing.CancellationPending)
-					return true;
-
+			Gtk.TreeIter iter;
+			
+			try {
+				iter = (Gtk.TreeIter) ((Task)sender).Data;
 				string file = (string) store.GetValue (iter, COL_PATH);
 				
-				try {
-					Gdk.Pixbuf im;
+				Gdk.Pixbuf im;
 
-					// TODO: This should be at VideoProjectElement.GetThumbnail
-					im = Backends.GStreamer.Thumbnail.VideoScreenshot (file);
+				// TODO: This should be at VideoProjectElement.GetThumbnail
+				im = Backends.GStreamer.Thumbnail.VideoScreenshot (file);
 
-					int max = Math.Max (im.Width, im.Height);
-					Gdk.Pixbuf scaled = im.ScaleSimple (thumbnail_width * im.Width / max, thumbnail_height * im.Height / max, InterpType.Nearest);
+				int max = Math.Max (im.Width, im.Height);
+				Gdk.Pixbuf scaled = im.ScaleSimple (thumbnail_width * im.Width / max, thumbnail_height * im.Height / max, InterpType.Nearest);
 
-					Application.Invoke (delegate {
-						store.SetValue (iter, COL_PIXBUF, scaled);
-					} );
+				Application.Invoke (delegate {
+					store.SetValue (iter, COL_PIXBUF, scaled);
+				} );
 
-					im.Dispose ();
-					return false;
-				}
+				im.Dispose ();
+			}
 			
-				catch (Exception ex) {
-					Logger.Error ("VideosFileView.DoWork. Exception: " + ex.Message);
-					return false;
-				}
-			});
-			Logger.Debug ("VideosFileView.Dowork end");
+			catch (Exception ex) {
+				Logger.Error ("VideosFileView.DoThumbnail. Exception: " + ex.Message);
+			}
 		}
+
 	}
 }



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