[gthumb/ext] refactored the GthPixbufTask class



commit f2778934ec7ca7a4c37afc95ec96368af22c7f62
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Sun Sep 20 13:46:08 2009 +0200

    refactored the GthPixbufTask class
    
    added a generic GthAsyncTask class, made GthPixbufTask an its
    subclass

 extensions/photo_importer/dlg-photo-importer.c |    4 +-
 gthumb/Makefile.am                             |    2 +
 gthumb/glib-utils.c                            |    4 +-
 gthumb/glib-utils.h                            |    6 +-
 gthumb/gth-async-task.c                        |  306 ++++++++++++++++++++++++
 gthumb/gth-async-task.h                        |   63 +++++
 gthumb/gth-file-list.c                         |    4 +-
 gthumb/gth-file-list.h                         |    2 +-
 gthumb/gth-image-loader.c                      |   16 +-
 gthumb/gth-image-loader.h                      |    4 +-
 gthumb/gth-image-preloader.c                   |    4 +-
 gthumb/gth-image-preloader.h                   |    2 +-
 gthumb/gth-image-viewer.c                      |    6 +-
 gthumb/gth-pixbuf-task.c                       |  283 +++++++++-------------
 gthumb/gth-pixbuf-task.h                       |   33 +--
 gthumb/gth-thumb-loader.c                      |    4 +-
 gthumb/gth-thumb-loader.h                      |    2 +-
 gthumb/typedefs.h                              |    3 +-
 18 files changed, 529 insertions(+), 219 deletions(-)
---
diff --git a/extensions/photo_importer/dlg-photo-importer.c b/extensions/photo_importer/dlg-photo-importer.c
index 8910f91..95c28e8 100644
--- a/extensions/photo_importer/dlg-photo-importer.c
+++ b/extensions/photo_importer/dlg-photo-importer.c
@@ -55,7 +55,7 @@ typedef struct {
 	gboolean       loading_list;
 	gboolean       import;
 	GthFileSource *vfs_source;
-	DoneFunc       done_func;
+	DataFunc       done_func;
 	gboolean       cancelling;
 	gulong         monitor_event;
 	GtkWidget     *filter_combobox;
@@ -170,7 +170,7 @@ cancel_done (gpointer user_data)
 
 static void
 cancel (DialogData *data,
-	DoneFunc    done_func)
+	DataFunc    done_func)
 {
 	if (data->cancelling)
 		return;
diff --git a/gthumb/Makefile.am b/gthumb/Makefile.am
index be3ef3d..aafa1b9 100644
--- a/gthumb/Makefile.am
+++ b/gthumb/Makefile.am
@@ -29,6 +29,7 @@ PUBLIC_HEADER_FILES = 					\
 	gio-utils.h					\
 	glib-utils.h					\
 	gnome-desktop-thumbnail.h			\
+	gth-async-task.h				\
 	gth-browser.h					\
 	gth-cell-renderer-thumbnail.h			\
 	gth-cursors.h					\
@@ -137,6 +138,7 @@ gthumb_SOURCES = 					\
 	gconf-utils.c					\
 	gio-utils.c					\
 	glib-utils.c					\
+	gth-async-task.c				\
 	gth-browser.c					\
 	gth-browser-actions-callbacks.c			\
 	gth-cell-renderer-thumbnail.c			\
diff --git a/gthumb/glib-utils.c b/gthumb/glib-utils.c
index be6804c..3e5d8ea 100644
--- a/gthumb/glib-utils.c
+++ b/gthumb/glib-utils.c
@@ -136,7 +136,7 @@ _g_enum_type_get_value_by_nick (GType       enum_type,
 
 
 IdleCall*
-idle_call_new (DoneFunc func,
+idle_call_new (DataFunc func,
 	       gpointer data)
 {
 	IdleCall *call = g_new0 (IdleCall, 1);
@@ -180,7 +180,7 @@ idle_call_exec (IdleCall *call,
 
 
 guint
-call_when_idle (DoneFunc  func,
+call_when_idle (DataFunc  func,
 		gpointer  data)
 {
 	return idle_call_exec (idle_call_new (func, data), TRUE);
diff --git a/gthumb/glib-utils.h b/gthumb/glib-utils.h
index d338dec..676ff44 100644
--- a/gthumb/glib-utils.h
+++ b/gthumb/glib-utils.h
@@ -89,17 +89,17 @@ GEnumValue *  _g_enum_type_get_value_by_nick (GType        enum_type,
 /* idle callback */
 
 typedef struct {
-	DoneFunc func;
+	DataFunc func;
 	gpointer data;
 } IdleCall;
 
 
-IdleCall* idle_call_new           (DoneFunc       func,
+IdleCall* idle_call_new           (DataFunc       func,
 				   gpointer       data);
 void      idle_call_free          (IdleCall      *call);
 guint     idle_call_exec          (IdleCall      *call,
 				   gboolean       use_idle_cb);
-guint     call_when_idle          (DoneFunc       func,
+guint     call_when_idle          (DataFunc       func,
 				   gpointer       data);
 void      object_ready_with_error (gpointer       object,
 				   ReadyCallback  ready_func,
diff --git a/gthumb/gth-async-task.c b/gthumb/gth-async-task.c
new file mode 100644
index 0000000..0c5262e
--- /dev/null
+++ b/gthumb/gth-async-task.c
@@ -0,0 +1,306 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2009 Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#include <glib.h>
+#include "gth-async-task.h"
+#include "typedefs.h"
+
+
+#define PROGRESS_DELAY 200 /* delay between progress notifications */
+
+
+/* Properties */
+enum {
+        PROP_0,
+        PROP_BEFORE_THREAD,
+        PROP_THREAD_FUNC,
+        PROP_AFTER_THREAD
+};
+
+
+struct _GthAsyncTaskPrivate {
+	DataFunc     before_func;
+	GThreadFunc  exec_func;
+	ReadyFunc    after_func;
+	GMutex      *data_mutex;
+	guint        progress_event;
+	gboolean     cancelled;
+	gboolean     terminated;
+	double       progress;
+};
+
+
+static gpointer parent_class = NULL;
+
+
+static void
+gth_async_task_finalize (GObject *object)
+{
+	GthAsyncTask *self;
+
+	g_return_if_fail (GTH_IS_ASYNC_TASK (object));
+	self = GTH_ASYNC_TASK (object);
+
+	if (self->priv->progress_event != 0) {
+		g_source_remove (self->priv->progress_event);
+		self->priv->progress_event = 0;
+	}
+
+	g_mutex_free (self->priv->data_mutex);
+
+	G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+
+static gboolean
+update_progress (gpointer data)
+{
+	GthAsyncTask *self = data;
+	gboolean      terminated;
+	gboolean      cancelled;
+	double        progress;
+
+	g_mutex_lock (self->priv->data_mutex);
+	terminated = self->priv->terminated;
+	cancelled = self->priv->cancelled;
+	progress = self->priv->progress;
+	g_mutex_unlock (self->priv->data_mutex);
+
+	if (terminated || cancelled) {
+		GError *error = NULL;
+
+		g_source_remove (self->priv->progress_event);
+		self->priv->progress_event = 0;
+
+		if (cancelled)
+			error = g_error_new_literal (GTH_TASK_ERROR, GTH_TASK_ERROR_CANCELLED, "");
+
+		if (self->priv->after_func != NULL)
+			self->priv->after_func (error, self);
+		gth_task_completed (GTH_TASK (self), error);
+
+		return FALSE;
+	}
+
+	gth_task_progress (GTH_TASK (self),
+			   NULL,
+			   NULL,
+			   FALSE,
+			   progress);
+
+	return TRUE;
+}
+
+
+static void
+gth_async_task_exec (GthTask *task)
+{
+	GthAsyncTask *self;
+
+	self = GTH_ASYNC_TASK (task);
+
+	if (self->priv->before_func != NULL)
+		self->priv->before_func (self);
+	g_thread_create (self->priv->exec_func, self, FALSE, NULL);
+	self->priv->progress_event = g_timeout_add (PROGRESS_DELAY, update_progress, self);
+}
+
+
+static void
+gth_async_task_cancel (GthTask *task)
+{
+	GthAsyncTask *self;
+
+	g_return_if_fail (GTH_IS_ASYNC_TASK (task));
+
+	self = GTH_ASYNC_TASK (task);
+
+	g_mutex_lock (self->priv->data_mutex);
+	self->priv->cancelled = TRUE;
+	g_mutex_unlock (self->priv->data_mutex);
+}
+
+
+static void
+gth_async_task_set_property (GObject      *object,
+			     guint         property_id,
+			     const GValue *value,
+			     GParamSpec   *pspec)
+{
+	GthAsyncTask *self;
+
+	self = GTH_ASYNC_TASK (object);
+
+	switch (property_id) {
+	case PROP_BEFORE_THREAD:
+		self->priv->before_func = g_value_get_pointer (value);
+		break;
+	case PROP_THREAD_FUNC:
+		self->priv->exec_func = g_value_get_pointer (value);
+		break;
+	case PROP_AFTER_THREAD:
+		self->priv->after_func = g_value_get_pointer (value);
+		break;
+	default:
+		break;
+	}
+}
+
+
+static void
+gth_async_task_get_property (GObject    *object,
+			     guint       property_id,
+			     GValue     *value,
+			     GParamSpec *pspec)
+{
+	GthAsyncTask *self;
+
+	self = GTH_ASYNC_TASK (object);
+
+	switch (property_id) {
+	case PROP_BEFORE_THREAD:
+		g_value_set_pointer (value, self->priv->before_func);
+		break;
+	case PROP_THREAD_FUNC:
+		g_value_set_pointer (value, self->priv->exec_func);
+		break;
+	case PROP_AFTER_THREAD:
+		g_value_set_pointer (value, self->priv->after_func);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+		break;
+	}
+}
+
+
+static void
+gth_async_task_class_init (GthAsyncTaskClass *class)
+{
+	GObjectClass *object_class;
+	GthTaskClass *task_class;
+
+	parent_class = g_type_class_peek_parent (class);
+	g_type_class_add_private (class, sizeof (GthAsyncTaskPrivate));
+
+	object_class = G_OBJECT_CLASS (class);
+	object_class->set_property = gth_async_task_set_property;
+	object_class->get_property = gth_async_task_get_property;
+	object_class->finalize = gth_async_task_finalize;
+
+	task_class = GTH_TASK_CLASS (class);
+	task_class->exec = gth_async_task_exec;
+	task_class->cancel = gth_async_task_cancel;
+
+
+	g_object_class_install_property (object_class,
+					 PROP_BEFORE_THREAD,
+					 g_param_spec_pointer ("before-thread",
+							       "Before",
+							       "The function to execute before the thread",
+							       G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+					 PROP_THREAD_FUNC,
+					 g_param_spec_pointer ("thread-func",
+							       "Function",
+							       "The function to execute inside the thread",
+							       G_PARAM_READWRITE));
+	g_object_class_install_property (object_class,
+					 PROP_AFTER_THREAD,
+					 g_param_spec_pointer ("after-thread",
+							       "After",
+							       "The function to execute after the thread",
+							       G_PARAM_READWRITE));
+}
+
+
+static void
+gth_async_task_init (GthAsyncTask *self)
+{
+	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_ASYNC_TASK, GthAsyncTaskPrivate);
+	self->priv->cancelled = FALSE;
+	self->priv->terminated = FALSE;
+	self->priv->progress_event = 0;
+	self->priv->data_mutex = g_mutex_new ();
+}
+
+
+GType
+gth_async_task_get_type (void)
+{
+	static GType type = 0;
+
+	if (! type) {
+		GTypeInfo type_info = {
+			sizeof (GthAsyncTaskClass),
+			NULL,
+			NULL,
+			(GClassInitFunc) gth_async_task_class_init,
+			NULL,
+			NULL,
+			sizeof (GthAsyncTask),
+			0,
+			(GInstanceInitFunc) gth_async_task_init
+		};
+
+		type = g_type_register_static (GTH_TYPE_TASK,
+					       "GthAsyncTask",
+					       &type_info,
+					       0);
+	}
+
+	return type;
+}
+
+
+void
+gth_async_task_set_data (GthAsyncTask *self,
+			 gboolean     *terminated,
+			 gboolean     *cancelled,
+			 double       *progress)
+{
+	g_mutex_lock (self->priv->data_mutex);
+	if (terminated != NULL)
+		self->priv->terminated = *terminated;
+	if (cancelled != NULL)
+		self->priv->cancelled = *cancelled;
+	if (progress != NULL)
+		self->priv->progress = *progress;
+	g_mutex_unlock (self->priv->data_mutex);
+}
+
+
+void
+gth_async_task_get_data (GthAsyncTask *self,
+			 gboolean     *terminated,
+			 gboolean     *cancelled,
+			 double       *progress)
+{
+	g_mutex_lock (self->priv->data_mutex);
+	if (terminated != NULL)
+		*terminated = self->priv->terminated;
+	if (cancelled != NULL)
+		*cancelled = self->priv->cancelled;
+	if (progress != NULL)
+		*progress = self->priv->progress;
+	g_mutex_unlock (self->priv->data_mutex);
+}
diff --git a/gthumb/gth-async-task.h b/gthumb/gth-async-task.h
new file mode 100644
index 0000000..e3c6f1b
--- /dev/null
+++ b/gthumb/gth-async-task.h
@@ -0,0 +1,63 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  GThumb
+ *
+ *  Copyright (C) 2009 The Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef GTH_ASYNC_TASK_H
+#define GTH_ASYNC_TASK_H
+
+#include <glib.h>
+#include "gth-task.h"
+
+G_BEGIN_DECLS
+
+#define GTH_TYPE_ASYNC_TASK            (gth_async_task_get_type ())
+#define GTH_ASYNC_TASK(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTH_TYPE_ASYNC_TASK, GthAsyncTask))
+#define GTH_ASYNC_TASK_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTH_TYPE_ASYNC_TASK, GthAsyncTaskClass))
+#define GTH_IS_ASYNC_TASK(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTH_TYPE_ASYNC_TASK))
+#define GTH_IS_ASYNC_TASK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTH_TYPE_ASYNC_TASK))
+#define GTH_ASYNC_TASK_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), GTH_TYPE_ASYNC_TASK, GthAsyncTaskClass))
+
+typedef struct _GthAsyncTask        GthAsyncTask;
+typedef struct _GthAsyncTaskClass   GthAsyncTaskClass;
+typedef struct _GthAsyncTaskPrivate GthAsyncTaskPrivate;
+
+struct _GthAsyncTask {
+	GthTask __parent;
+	GthAsyncTaskPrivate *priv;
+};
+
+struct _GthAsyncTaskClass {
+	GthTaskClass __parent;
+};
+
+GType         gth_async_task_get_type    (void);
+void          gth_async_task_set_data    (GthAsyncTask *self,
+					  gboolean     *terminated,
+					  gboolean     *cancelled,
+					  double       *progress);
+void          gth_async_task_get_data    (GthAsyncTask *self,
+					  gboolean     *terminated,
+					  gboolean     *cancelled,
+					  double       *progress);
+
+G_END_DECLS
+
+#endif /* GTH_ASYNC_TASK_H */
diff --git a/gthumb/gth-file-list.c b/gthumb/gth-file-list.c
index 52d6561..2343eee 100644
--- a/gthumb/gth-file-list.c
+++ b/gthumb/gth-file-list.c
@@ -110,7 +110,7 @@ struct _GthFileListPrivateData
 
 	char           **caption_attributes_v;
 
-	DoneFunc         done_func;
+	DataFunc         done_func;
 	gpointer         done_func_data;
 };
 
@@ -702,7 +702,7 @@ cancel_step2 (gpointer user_data)
 
 void
 gth_file_list_cancel (GthFileList *file_list,
-		      DoneFunc     done_func,
+		      DataFunc     done_func,
 		      gpointer     user_data)
 {
 	_gth_file_list_clear_queue (file_list);
diff --git a/gthumb/gth-file-list.h b/gthumb/gth-file-list.h
index 0f4c03c..3b171c9 100644
--- a/gthumb/gth-file-list.h
+++ b/gthumb/gth-file-list.h
@@ -60,7 +60,7 @@ struct _GthFileListClass {
 GType           gth_file_list_get_type        (void);
 GtkWidget *     gth_file_list_new             (GthFileListType       list_type);
 void            gth_file_list_cancel          (GthFileList          *file_list,
-					       DoneFunc              done_func,
+					       DataFunc              done_func,
 					       gpointer              user_data);
 void            gth_file_list_set_files       (GthFileList          *file_list,
 					       GList                *list);
diff --git a/gthumb/gth-image-loader.c b/gthumb/gth-image-loader.c
index a73d075..e0b0702 100644
--- a/gthumb/gth-image-loader.c
+++ b/gthumb/gth-image-loader.c
@@ -59,7 +59,7 @@ struct _GthImageLoaderPrivate {
 	gboolean            loading;
 	gboolean            emit_signal;
 
-	DoneFunc            done_func;
+	DataFunc            done_func;
 	gpointer            done_func_data;
 
 	guint               check_id;
@@ -136,7 +136,7 @@ gth_image_loader_finalize__step2 (GObject *object)
 
 
 static void _gth_image_loader_stop (GthImageLoader *iloader,
-				    DoneFunc        done_func,
+				    DataFunc        done_func,
 				    gpointer        done_func_data,
 				    gboolean        emit_sig,
 				    gboolean        use_idle_cb);
@@ -163,7 +163,7 @@ gth_image_loader_finalize (GObject *object)
 	}
 
 	_gth_image_loader_stop (iloader,
-				(DoneFunc) gth_image_loader_finalize__step2,
+				(DataFunc) gth_image_loader_finalize__step2,
 				object,
 				FALSE,
 				FALSE);
@@ -679,7 +679,7 @@ gth_image_loader_load (GthImageLoader *iloader)
 		return;
 
 	_gth_image_loader_stop (iloader,
-				(DoneFunc) _gth_image_loader_load__step2,
+				(DataFunc) _gth_image_loader_load__step2,
 				iloader,
 				FALSE,
 				TRUE);
@@ -693,7 +693,7 @@ static void
 _gth_image_loader_stop__step2 (GthImageLoader *iloader,
 			       gboolean        use_idle_cb)
 {
-	DoneFunc  done_func = iloader->priv->done_func;
+	DataFunc  done_func = iloader->priv->done_func;
 	GError   *error;
 
 	g_mutex_lock (iloader->priv->data_mutex);
@@ -731,7 +731,7 @@ _gth_image_loader_stop__step2 (GthImageLoader *iloader,
 
 static void
 _gth_image_loader_stop (GthImageLoader *iloader,
-			DoneFunc        done_func,
+			DataFunc        done_func,
 			gpointer        done_func_data,
 			gboolean        emit_signal,
 			gboolean        use_idle_cb)
@@ -746,7 +746,7 @@ _gth_image_loader_stop (GthImageLoader *iloader,
 
 void
 gth_image_loader_cancel (GthImageLoader *iloader,
-			  DoneFunc        done_func,
+			  DataFunc        done_func,
 			 gpointer        done_func_data)
 {
 	g_mutex_lock (iloader->priv->data_mutex);
@@ -770,7 +770,7 @@ gth_image_loader_cancel (GthImageLoader *iloader,
 
 void
 gth_image_loader_cancel_with_error (GthImageLoader *iloader,
-				    DoneFunc        done_func,
+				    DataFunc        done_func,
 				    gpointer        done_func_data)
 {
 	g_mutex_lock (iloader->priv->data_mutex);
diff --git a/gthumb/gth-image-loader.h b/gthumb/gth-image-loader.h
index 25da34f..9d957ba 100644
--- a/gthumb/gth-image-loader.h
+++ b/gthumb/gth-image-loader.h
@@ -77,10 +77,10 @@ GdkPixbufAnimation * gth_image_loader_get_animation           (GthImageLoader
 gboolean             gth_image_loader_is_ready                (GthImageLoader    *iloader);
 void                 gth_image_loader_load                    (GthImageLoader    *iloader);
 void                 gth_image_loader_cancel                  (GthImageLoader    *iloader,
-						               DoneFunc           done_func,
+						               DataFunc           done_func,
 						               gpointer           done_func_data);
 void                 gth_image_loader_cancel_with_error       (GthImageLoader    *iloader,
-						               DoneFunc           done_func,
+						               DataFunc           done_func,
 						               gpointer           done_func_data);
 void                 gth_image_loader_load_from_pixbuf_loader (GthImageLoader    *iloader,
 				                               GdkPixbufLoader   *pixbuf_loader);						               
diff --git a/gthumb/gth-image-preloader.c b/gthumb/gth-image-preloader.c
index 65334a5..ca594db 100644
--- a/gthumb/gth-image-preloader.c
+++ b/gthumb/gth-image-preloader.c
@@ -465,7 +465,7 @@ gth_image_preloader_load (GthImagePreloader  *image_preloader,
 	LoadData *load_data;
 
 	load_data = load_data_new (image_preloader, requested, next1, prev1);
-	gth_image_preloader_stop (image_preloader, (DoneFunc) gth_image_preloader_load__step2, load_data);
+	gth_image_preloader_stop (image_preloader, (DataFunc) gth_image_preloader_load__step2, load_data);
 }
 
 
@@ -567,7 +567,7 @@ start_next_loader (GthImagePreloader *image_preloader)
 
 void
 gth_image_preloader_stop (GthImagePreloader *image_preloader,
-			  DoneFunc           done_func,
+			  DataFunc           done_func,
 			  gpointer           done_func_data)
 {
 	Preloader *preloader;
diff --git a/gthumb/gth-image-preloader.h b/gthumb/gth-image-preloader.h
index 6853a5b..5025137 100644
--- a/gthumb/gth-image-preloader.h
+++ b/gthumb/gth-image-preloader.h
@@ -64,7 +64,7 @@ void                gth_image_preloader_load          (GthImagePreloader  *prelo
 						       GthFileData        *next1,
 						       GthFileData        *prev1);
 void                gth_image_preloader_stop          (GthImagePreloader  *preloader,
-						       DoneFunc            done_func,
+						       DataFunc            done_func,
 						       gpointer            done_func_data);
 GthImageLoader *    gth_image_preloader_get_loader    (GthImagePreloader  *preloader,
 						       GthFileData        *file_data);
diff --git a/gthumb/gth-image-viewer.c b/gthumb/gth-image-viewer.c
index c96f81a..b40ecb8 100644
--- a/gthumb/gth-image-viewer.c
+++ b/gthumb/gth-image-viewer.c
@@ -1919,7 +1919,7 @@ gth_image_viewer_load (GthImageViewer *viewer,
 	lidata = g_new0 (LoadImageData, 1);
 	lidata->viewer = viewer;
 	lidata->file_data = g_object_ref (file_data);
-	gth_image_loader_cancel (viewer->priv->loader, (DoneFunc) load_image__step2, lidata);
+	gth_image_loader_cancel (viewer->priv->loader, (DataFunc) load_image__step2, lidata);
 }
 
 
@@ -1975,7 +1975,7 @@ gth_image_viewer_load_from_pixbuf_loader (GthImageViewer  *viewer,
 	ivl_data->data = g_object_ref (pixbuf_loader);
 
 	gth_image_loader_cancel (viewer->priv->loader,
-				 (DoneFunc) load_from_pixbuf_loader__step2,
+				 (DataFunc) load_from_pixbuf_loader__step2,
 				 ivl_data);
 }
 
@@ -2012,7 +2012,7 @@ gth_image_viewer_load_from_image_loader (GthImageViewer *viewer,
 	ivl_data->data = g_object_ref (image_loader);
 
 	gth_image_loader_cancel (viewer->priv->loader,
-				 (DoneFunc) load_from_image_loader__step2,
+				 (DataFunc) load_from_image_loader__step2,
 				 ivl_data);
 }
 
diff --git a/gthumb/gth-pixbuf-task.c b/gthumb/gth-pixbuf-task.c
index f95ba74..a414d44 100644
--- a/gthumb/gth-pixbuf-task.c
+++ b/gthumb/gth-pixbuf-task.c
@@ -24,23 +24,29 @@
 #include "gth-pixbuf-task.h"
 
 
-#define PROGRESS_DELAY 200 /* delay between progress notifications */
+struct _GthPixbufTaskPrivate {
+	const char     *description;
+	PixbufOpFunc    init_func;
+	PixbufOpFunc    step_func;
+	PixbufDataFunc  release_func;
+	PixbufOpFunc    free_data_func;
+};
 
 
 static gpointer parent_class = NULL;
 
 
 static void
-release_pixbufs (GthPixbufTask *pixbuf_task)
+release_pixbufs (GthPixbufTask *self)
 {
-	if (pixbuf_task->src != NULL) {
-		g_object_unref (pixbuf_task->src);
-		pixbuf_task->src = NULL;
+	if (self->src != NULL) {
+		g_object_unref (self->src);
+		self->src = NULL;
 	}
 
-	if (pixbuf_task->dest != NULL) {
-		g_object_unref (pixbuf_task->dest);
-		pixbuf_task->dest = NULL;
+	if (self->dest != NULL) {
+		g_object_unref (self->dest);
+		self->dest = NULL;
 	}
 }
 
@@ -48,157 +54,106 @@ release_pixbufs (GthPixbufTask *pixbuf_task)
 static void
 gth_pixbuf_task_finalize (GObject *object)
 {
-	GthPixbufTask *pixbuf_task;
+	GthPixbufTask *self;
 
 	g_return_if_fail (GTH_IS_PIXBUF_TASK (object));
-	pixbuf_task = GTH_PIXBUF_TASK (object);
+	self = GTH_PIXBUF_TASK (object);
 
-	if (pixbuf_task->progress_event != 0) {
-		g_source_remove (pixbuf_task->progress_event);
-		pixbuf_task->progress_event = 0;
-	}
-
-	release_pixbufs (pixbuf_task);
-	if (pixbuf_task->free_data_func != NULL)
-		(*pixbuf_task->free_data_func) (pixbuf_task);
-
-	g_mutex_free (pixbuf_task->data_mutex);
+	release_pixbufs (self);
+	if (self->priv->free_data_func != NULL)
+		(*self->priv->free_data_func) (self);
 
 	G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
 
-static gboolean
-update_progress (gpointer data)
+static void
+before_execute_pixbuf_task (gpointer user_data)
 {
-	GthPixbufTask *pixbuf_task = data;
-	gboolean       interrupt;
-	int            line;
-
-	g_mutex_lock (pixbuf_task->data_mutex);
-	interrupt = pixbuf_task->interrupt;
-	line = pixbuf_task->line;
-	g_mutex_unlock (pixbuf_task->data_mutex);
-
-	if ((line >= pixbuf_task->height) || interrupt) {
-		GError *error = NULL;
-
-		g_source_remove (pixbuf_task->progress_event);
-		pixbuf_task->progress_event = 0;
-
-		if (interrupt)
-			error = g_error_new_literal (GTH_TASK_ERROR, GTH_TASK_ERROR_CANCELLED, "");
-
-		if (pixbuf_task->release_func != NULL)
-			(*pixbuf_task->release_func) (pixbuf_task, error);
+	GthPixbufTask *self = user_data;
 
-		gth_task_completed (GTH_TASK (pixbuf_task), error);
-
-		return FALSE;
-	}
-
-	gth_task_progress (GTH_TASK (pixbuf_task),
-			   pixbuf_task->description,
+	gth_task_progress (GTH_TASK (self),
+			   self->priv->description,
 			   NULL,
-			   FALSE,
-			   (double) line / pixbuf_task->height);
-
-	return TRUE;
+			   TRUE,
+			   0.0);
 }
 
 
 static gboolean
-execute_step (GthPixbufTask *pixbuf_task)
+execute_step (GthPixbufTask *self)
 {
-	int      dir = 1;
-	gboolean interrupt;
-	int      line;
-
-	g_mutex_lock (pixbuf_task->data_mutex);
-	interrupt = pixbuf_task->interrupt;
-	line = pixbuf_task->line;
-	g_mutex_unlock (pixbuf_task->data_mutex);
-
-	if ((line >= pixbuf_task->height) || interrupt)
+	gboolean terminated;
+	gboolean cancelled;
+	double   progress;
+	int      dir;
+
+	gth_async_task_get_data (GTH_ASYNC_TASK (self), &terminated, &cancelled, NULL);
+	if (self->line >= self->height)
+		terminated = TRUE;
+	progress = (double) self->line / self->height;
+	gth_async_task_set_data (GTH_ASYNC_TASK (self), &terminated, NULL, &progress);
+
+	if (terminated || cancelled)
 		return FALSE;
 
-	pixbuf_task->src_pixel = pixbuf_task->src_line;
-	pixbuf_task->src_line += pixbuf_task->rowstride;
+	self->src_pixel = self->src_line;
+	self->src_line += self->rowstride;
 
-	pixbuf_task->dest_pixel = pixbuf_task->dest_line;
-	pixbuf_task->dest_line += pixbuf_task->rowstride;
+	self->dest_pixel = self->dest_line;
+	self->dest_line += self->rowstride;
 
-	if (! pixbuf_task->ltr) { /* right to left */
-		int ofs = (pixbuf_task->width - 1) * pixbuf_task->bytes_per_pixel;
-		pixbuf_task->src_pixel += ofs;
-		pixbuf_task->dest_pixel += ofs;
+	if (! self->ltr) { /* right to left */
+		int ofs = (self->width - 1) * self->bytes_per_pixel;
+		self->src_pixel += ofs;
+		self->dest_pixel += ofs;
 		dir = -1;
-		pixbuf_task->column = pixbuf_task->width - 1;
+		self->column = self->width - 1;
 	}
-	else
-		pixbuf_task->column = 0;
-
-	pixbuf_task->line_step = 0;
-	while (pixbuf_task->line_step < pixbuf_task->width) {
-		(*pixbuf_task->step_func) (pixbuf_task);
-		pixbuf_task->src_pixel += dir * pixbuf_task->bytes_per_pixel;
-		pixbuf_task->dest_pixel += dir * pixbuf_task->bytes_per_pixel;
-		pixbuf_task->column += dir;
-		pixbuf_task->line_step++;
+	else {
+		dir = 1;
+		self->column = 0;
 	}
 
-	g_mutex_lock (pixbuf_task->data_mutex);
-	pixbuf_task->line++;
-	g_mutex_unlock (pixbuf_task->data_mutex);
+	self->line_step = 0;
+	while (self->line_step < self->width) {
+		(*self->priv->step_func) (self);
+		self->src_pixel += dir * self->bytes_per_pixel;
+		self->dest_pixel += dir * self->bytes_per_pixel;
+		self->column += dir;
+		self->line_step++;
+	}
+
+	self->line++;
 
 	return TRUE;
 }
 
 
 static gpointer
-execute_task (gpointer user_data)
+execute_pixbuf_task (gpointer user_data)
 {
-	GthPixbufTask *pixbuf_task = user_data;
-
-	g_mutex_lock (pixbuf_task->data_mutex);
-	pixbuf_task->line = 0;
-	g_mutex_unlock (pixbuf_task->data_mutex);
+	GthPixbufTask *self = user_data;
 
-	if (pixbuf_task->init_func != NULL)
-		(*pixbuf_task->init_func) (pixbuf_task);
+	self->line = 0;
+	if (self->priv->init_func != NULL)
+		(*self->priv->init_func) (self);
 
-	while (execute_step (pixbuf_task)) /* void */;
+	while (execute_step (self))
+		/* void */;
 
 	return NULL;
 }
 
 
 static void
-gth_pixbuf_task_exec (GthTask *task)
-{
-	GthPixbufTask *pixbuf_task;
-
-	pixbuf_task = GTH_PIXBUF_TASK (task);
-
-	g_return_if_fail (pixbuf_task->src != NULL);
-
-	g_thread_create (execute_task, pixbuf_task, FALSE, NULL);
-	pixbuf_task->progress_event = g_timeout_add (PROGRESS_DELAY, update_progress, pixbuf_task);
-}
-
-
-static void
-gth_pixbuf_task_cancel (GthTask *task)
+after_execute_pixbuf_task (GError   *error,
+			   gpointer  user_data)
 {
-	GthPixbufTask *pixbuf_task;
-
-	g_return_if_fail (GTH_IS_PIXBUF_TASK (task));
-
-	pixbuf_task = GTH_PIXBUF_TASK (task);
+	GthPixbufTask *self = user_data;
 
-	g_mutex_lock (pixbuf_task->data_mutex);
-	pixbuf_task->interrupt = TRUE;
-	g_mutex_unlock (pixbuf_task->data_mutex);
+	if (self->priv->release_func != NULL)
+		(*self->priv->release_func) (self, error);
 }
 
 
@@ -206,43 +161,33 @@ static void
 gth_pixbuf_task_class_init (GthPixbufTaskClass *class)
 {
 	GObjectClass *object_class;
-	GthTaskClass *task_class;
 
 	parent_class = g_type_class_peek_parent (class);
+	g_type_class_add_private (class, sizeof (GthPixbufTaskPrivate));
 
 	object_class = G_OBJECT_CLASS (class);
 	object_class->finalize = gth_pixbuf_task_finalize;
-
-	task_class = GTH_TASK_CLASS (class);
-	task_class->exec = gth_pixbuf_task_exec;
-	task_class->cancel = gth_pixbuf_task_cancel;
 }
 
 
 static void
-gth_pixbuf_task_init (GthPixbufTask *pixbuf_task)
+gth_pixbuf_task_init (GthPixbufTask *self)
 {
-	pixbuf_task->src = NULL;
-	pixbuf_task->dest = NULL;
-	pixbuf_task->data = NULL;
-
-	pixbuf_task->init_func = NULL;
-	pixbuf_task->step_func = NULL;
-	pixbuf_task->release_func = NULL;
-	pixbuf_task->free_data_func = NULL;
-
-	pixbuf_task->src_line = NULL;
-	pixbuf_task->src_pixel = NULL;
-	pixbuf_task->dest_line = NULL;
-	pixbuf_task->dest_pixel = NULL;
-
-	pixbuf_task->ltr = TRUE;
-
-	pixbuf_task->progress_event = 0;
-	pixbuf_task->line = 0;
-	pixbuf_task->interrupt = FALSE;
-
-	pixbuf_task->data_mutex = g_mutex_new ();
+	self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, GTH_TYPE_PIXBUF_TASK, GthPixbufTaskPrivate);
+	self->priv->init_func = NULL;
+	self->priv->step_func = NULL;
+	self->priv->release_func = NULL;
+	self->priv->free_data_func = NULL;
+
+	self->data = NULL;
+	self->src = NULL;
+	self->dest = NULL;
+	self->src_line = NULL;
+	self->src_pixel = NULL;
+	self->dest_line = NULL;
+	self->dest_pixel = NULL;
+	self->ltr = TRUE;
+	self->line = 0;
 }
 
 
@@ -264,7 +209,7 @@ gth_pixbuf_task_get_type (void)
 			(GInstanceInitFunc) gth_pixbuf_task_init
 		};
 
-		type = g_type_register_static (GTH_TYPE_TASK,
+		type = g_type_register_static (GTH_TYPE_ASYNC_TASK,
 					       "GthPixbufTask",
 					       &type_info,
 					       0);
@@ -280,27 +225,31 @@ gth_pixbuf_task_new (const char     *description,
 		     GdkPixbuf      *dest,
 		     PixbufOpFunc    init_func,
 		     PixbufOpFunc    step_func,
-		     PixbufDoneFunc  release_func,
+		     PixbufDataFunc  release_func,
 		     gpointer        data)
 {
-	GthPixbufTask *pixbuf_task;
+	GthPixbufTask *self;
 
-	pixbuf_task = GTH_PIXBUF_TASK (g_object_new (GTH_TYPE_PIXBUF_TASK, NULL));
+	self = (GthPixbufTask *) g_object_new (GTH_TYPE_PIXBUF_TASK,
+					       "before-thread", before_execute_pixbuf_task,
+					       "thread-func", execute_pixbuf_task,
+					       "after-thread", after_execute_pixbuf_task,
+					       NULL);
 
-	pixbuf_task->description = description;
-	pixbuf_task->init_func = init_func;
-	pixbuf_task->step_func = step_func;
-	pixbuf_task->release_func = release_func;
-	pixbuf_task->data = data;
+	self->priv->description = description;
+	self->priv->init_func = init_func;
+	self->priv->step_func = step_func;
+	self->priv->release_func = release_func;
+	self->data = data;
 
-	gth_pixbuf_task_set_pixbufs (pixbuf_task, src, dest);
+	gth_pixbuf_task_set_pixbufs (self, src, dest);
 
-	return (GthTask *) pixbuf_task;
+	return (GthTask *) self;
 }
 
 
 void
-gth_pixbuf_task_set_pixbufs (GthPixbufTask *pixbuf_task,
+gth_pixbuf_task_set_pixbufs (GthPixbufTask *self,
 			     GdkPixbuf     *src,
 			     GdkPixbuf     *dest)
 {
@@ -318,21 +267,21 @@ gth_pixbuf_task_set_pixbufs (GthPixbufTask *pixbuf_task,
 		g_return_if_fail (gdk_pixbuf_get_colorspace (src) == gdk_pixbuf_get_colorspace (dest));
 	}
 
-	release_pixbufs (pixbuf_task);
+	release_pixbufs (self);
 
 	g_object_ref (src);
-	pixbuf_task->src = src;
+	self->src = src;
 
-	pixbuf_task->has_alpha       = gdk_pixbuf_get_has_alpha (src);
-	pixbuf_task->bytes_per_pixel = pixbuf_task->has_alpha ? 4 : 3;
-	pixbuf_task->width           = gdk_pixbuf_get_width (src);
-	pixbuf_task->height          = gdk_pixbuf_get_height (src);
-	pixbuf_task->rowstride       = gdk_pixbuf_get_rowstride (src);
-	pixbuf_task->src_line        = gdk_pixbuf_get_pixels (src);
+	self->has_alpha       = gdk_pixbuf_get_has_alpha (src);
+	self->bytes_per_pixel = self->has_alpha ? 4 : 3;
+	self->width           = gdk_pixbuf_get_width (src);
+	self->height          = gdk_pixbuf_get_height (src);
+	self->rowstride       = gdk_pixbuf_get_rowstride (src);
+	self->src_line        = gdk_pixbuf_get_pixels (src);
 
 	if (dest != NULL) {
 		g_object_ref (dest);
-		pixbuf_task->dest = dest;
-		pixbuf_task->dest_line = gdk_pixbuf_get_pixels (dest);
+		self->dest = dest;
+		self->dest_line = gdk_pixbuf_get_pixels (dest);
 	}
 }
diff --git a/gthumb/gth-pixbuf-task.h b/gthumb/gth-pixbuf-task.h
index 4f8d251..83ab90f 100644
--- a/gthumb/gth-pixbuf-task.h
+++ b/gthumb/gth-pixbuf-task.h
@@ -20,12 +20,12 @@
  *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
  */
 
-#ifndef _GTH_PIXBUF_TASK_H
-#define _GTH_PIXBUF_TASK_H
+#ifndef GTH_PIXBUF_TASK_H
+#define GTH_PIXBUF_TASK_H
 
 #include <glib.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
-#include "gth-task.h"
+#include "gth-async-task.h"
 
 G_BEGIN_DECLS
 
@@ -38,9 +38,10 @@ G_BEGIN_DECLS
 
 typedef struct _GthPixbufTask        GthPixbufTask;
 typedef struct _GthPixbufTaskClass   GthPixbufTaskClass;
+typedef struct _GthPixbufTaskPrivate GthPixbufTaskPrivate;
 
 typedef void (*PixbufOpFunc)   (GthPixbufTask *pixbuf_task);
-typedef void (*PixbufDoneFunc) (GthPixbufTask *pixbuf_task, GError *error);
+typedef void (*PixbufDataFunc) (GthPixbufTask *pixbuf_task, GError *error);
 
 enum {
 	RED_PIX   = 0,
@@ -50,16 +51,13 @@ enum {
 };
 
 struct _GthPixbufTask {
-	GthTask __parent;
+	GthAsyncTask __parent;
+	GthPixbufTaskPrivate *priv;
 
-	GdkPixbuf      *src;
-	GdkPixbuf      *dest;
 	gpointer        data;
 
-	PixbufOpFunc    init_func;
-	PixbufOpFunc    step_func;
-	PixbufDoneFunc  release_func;
-	PixbufOpFunc    free_data_func;
+	GdkPixbuf      *src;
+	GdkPixbuf      *dest;
 
 	gboolean        has_alpha;
 	int             bytes_per_pixel;
@@ -72,17 +70,10 @@ struct _GthPixbufTask {
 	int             line;
 	int             line_step;
 	int             column;
-	gboolean        interrupt;
-	const char     *description;
-
-	/*< private >*/
-
-	GMutex         *data_mutex;
-	guint           progress_event;
 };
 
 struct _GthPixbufTaskClass {
-	GthTaskClass __parent;
+	GthAsyncTaskClass __parent;
 };
 
 GType         gth_pixbuf_task_get_type        (void);
@@ -91,7 +82,7 @@ GthTask *     gth_pixbuf_task_new             (const char     *description,
 					       GdkPixbuf      *dest,
 					       PixbufOpFunc    init_func,
 					       PixbufOpFunc    step_func,
-					       PixbufDoneFunc  release_func,
+					       PixbufDataFunc  release_func,
 					       gpointer        data);
 void          gth_pixbuf_task_set_pixbufs     (GthPixbufTask  *pixbuf_task,
 					       GdkPixbuf      *src,
@@ -99,4 +90,4 @@ void          gth_pixbuf_task_set_pixbufs     (GthPixbufTask  *pixbuf_task,
 
 G_END_DECLS
 
-#endif /* _GTH_PIXBUF_TASK_H */
+#endif /* GTH_PIXBUF_TASK_H */
diff --git a/gthumb/gth-thumb-loader.c b/gthumb/gth-thumb-loader.c
index 1525f2f..206889b 100644
--- a/gthumb/gth-thumb-loader.c
+++ b/gthumb/gth-thumb-loader.c
@@ -729,13 +729,13 @@ gth_thumb_loader_load__step2 (GthThumbLoader *tloader)
 void
 gth_thumb_loader_load (GthThumbLoader *tloader)
 {
-	gth_thumb_loader_cancel (tloader, (DoneFunc) gth_thumb_loader_load__step2, tloader);
+	gth_thumb_loader_cancel (tloader, (DataFunc) gth_thumb_loader_load__step2, tloader);
 }
 
 
 void
 gth_thumb_loader_cancel (GthThumbLoader *tloader,
-			 DoneFunc        done_func,
+			 DataFunc        done_func,
 			 gpointer        done_func_data)
 {
 	g_return_if_fail (tloader->priv->iloader != NULL);
diff --git a/gthumb/gth-thumb-loader.h b/gthumb/gth-thumb-loader.h
index 7842499..cfc6206 100644
--- a/gthumb/gth-thumb-loader.h
+++ b/gthumb/gth-thumb-loader.h
@@ -78,7 +78,7 @@ void             gth_thumb_loader_set_uri            (GthThumbLoader *tl,
 GdkPixbuf *      gth_thumb_loader_get_pixbuf         (GthThumbLoader *tl);
 void             gth_thumb_loader_load               (GthThumbLoader *tl);
 void             gth_thumb_loader_cancel             (GthThumbLoader *tl,
-					              DoneFunc        func,
+					              DataFunc        func,
 					              gpointer        data);
 
 G_END_DECLS
diff --git a/gthumb/typedefs.h b/gthumb/typedefs.h
index 1a30ca9..65c8594 100644
--- a/gthumb/typedefs.h
+++ b/gthumb/typedefs.h
@@ -87,8 +87,7 @@ typedef enum {
 } GthTransform;
 
 
-typedef void (*ErrorFunc)        (gpointer    user_data);
-typedef void (*DoneFunc)         (gpointer    user_data);
+typedef void (*DataFunc)         (gpointer    user_data);
 typedef void (*ReadyFunc)        (GError     *error,
 			 	  gpointer    user_data);
 typedef void (*ReadyCallback)    (GObject    *object,



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