[f-spot/rubenv-gsoc-2009: 65/86] Correctly abort loaders and do it responsively.
- From: Ruben Vermeersch <rubenv src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [f-spot/rubenv-gsoc-2009: 65/86] Correctly abort loaders and do it responsively.
- Date: Sun, 23 May 2010 12:37:25 +0000 (UTC)
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]