[anjuta/libgit2-glib: 1/5] libanjuta: Implement AnjutaTask



commit b8dc3431d2f2d0d87628cb45afbf1a042ff578aa
Author: James Liggett <jrliggett cox net>
Date:   Wed Jun 26 17:25:19 2013 -0700

    libanjuta: Implement AnjutaTask
    
    AnjutaTask is designed to be a replacement for AnjutaCommand, offering these
    improvements:
    
    * The name AnjutaTask better reflects that not code that uses AnjutaCommand
       always use it to implement commands. Some use it just for data processing
       tasks.
    
    * Error messages and return codes are not handled in the base class, but are
       instead left to subclasses to let implementers decide how to handle errors
       and success and failure conditions

 libanjuta/Makefile.am   |    4 +-
 libanjuta/anjuta-task.c |  348 +++++++++++++++++++++++++++++++++++++++++++++++
 libanjuta/anjuta-task.h |   86 ++++++++++++
 3 files changed, 437 insertions(+), 1 deletions(-)
---
diff --git a/libanjuta/Makefile.am b/libanjuta/Makefile.am
index 4ac227e..aa90ecf 100644
--- a/libanjuta/Makefile.am
+++ b/libanjuta/Makefile.am
@@ -138,7 +138,9 @@ libanjuta_3_la_SOURCES= \
        anjuta-close-button.c \
        anjuta-close-button.h \
        anjuta-modeline.c \
-       anjuta-modeline.h
+       anjuta-modeline.h \
+       anjuta-task.c \
+       anjuta-task.h
 
 # Glade module
 if ENABLE_GLADE_CATALOG
diff --git a/libanjuta/anjuta-task.c b/libanjuta/anjuta-task.c
new file mode 100644
index 0000000..ada1859
--- /dev/null
+++ b/libanjuta/anjuta-task.c
@@ -0,0 +1,348 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ * 
+ * anjuta is free software.
+ * 
+ * You may 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.
+ * 
+ * anjuta 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 anjuta.  If not, write to:
+ *     The Free Software Foundation, Inc.,
+ *     51 Franklin Street, Fifth Floor
+ *     Boston, MA  02110-1301, USA.
+ */
+
+#include "anjuta-task.h"
+
+/**
+ * SECTION: anjuta-task
+ * @short_description: System for creating objects that provide a standard 
+ *                                        interface to external components (libraries, processes,
+ *                                        etc.) 
+ * @see_also: #AnjutaAsyncTask
+ * @include libanjuta/anjuta-task.h
+ *
+ * #AnjutaTask is the base class for objects that are designed to provide 
+ * a layer of abstraction between UI code and some other component, like a 
+ * library or child process. AnjutaTask provides a simple and consistent
+ * interface for plugins to interact with these components without needing 
+ * to concern themselves with the exact details of how these components work.
+ * 
+ * To create task objects, plugins derive them from an #AnjutaTask 
+ * subclass like #AnjutaAsyncTask, which runs tasks in another thread or 
+ * #AnjutaSyncTask, which runs tasks synchronously.
+ *
+ * These classes determine how ::run is called and how signals are emitted.
+ * ::run is responsible for actually doing the work of the task. It is the 
+ * responsiblity of the task object that does a certain task to implement 
+ * ::run to do its job. Everything else is normally implemented by its parent
+ * classes at this point
+ *
+ * For an example of how to use #AnjutaTask, see the Git plugin.
+ */
+
+struct _AnjutaTaskPriv
+{
+       gboolean running;
+};
+
+enum
+{
+       DATA_ARRIVED,
+       STARTED,
+       FINISHED,
+       PROGRESS,
+
+       LAST_SIGNAL
+};
+
+
+static guint anjuta_task_signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (AnjutaTask, anjuta_task, G_TYPE_OBJECT);
+
+static void
+anjuta_task_init (AnjutaTask *self)
+{
+       self->priv = g_new0 (AnjutaTaskPriv, 1);
+}
+
+static void
+anjuta_task_finalize (GObject *object)
+{
+       AnjutaTask *self;
+       
+       self = ANJUTA_TASK (object);
+       
+       g_free (self->priv);
+
+       G_OBJECT_CLASS (anjuta_task_parent_class)->finalize (object);
+}
+
+static gboolean
+start_automatic_monitor (AnjutaTask *self)
+{
+       return FALSE;
+}
+
+static void
+stop_automatic_monitor (AnjutaTask *self)
+{
+}
+
+static void
+data_arrived (AnjutaTask *task)
+{
+}
+
+static void
+started (AnjutaTask *task)
+{
+       task->priv->running = TRUE;
+}
+
+static void
+finished (AnjutaTask *task)
+{
+       task->priv->running = FALSE;
+}
+
+static void
+progress (AnjutaTask *task, gfloat progress)
+{
+}
+
+static void
+anjuta_task_class_init (AnjutaTaskClass *klass)
+{
+       GObjectClass* object_class = G_OBJECT_CLASS (klass);
+
+       object_class->finalize = anjuta_task_finalize;
+       
+       klass->run = NULL;
+       klass->start = NULL;
+       klass->cancel = NULL;
+       klass->notify_data_arrived = NULL;
+       klass->notify_finished = NULL;
+       klass->notify_progress = NULL;
+       klass->start_automatic_monitor = start_automatic_monitor;
+       klass->stop_automatic_monitor = stop_automatic_monitor;
+       klass->data_arrived = data_arrived;
+       klass->started = started;
+       klass->finished = finished;
+       klass->progress = progress;
+
+       /**
+        * AnjutaTask::data-arrived:
+        * @task: Task
+        * 
+        * Notifies clients that the task has processed data that is ready to 
+        * be used.
+        */
+       anjuta_task_signals[DATA_ARRIVED] =
+               g_signal_new ("data-arrived",
+                             G_OBJECT_CLASS_TYPE (klass),
+                             G_SIGNAL_RUN_LAST,
+                             G_STRUCT_OFFSET (AnjutaTaskClass, data_arrived),
+                             NULL, NULL,
+                             g_cclosure_marshal_VOID__VOID,
+                             G_TYPE_NONE, 
+                                         0);
+
+       /**
+        * AnjuaTask::started:
+        * @task: Task
+        *
+        * Indicates that a task has begun executing. This signal is intended to 
+        * be used for tasks that start themselves automatically.
+        *
+        * <note>
+        *  <para>
+        *        Sublasses that override the method for this signal should chain up to
+        *        the parent implementation to ensure proper handling of running/not 
+        *        running states. 
+        *      </para>
+        * </note>
+        */
+       anjuta_task_signals[STARTED] =
+               g_signal_new ("started",
+                             G_OBJECT_CLASS_TYPE (klass),
+                             G_SIGNAL_RUN_FIRST,
+                             G_STRUCT_OFFSET (AnjutaTaskClass, started),
+                             NULL, NULL,
+                             g_cclosure_marshal_VOID__VOID,
+                             G_TYPE_NONE, 
+                             0);
+
+       /**
+        * AnjutaTask::finished:
+        * @task: Task
+        * @return_code: The return code of the finished commmand
+        *
+        * Indicates that the task has completed. Clients should at least handle
+        * this signal to unref the task object.
+        *
+        * <note>
+        *  <para>
+        *        Sublasses that override the method for this signal should chain up to
+        *        the parent implementation to ensure proper handling of running/not 
+        *        running states. 
+        *      </para>
+        * </note>
+        */
+       anjuta_task_signals[FINISHED] =
+               g_signal_new ("finished",
+                             G_OBJECT_CLASS_TYPE (klass),
+                             G_SIGNAL_RUN_FIRST,
+                             G_STRUCT_OFFSET (AnjutaTaskClass, finished),
+                             NULL, NULL,
+                             g_cclosure_marshal_VOID__VOID ,
+                             G_TYPE_NONE, 1,
+                             G_TYPE_UINT);
+       
+       
+       /**
+        * AnjutaTask::progress:
+        * @task: Task
+        * @progress: Fraction of the task's task that is complete, between 0.0
+        *                        and 1.0, inclusive.
+        *
+        * Notifies clients of changes in progress during task execution. 
+        */
+       anjuta_task_signals[PROGRESS] =
+               g_signal_new ("progress",
+                             G_OBJECT_CLASS_TYPE (klass),
+                             G_SIGNAL_RUN_FIRST,
+                             G_STRUCT_OFFSET (AnjutaTaskClass, progress),
+                             NULL, NULL,
+                             g_cclosure_marshal_VOID__FLOAT,
+                             G_TYPE_NONE, 1,
+                             G_TYPE_FLOAT);
+}
+
+/**
+ * anjuta_task_start:
+ * @self: Task object to start
+ *
+ * Starts a task. Client code can handle data from the task by connecting
+ * to the ::data-arrived signal. 
+ *
+ * #AnjutaTask subclasses should override this method to determine how they
+ * call ::run, which actually does the task's legwork. 
+ */
+void
+anjuta_task_start (AnjutaTask *self)
+{
+       if (!self->priv->running)
+       {
+               g_signal_emit_by_name (self, "task-started");
+
+               ANJUTA_TASK_GET_CLASS (self)->start (self);
+       }
+}
+
+/**
+ * anjuta_task_cancel:
+ * @self: Task object.
+ *
+ * Cancels a running task.
+ */
+void
+anjuta_task_cancel (AnjutaTask *self)
+{
+       ANJUTA_TASK_GET_CLASS (self)->cancel (self);
+}
+
+/**
+ * anjuta_task_notify_data_arrived:
+ * @self: Task object.
+ * 
+ * Used by base classes derived from #AnjutaTask to emit the ::data-arrived
+ * signal. This method should be used by both base task classes and
+ * non-base classes as appropriate. 
+ */
+void
+anjuta_task_notify_data_arrived (AnjutaTask *self)
+{
+       ANJUTA_TASK_GET_CLASS (self)->notify_data_arrived (self);
+}
+
+/**
+ * anjuta_task_notify_finished:
+ * @self: Task object
+ * 
+ * Used by base classes derived from #AnjutaTask to emit the 
+ * ::task-finished signal. This method should not be used by client code or  
+ * #AnjutaTask objects that are not base classes. 
+ */
+void
+anjuta_task_notify_finished (AnjutaTask *self)
+{
+       ANJUTA_TASK_GET_CLASS (self)->notify_finished (self);
+}
+
+/**
+ * anjuta_task_notify_progress:
+ * @self: Task object.
+ * @progress: The of the task that is passed to the notify callback
+ * 
+ * Emits the ::progress signal. Can be used by both base classes and 
+ * tasks as needed. 
+ */
+void 
+anjuta_task_notify_progress (AnjutaTask *self, gfloat progress)
+{
+       ANJUTA_TASK_GET_CLASS (self)->notify_progress (self, progress);
+}
+
+/**
+ * anjuta_task_is_running:
+ * @self: Task object.
+ *
+ * Return value: %TRUE if the task is currently running; %FALSE otherwise.
+ */
+gboolean
+anjuta_task_is_running (AnjutaTask *self)
+{
+       return self->priv->running;
+}
+
+/**
+ * anjuta_task_start_automatic_monitor:
+ * @self: Task object.
+ *
+ * Sets up any monitoring needed for tasks that should start themselves 
+ * automatically in response to some event. 
+ *
+ * Return value: %TRUE if automatic starting is supported by the task and 
+ * no errors were encountered; %FALSE if automatic starting is unsupported or on
+ * error.
+ */
+gboolean
+anjuta_task_start_automatic_monitor (AnjutaTask *self)
+{
+       return ANJUTA_TASK_GET_CLASS (self)->start_automatic_monitor (self);
+}
+
+/**
+ * anjuta_task_stop_automatic_monitor:
+ * @self: Task object.
+ *
+ * Stops automatic monitoring for self executing tasks. For tasks that 
+ * do not support self-starting, this function does nothing.
+ */
+void
+anjuta_task_stop_automatic_monitor (AnjutaTask *self)
+{
+       ANJUTA_TASK_GET_CLASS (self)->stop_automatic_monitor (self);
+}
diff --git a/libanjuta/anjuta-task.h b/libanjuta/anjuta-task.h
new file mode 100644
index 0000000..aa37597
--- /dev/null
+++ b/libanjuta/anjuta-task.h
@@ -0,0 +1,86 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * anjuta
+ * Copyright (C) James Liggett 2007 <jrliggett cox net>
+ * 
+ * anjuta is free software.
+ * 
+ * You may 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.
+ * 
+ * anjuta 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 anjuta.  If not, write to:
+ *     The Free Software Foundation, Inc.,
+ *     51 Franklin Street, Fifth Floor
+ *     Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _ANJUTA_TASK_H_
+#define _ANJUTA_TASK_H_
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define ANJUTA_TYPE_TASK             (anjuta_task_get_type ())
+#define ANJUTA_TASK(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), ANJUTA_TYPE_TASK, AnjutaTask))
+#define ANJUTA_TASK_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), ANJUTA_TYPE_TASK, AnjutaTaskClass))
+#define ANJUTA_IS_TASK(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ANJUTA_TYPE_TASK))
+#define ANJUTA_IS_TASK_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), ANJUTA_TYPE_TASK))
+#define ANJUTA_TASK_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), ANJUTA_TYPE_TASK, AnjutaTaskClass))
+
+typedef struct _AnjutaTaskClass AnjutaTaskClass;
+typedef struct _AnjutaTask AnjutaTask;
+typedef struct _AnjutaTaskPriv AnjutaTaskPriv;
+
+struct _AnjutaTaskClass
+{
+       GObjectClass parent_class;
+       
+       /* Virtual Methods */
+       guint (*run) (AnjutaTask *self);
+       void (*start) (AnjutaTask *self);
+       void (*cancel) (AnjutaTask *self);
+       void (*notify_data_arrived) (AnjutaTask *self);
+       void (*notify_finished) (AnjutaTask *self);
+       void (*notify_progress) (AnjutaTask *self, gfloat progress);
+       gboolean (*start_automatic_monitor) (AnjutaTask *self);
+       void (*stop_automatic_monitor) (AnjutaTask *self);
+       
+       /* Signals */
+       void (*data_arrived) (AnjutaTask *task);
+       void (*started) (AnjutaTask *task);
+       void (*finished) (AnjutaTask *task);
+       void (*progress) (AnjutaTask *task, gfloat progress);
+
+};
+
+struct _AnjutaTask
+{
+       GObject parent_instance;
+       
+       AnjutaTaskPriv *priv;
+};
+
+GType anjuta_task_get_type (void) G_GNUC_CONST;
+
+void anjuta_task_start (AnjutaTask *self);
+void anjuta_task_cancel (AnjutaTask *self);
+void anjuta_task_notify_data_arrived (AnjutaTask *self);
+void anjuta_task_notify_finished (AnjutaTask *self);
+void anjuta_task_notify_progress (AnjutaTask *self, gfloat progress);
+gboolean anjuta_task_is_running (AnjutaTask *self);
+
+gboolean anjuta_task_start_automatic_monitor (AnjutaTask *self);
+void anjuta_task_stop_automatic_monitor (AnjutaTask *self);
+
+G_END_DECLS
+
+#endif /* _ANJUTA_TASK_H_ */


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