Commit f2778934 authored by Paolo Bacchilega's avatar Paolo Bacchilega
Browse files

refactored the GthPixbufTask class

added a generic GthAsyncTask class, made GthPixbufTask an its
subclass
parent e31546c3
......@@ -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;
......
......@@ -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 \
......
......@@ -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);
......
......@@ -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,
......
/* -*- 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);
}
/* -*- 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 */
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
......@@ -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);
......
......@@ -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;
......
......@@ -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);
......
......@@ -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);
}
......
......@@ -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)