[f-spot/rubenv-gsoc-2009: 65/86] Correctly abort loaders and do it responsively.



commit 56a7ddca49aaaf1a7afc2eb8cc983d3f8fd943fa
Author: Ruben Vermeersch <ruben savanne be>
Date:   Tue Aug 11 16:58:52 2009 +0200

    Correctly abort loaders and do it responsively.

 lib/libfspotraw/fspot-librawloader.cpp |   34 ++++++++++++++++++-------------
 src/Editors/Editor.cs                  |    3 ++
 src/PhotoImageView.cs                  |   17 +++++++++++++++-
 3 files changed, 39 insertions(+), 15 deletions(-)
---
diff --git a/lib/libfspotraw/fspot-librawloader.cpp b/lib/libfspotraw/fspot-librawloader.cpp
index d25b394..dd14a97 100644
--- a/lib/libfspotraw/fspot-librawloader.cpp
+++ b/lib/libfspotraw/fspot-librawloader.cpp
@@ -12,6 +12,8 @@
 
 #include <libraw/libraw.h>
 
+#define return_null_if(cond) if ((cond)) { g_print ("Stopping running!"); self->priv->running = false; return NULL; }
+
 G_DEFINE_TYPE (FSpotLibrawLoader, fspot_librawloader, G_TYPE_OBJECT);
 
 enum {
@@ -54,6 +56,7 @@ struct _FSpotLibrawLoaderPriv
 
 	gboolean opened;
 	gboolean aborted;
+	volatile gboolean running;
 };
 
 static void
@@ -107,6 +110,7 @@ fspot_librawloader_init (FSpotLibrawLoader *self)
 	self->priv->raw_proc = new LibRaw;
 	self->priv->opened = false;
 	self->priv->aborted = false;
+	self->priv->running = false;
 
 	self->priv->raw_proc->set_progress_handler (libraw_progress_callback, self);
 }
@@ -191,14 +195,14 @@ fspot_librawloader_load_embedded (FSpotLibrawLoader *self, int *orientation)
 	GdkPixbuf *pixbuf = NULL;
 	GError *error = NULL;
 
-	if (!open_if_needed (self))
-		return NULL;
+	self->priv->running = true;
+
+	return_null_if (!open_if_needed (self));
 
 	self->priv->raw_proc->unpack_thumb ();
 	image = self->priv->raw_proc->dcraw_make_mem_thumb (&result);
-	if (result != 0 || image == NULL) {
-		return NULL;
-	}
+	return_null_if (result != 0 || image == NULL);
+
 	g_assert (image->type == LIBRAW_IMAGE_JPEG);
 
 	loader = gdk_pixbuf_loader_new ();
@@ -212,6 +216,7 @@ fspot_librawloader_load_embedded (FSpotLibrawLoader *self, int *orientation)
 	g_object_unref (loader);
 	g_free (image);
 
+	self->priv->running = false;
 	return pixbuf;
 }
 
@@ -222,21 +227,18 @@ fspot_librawloader_load_full (FSpotLibrawLoader *self)
 	libraw_processed_image_t *image = NULL;
 	GdkPixbuf *pixbuf = NULL;
 
-	if (!open_if_needed (self))
-		return NULL;
+	self->priv->running = true;
+
+	return_null_if (!open_if_needed (self));
 
 	result = self->priv->raw_proc->unpack ();
-	if (result != 0)
-		return NULL;
+	return_null_if (result != 0);
 
 	result = self->priv->raw_proc->dcraw_process ();
-	if (result != 0)
-		return NULL;
+	return_null_if (result != 0);
 
 	image = self->priv->raw_proc->dcraw_make_mem_image (&result);
-	if (result != 0 || image == NULL) {
-		return NULL;
-	}
+	return_null_if (result != 0 || image == NULL);
 	g_assert (image->type == LIBRAW_IMAGE_BITMAP);
 
 	pixbuf = gdk_pixbuf_new_from_data (image->data,
@@ -249,6 +251,7 @@ fspot_librawloader_load_full (FSpotLibrawLoader *self)
 									   (GdkPixbufDestroyNotify) pixbuf_freed,
 									   image);
 
+	self->priv->running = false;
 	return pixbuf;
 }
 
@@ -305,4 +308,7 @@ fspot_librawloader_set_aborted (FSpotLibrawLoader *self, gboolean aborted)
 {
 	g_return_if_fail (FSPOT_IS_LIBRAWLOADER (self));
 	self->priv->aborted = aborted;
+
+	while (self->priv->running)
+		;
 }
diff --git a/src/Editors/Editor.cs b/src/Editors/Editor.cs
index caf93dc..bac7c4f 100644
--- a/src/Editors/Editor.cs
+++ b/src/Editors/Editor.cs
@@ -227,6 +227,9 @@ namespace FSpot.Editors {
 			Pixbuf previewed = ProcessFast (Preview, null);
 
 			Gtk.Application.Invoke (delegate {
+					if (!StateInitialized)
+						return;
+
 					State.PhotoImageView.ChangeImage (previewed, State.PhotoImageView.PixbufOrientation, false, false);
                     App.Instance.Organizer.InfoBox.UpdateHistogram (previewed);
 
diff --git a/src/PhotoImageView.cs b/src/PhotoImageView.cs
index f3fa4c6..ade9fe7 100644
--- a/src/PhotoImageView.cs
+++ b/src/PhotoImageView.cs
@@ -11,6 +11,8 @@
 //
 
 using System;
+using System.Threading;
+
 using FSpot.Editors;
 using FSpot.Utils;
 using FSpot.Loaders;
@@ -205,6 +207,9 @@ namespace FSpot.Widgets {
 
 		void HandleProgressHint (object sender, ProgressHintEventArgs args)
 		{
+			if (sender != Loader)
+				return;
+
 			UpdateStatus (args.Text, args.Fraction);
 		}
 #endregion
@@ -216,11 +221,21 @@ namespace FSpot.Widgets {
 		bool prepared_is_new;
 		ImageLoaderItem current_item;
 
+		void DisposeLoader (IImageLoader loader)
+		{
+			// This can take some time for slow loaders, doing it in a thread
+			// to improve responsiveness.
+			Thread t = new Thread (delegate () {
+				loader.Dispose ();
+			});
+			t.Start ();
+		}
+
 		void Load (Uri uri)
 		{
 			timer = Log.DebugTimerStart ();
 			if (Loader != null)
-				Loader.Dispose ();
+				DisposeLoader (Loader);
 			HideStatus ();
 
 			current_item = ImageLoaderItem.None;



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