[gnome-builder/wip/libide: 208/237] libide: add IdeScriptManager to manage startup scripts



commit b226f9de22f1e6d8fead23e61727b6e7cf064cba
Author: Christian Hergert <christian hergert me>
Date:   Sun Feb 15 22:20:03 2015 -0800

    libide: add IdeScriptManager to manage startup scripts

 libide/Makefile.am          |    2 +
 libide/ide-context.c        |   60 ++++++++
 libide/ide-script-manager.c |  342 +++++++++++++++++++++++++++++++++++++++++++
 libide/ide-script-manager.h |   41 +++++
 libide/ide-script.c         |  170 ++++++++++++++++++++-
 libide/ide-script.h         |   12 +-
 libide/ide-types.h          |    2 +
 libide/ide.c                |    1 +
 libide/ide.h                |    1 +
 9 files changed, 617 insertions(+), 14 deletions(-)
---
diff --git a/libide/Makefile.am b/libide/Makefile.am
index 4c72e5b..82e8eff 100644
--- a/libide/Makefile.am
+++ b/libide/Makefile.am
@@ -99,6 +99,8 @@ libide_1_0_la_public_sources = \
        libide/ide-refactory.h \
        libide/ide-script.c \
        libide/ide-script.h \
+       libide/ide-script-manager.c \
+       libide/ide-script-manager.h \
        libide/ide-search-context.c \
        libide/ide-search-context.h \
        libide/ide-search-engine.c \
diff --git a/libide/ide-context.c b/libide/ide-context.c
index 78d5306..1908576 100644
--- a/libide/ide-context.c
+++ b/libide/ide-context.c
@@ -28,6 +28,7 @@
 #include "ide-global.h"
 #include "ide-internal.h"
 #include "ide-project.h"
+#include "ide-script-manager.h"
 #include "ide-service.h"
 #include "ide-unsaved-files.h"
 #include "ide-vcs.h"
@@ -37,6 +38,7 @@ typedef struct
   IdeBackForwardList *back_forward_list;
   IdeBuildSystem     *build_system;
   IdeDeviceManager   *device_manager;
+  IdeScriptManager   *script_manager;
   IdeProject         *project;
   GFile              *project_file;
   gchar              *root_build_dir;
@@ -253,6 +255,12 @@ ide_context_new_async (GFile               *project_file,
   g_object_unref (task);
 }
 
+/**
+ * ide_context_new_finish:
+ *
+ * Returns: (transfer full): An #IdeContext or %NULL upon failure and
+ *   @error is set.
+ */
 IdeContext *
 ide_context_new_finish (GAsyncResult  *result,
                         GError       **error)
@@ -575,6 +583,7 @@ static void
 ide_context_init (IdeContext *self)
 {
   IdeContextPrivate *priv = ide_context_get_instance_private (self);
+  g_autoptr(gchar) scriptsdir = NULL;
 
   priv->root_build_dir = g_build_filename (g_get_user_cache_dir (),
                                            ide_get_program_name (),
@@ -601,6 +610,15 @@ ide_context_init (IdeContext *self)
   priv->unsaved_files = g_object_new (IDE_TYPE_UNSAVED_FILES,
                                       "context", self,
                                       NULL);
+
+  scriptsdir = g_build_filename (g_get_user_config_dir (),
+                                 ide_get_program_name (),
+                                 "scripts",
+                                 NULL);
+  priv->script_manager = g_object_new (IDE_TYPE_SCRIPT_MANAGER,
+                                       "context", self,
+                                       "scripts-directory", scriptsdir,
+                                       NULL);
 }
 
 static void
@@ -804,6 +822,47 @@ ide_context_init_unsaved_files (gpointer             source_object,
 }
 
 static void
+ide_context_init_scripts_cb (GObject      *object,
+                             GAsyncResult *result,
+                             gpointer      user_data)
+{
+  IdeScriptManager *manager = (IdeScriptManager *)object;
+  g_autoptr(GTask) task = user_data;
+  GError *error = NULL;
+
+  g_assert (IDE_IS_SCRIPT_MANAGER (manager));
+  g_assert (G_IS_TASK (task));
+
+  if (!ide_script_manager_load_finish (manager, result, &error))
+    {
+      g_task_return_error (task, error);
+      return;
+    }
+
+  g_task_return_boolean (task, TRUE);
+}
+
+static void
+ide_context_init_scripts (gpointer             source_object,
+                          GCancellable        *cancellable,
+                          GAsyncReadyCallback  callback,
+                          gpointer             user_data)
+{
+  IdeContext *self = source_object;
+  IdeContextPrivate *priv = ide_context_get_instance_private (self);
+  g_autoptr(GTask) task = NULL;
+
+  g_return_if_fail (IDE_IS_CONTEXT (self));
+  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  task = g_task_new (self, cancellable, callback, user_data);
+  ide_script_manager_load_async (priv->script_manager,
+                                 cancellable,
+                                 ide_context_init_scripts_cb,
+                                 g_object_ref (task));
+}
+
+static void
 ide_context_init_back_forward_list (gpointer             source_object,
                                     GCancellable        *cancellable,
                                     GAsyncReadyCallback  callback,
@@ -905,6 +964,7 @@ ide_context_init_async (GAsyncInitable      *initable,
                         ide_context_init_project_name,
                         ide_context_init_back_forward_list,
                         ide_context_init_unsaved_files,
+                        ide_context_init_scripts,
                         NULL);
 }
 
diff --git a/libide/ide-script-manager.c b/libide/ide-script-manager.c
new file mode 100644
index 0000000..4d8262c
--- /dev/null
+++ b/libide/ide-script-manager.c
@@ -0,0 +1,342 @@
+/* ide-script-manager.c
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This file 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <glib/gi18n.h>
+#include <girepository.h>
+
+#include "ide-script.h"
+#include "ide-script-manager.h"
+
+struct _IdeScriptManager
+{
+  IdeObject  parent_instance;
+  gchar     *scripts_directory;
+  GList     *scripts;
+};
+
+typedef struct
+{
+  gint ref_count;
+} LoadState;
+
+G_DEFINE_TYPE (IdeScriptManager, ide_script_manager, IDE_TYPE_OBJECT)
+
+enum {
+  PROP_0,
+  PROP_SCRIPTS_DIRECTORY,
+  LAST_PROP
+};
+
+static GParamSpec *gParamSpecs [LAST_PROP];
+
+const gchar *
+ide_script_manager_get_scripts_directory (IdeScriptManager *self)
+{
+  g_return_val_if_fail (IDE_IS_SCRIPT_MANAGER (self), NULL);
+
+  return self->scripts_directory;
+}
+
+static void
+ide_script_manager_set_scripts_directory (IdeScriptManager *self,
+                                          const gchar      *scripts_directory)
+{
+  g_return_if_fail (IDE_IS_SCRIPT_MANAGER (self));
+  g_return_if_fail (!self->scripts_directory);
+
+  self->scripts_directory = g_strdup (scripts_directory);
+}
+
+static void
+ide_script_manager_finalize (GObject *object)
+{
+  IdeScriptManager *self = (IdeScriptManager *)object;
+
+  g_clear_pointer (&self->scripts_directory, g_free);
+
+  g_list_foreach (self->scripts, (GFunc)g_object_unref, NULL);
+  g_list_free (self->scripts);
+  self->scripts = NULL;
+
+  G_OBJECT_CLASS (ide_script_manager_parent_class)->finalize (object);
+}
+
+static void
+ide_script_manager_get_property (GObject    *object,
+                                 guint       prop_id,
+                                 GValue     *value,
+                                 GParamSpec *pspec)
+{
+  IdeScriptManager *self = IDE_SCRIPT_MANAGER (object);
+
+  switch (prop_id)
+    {
+    case PROP_SCRIPTS_DIRECTORY:
+      g_value_set_string (value, ide_script_manager_get_scripts_directory (self));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_script_manager_set_property (GObject      *object,
+                                 guint         prop_id,
+                                 const GValue *value,
+                                 GParamSpec   *pspec)
+{
+  IdeScriptManager *self = IDE_SCRIPT_MANAGER (object);
+
+  switch (prop_id)
+    {
+    case PROP_SCRIPTS_DIRECTORY:
+      ide_script_manager_set_scripts_directory (self, g_value_get_string (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+    }
+}
+
+static void
+ide_script_manager_class_init (IdeScriptManagerClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = ide_script_manager_finalize;
+  object_class->get_property = ide_script_manager_get_property;
+  object_class->set_property = ide_script_manager_set_property;
+
+  gParamSpecs [PROP_SCRIPTS_DIRECTORY] =
+    g_param_spec_string ("scripts-directory",
+                         _("Scripts Directory"),
+                         _("The local path to the directory containing scripts."),
+                         NULL,
+                         (G_PARAM_READWRITE |
+                          G_PARAM_CONSTRUCT_ONLY |
+                          G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (object_class, PROP_SCRIPTS_DIRECTORY,
+                                   gParamSpecs [PROP_SCRIPTS_DIRECTORY]);
+}
+
+static void
+ide_script_manager_init (IdeScriptManager *self)
+{
+}
+
+static void
+ide_script_manager_get_files_worker (GTask        *task,
+                                     gpointer      source_object,
+                                     gpointer      task_data,
+                                     GCancellable *cancellable)
+{
+  IdeScriptManager *self = source_object;
+  gchar *directory = task_data;
+  const gchar *name;
+  GPtrArray *ar;
+  GError *error = NULL;
+  GDir *dir;
+
+  g_assert (IDE_IS_SCRIPT_MANAGER (self));
+  g_assert (directory);
+
+  dir = g_dir_open (directory, 0, &error);
+
+  if (!dir)
+    {
+      g_task_return_error (task, error);
+      return;
+    }
+
+  ar = g_ptr_array_new_with_free_func (g_object_unref);
+
+  while ((name = g_dir_read_name (dir)))
+    {
+      g_autoptr(gchar) path = NULL;
+      g_autoptr(GFile) file = NULL;
+
+      path = g_build_filename (directory, name, NULL);
+      file = g_file_new_for_path (path);
+
+      g_ptr_array_add (ar, g_object_ref (file));
+    }
+
+  g_dir_close (dir);
+
+  g_task_return_pointer (task, ar, (GDestroyNotify)g_ptr_array_unref);
+}
+
+static void
+ide_script_manager_get_files_async (IdeScriptManager    *self,
+                                    GCancellable        *cancellable,
+                                    GAsyncReadyCallback  callback,
+                                    gpointer             user_data)
+{
+  g_autoptr(GTask) task = NULL;
+
+  g_return_if_fail (IDE_IS_SCRIPT_MANAGER (self));
+  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  task = g_task_new (self, cancellable, callback, user_data);
+  g_task_set_task_data (task, g_strdup (self->scripts_directory), g_free);
+  g_task_run_in_thread (task, ide_script_manager_get_files_worker);
+}
+
+static GPtrArray *
+ide_script_manager_get_files_finish (IdeScriptManager  *self,
+                                     GAsyncResult      *result,
+                                     GError           **error)
+{
+  GTask *task = (GTask *)result;
+
+  g_assert (IDE_IS_SCRIPT_MANAGER (self));
+  g_assert (G_IS_TASK (task));
+
+  return g_task_propagate_pointer (task, error);
+}
+
+static void
+ide_script_manager_new_script_cb (GObject      *object,
+                                  GAsyncResult *result,
+                                  gpointer      user_data)
+{
+  IdeScriptManager *self;
+  g_autoptr(GTask) task = user_data;
+  g_autoptr(IdeObject) res = NULL;
+  g_autoptr(GError) error = NULL;
+  LoadState *state;
+
+  g_assert (G_IS_TASK (task));
+
+  self = g_task_get_source_object (task);
+  state = g_task_get_task_data (task);
+
+  res = ide_object_new_finish (result, &error);
+
+  if (!res)
+    g_warning ("%s", error->message);
+
+  if (--state->ref_count == 0)
+    g_task_return_boolean (task, TRUE);
+
+  self->scripts = g_list_prepend (self->scripts, g_object_ref (res));
+}
+
+static void
+ide_script_manager_load_cb (GObject      *object,
+                            GAsyncResult *result,
+                            gpointer      user_data)
+{
+  IdeScriptManager *self = (IdeScriptManager *)object;
+  IdeContext *context;
+  g_autoptr(GTask) task = user_data;
+  LoadState *state;
+  GPtrArray *ar;
+  GError *error = NULL;
+  gsize i;
+
+  g_assert (IDE_IS_SCRIPT_MANAGER (self));
+  g_assert (G_IS_TASK (task));
+
+  context = ide_object_get_context (IDE_OBJECT (self));
+
+  ar = ide_script_manager_get_files_finish (self, result, &error);
+
+  if (!ar)
+    {
+      if (g_error_matches (error, G_FILE_ERROR, G_FILE_ERROR_NOENT))
+        g_task_return_boolean (task, TRUE);
+      else
+        g_task_return_error (task, error);
+      return;
+    }
+
+  state = g_new0 (LoadState, 1);
+  state->ref_count = ar->len;
+  g_task_set_task_data (task, state, g_free);
+
+  if (!ar->len)
+    {
+      g_task_return_boolean (task, TRUE);
+      g_ptr_array_unref (ar);
+      return;
+    }
+
+  for (i = 0; i < ar->len; i++)
+    {
+      GFile *file;
+
+      file = g_ptr_array_index (ar, i);
+
+      ide_object_new_async (IDE_SCRIPT_EXTENSION_POINT,
+                            G_PRIORITY_DEFAULT,
+                            g_task_get_cancellable (task),
+                            ide_script_manager_new_script_cb,
+                            g_object_ref (task),
+                            "context", context,
+                            "file", file,
+                            NULL);
+    }
+
+  g_ptr_array_unref (ar);
+}
+
+void
+ide_script_manager_load_async  (IdeScriptManager    *self,
+                                GCancellable        *cancellable,
+                                GAsyncReadyCallback  callback,
+                                gpointer             user_data)
+{
+  g_autoptr(GTask) task = NULL;
+  GIRepository *repository;
+  GITypelib *typelib;
+  GError *error = NULL;
+
+  g_return_if_fail (IDE_IS_SCRIPT_MANAGER (self));
+  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  task = g_task_new (self, cancellable, callback, user_data);
+
+  repository = g_irepository_get_default ();
+  typelib = g_irepository_require (repository, "Ide", NULL, 0, &error);
+
+  if (!typelib)
+    {
+      g_task_return_error (task, error);
+      return;
+    }
+
+  ide_script_manager_get_files_async (self,
+                                      cancellable,
+                                      ide_script_manager_load_cb,
+                                      g_object_ref (task));
+}
+
+gboolean
+ide_script_manager_load_finish (IdeScriptManager  *self,
+                                GAsyncResult      *result,
+                                GError           **error)
+{
+  GTask *task = (GTask *)result;
+
+  g_return_val_if_fail (IDE_IS_SCRIPT_MANAGER (self), FALSE);
+  g_return_val_if_fail (G_IS_TASK (task), FALSE);
+
+  return g_task_propagate_boolean (task, error);
+}
diff --git a/libide/ide-script-manager.h b/libide/ide-script-manager.h
new file mode 100644
index 0000000..85d2205
--- /dev/null
+++ b/libide/ide-script-manager.h
@@ -0,0 +1,41 @@
+/* ide-script-manager.h
+ *
+ * Copyright (C) 2015 Christian Hergert <christian hergert me>
+ *
+ * This file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This file 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef IDE_SCRIPT_MANAGER_H
+#define IDE_SCRIPT_MANAGER_H
+
+#include "ide-object.h"
+
+G_BEGIN_DECLS
+
+#define IDE_TYPE_SCRIPT_MANAGER (ide_script_manager_get_type())
+
+G_DECLARE_FINAL_TYPE (IdeScriptManager, ide_script_manager, IDE, SCRIPT_MANAGER, IdeObject)
+
+const gchar *ide_script_manager_get_scripts_directory (IdeScriptManager *self);
+void         ide_script_manager_load_async            (IdeScriptManager    *self,
+                                                       GCancellable        *cancellable,
+                                                       GAsyncReadyCallback  callback,
+                                                       gpointer             user_data);
+gboolean     ide_script_manager_load_finish           (IdeScriptManager  *self,
+                                                       GAsyncResult      *result,
+                                                       GError           **error);
+
+G_END_DECLS
+
+#endif /* IDE_SCRIPT_MANAGER_H */
diff --git a/libide/ide-script.c b/libide/ide-script.c
index 657ad31..1a5bc84 100644
--- a/libide/ide-script.c
+++ b/libide/ide-script.c
@@ -6,7 +6,7 @@
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
- * 
+ *
  * This file 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
@@ -20,7 +20,23 @@
 
 #include "ide-script.h"
 
-G_DEFINE_ABSTRACT_TYPE (IdeScript, ide_script, IDE_TYPE_OBJECT)
+typedef struct
+{
+  GFile *file;
+} IdeScriptPrivate;
+
+static void async_initable_iface_init (GAsyncInitableIface *iface);
+
+G_DEFINE_ABSTRACT_TYPE_WITH_CODE (IdeScript, ide_script, IDE_TYPE_OBJECT,
+                                  G_ADD_PRIVATE (IdeScript)
+                                  G_IMPLEMENT_INTERFACE (G_TYPE_ASYNC_INITABLE,
+                                                         async_initable_iface_init))
+
+enum {
+  PROP_0,
+  PROP_FILE,
+  LAST_PROP
+};
 
 enum {
   LOAD,
@@ -28,27 +44,124 @@ enum {
   LAST_SIGNAL
 };
 
-static guint gSignals [LAST_SIGNAL];
+static GParamSpec *gParamSpecs [LAST_PROP];
+static guint       gSignals [LAST_SIGNAL];
+
+/**
+ * ide_script_get_file:
+ *
+ * Returns a #GFile pointing to the location of the script on disk.
+ *
+ * Returns: (transfer none): A #GFile
+ */
+GFile *
+ide_script_get_file (IdeScript *self)
+{
+  IdeScriptPrivate *priv = ide_script_get_instance_private (self);
+
+  g_return_val_if_fail (IDE_IS_SCRIPT (self), NULL);
+
+  return priv->file;
+}
+
+static void
+ide_script_set_file (IdeScript *self,
+                     GFile     *file)
+{
+  IdeScriptPrivate *priv = ide_script_get_instance_private (self);
+
+  g_return_if_fail (IDE_IS_SCRIPT (self));
+  g_return_if_fail (G_IS_FILE (file));
+
+  if (g_set_object (&priv->file, file))
+    g_object_notify_by_pspec (G_OBJECT (self), gParamSpecs [PROP_FILE]);
+}
 
 void
-ide_script_load (IdeScript *script)
+ide_script_load (IdeScript *self)
 {
-  g_return_if_fail (IDE_IS_SCRIPT (script));
+  g_return_if_fail (IDE_IS_SCRIPT (self));
 
-  g_signal_emit (script, gSignals [LOAD], 0);
+  g_signal_emit (self, gSignals [LOAD], 0);
 }
 
 void
-ide_script_unload (IdeScript *script)
+ide_script_unload (IdeScript *self)
+{
+  g_return_if_fail (IDE_IS_SCRIPT (self));
+
+  g_signal_emit (self, gSignals [UNLOAD], 0);
+}
+
+static void
+ide_script_finalize (GObject *object)
 {
-  g_return_if_fail (IDE_IS_SCRIPT (script));
+  IdeScript *self = (IdeScript *)object;
+  IdeScriptPrivate *priv = ide_script_get_instance_private (self);
 
-  g_signal_emit (script, gSignals [UNLOAD], 0);
+  g_clear_object (&priv->file);
+
+  G_OBJECT_CLASS (ide_script_parent_class)->finalize (object);
+}
+
+static void
+ide_script_get_property (GObject    *object,
+                         guint       prop_id,
+                         GValue     *value,
+                         GParamSpec *pspec)
+{
+  IdeScript *self = IDE_SCRIPT(object);
+
+  switch (prop_id)
+    {
+    case PROP_FILE:
+      g_value_set_object (value, ide_script_get_file (self));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    }
+}
+
+static void
+ide_script_set_property (GObject      *object,
+                         guint         prop_id,
+                         const GValue *value,
+                         GParamSpec   *pspec)
+{
+  IdeScript *self = IDE_SCRIPT(object);
+
+  switch (prop_id)
+    {
+    case PROP_FILE:
+      ide_script_set_file (self, g_value_get_object (value));
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
+    }
 }
 
 static void
 ide_script_class_init (IdeScriptClass *klass)
 {
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+  object_class->finalize = ide_script_finalize;
+  object_class->get_property = ide_script_get_property;
+  object_class->set_property = ide_script_set_property;
+
+  gParamSpecs [PROP_FILE] =
+    g_param_spec_object ("file",
+                         _("File"),
+                         _("The file containing the script."),
+                         G_TYPE_FILE,
+                         (G_PARAM_READWRITE |
+                          G_PARAM_CONSTRUCT_ONLY |
+                          G_PARAM_STATIC_STRINGS));
+  g_object_class_install_property (object_class, PROP_FILE,
+                                   gParamSpecs [PROP_FILE]);
+
   gSignals [LOAD] =
     g_signal_new ("load",
                   IDE_TYPE_SCRIPT,
@@ -76,3 +189,42 @@ static void
 ide_script_init (IdeScript *self)
 {
 }
+
+static void
+ide_script_init_async (GAsyncInitable      *initable,
+                       gint                 io_priority,
+                       GCancellable        *cancellable,
+                       GAsyncReadyCallback  callback,
+                       gpointer             user_data)
+{
+  g_autoptr(GTask) task = NULL;
+
+  g_return_if_fail (G_IS_ASYNC_INITABLE (initable));
+  g_return_if_fail (!cancellable || G_IS_CANCELLABLE (cancellable));
+
+  task = g_task_new (initable, cancellable, callback, user_data);
+  g_task_return_new_error (task,
+                           G_IO_ERROR,
+                           G_IO_ERROR_NOT_SUPPORTED,
+                           _("%s has not implemented GAsyncInitable."),
+                           g_type_name (G_TYPE_FROM_INSTANCE (initable)));
+}
+
+static gboolean
+ide_script_init_finish (GAsyncInitable  *initable,
+                        GAsyncResult    *result,
+                        GError         **error)
+{
+  GTask *task = (GTask *)result;
+
+  g_return_val_if_fail (G_IS_TASK (task), FALSE);
+
+  return g_task_propagate_boolean (task, error);
+}
+
+static void
+async_initable_iface_init (GAsyncInitableIface *iface)
+{
+  iface->init_async = ide_script_init_async;
+  iface->init_finish = ide_script_init_finish;
+}
diff --git a/libide/ide-script.h b/libide/ide-script.h
index 7da358e..1ec1ce0 100644
--- a/libide/ide-script.h
+++ b/libide/ide-script.h
@@ -23,7 +23,8 @@
 
 G_BEGIN_DECLS
 
-#define IDE_TYPE_SCRIPT (ide_script_get_type())
+#define IDE_TYPE_SCRIPT            (ide_script_get_type())
+#define IDE_SCRIPT_EXTENSION_POINT "org.gnome.libide.extensions.script"
 
 G_DECLARE_DERIVABLE_TYPE (IdeScript, ide_script, IDE, SCRIPT, IdeObject)
 
@@ -31,12 +32,13 @@ struct _IdeScriptClass
 {
   IdeObjectClass parent;
 
-  void (*load)   (IdeScript *script);
-  void (*unload) (IdeScript *script);
+  void (*load)   (IdeScript *self);
+  void (*unload) (IdeScript *self);
 };
 
-void ide_script_load   (IdeScript *script);
-void ide_script_unload (IdeScript *script);
+void   ide_script_load     (IdeScript *self);
+void   ide_script_unload   (IdeScript *self);
+GFile *ide_script_get_file (IdeScript *self);
 
 G_END_DECLS
 
diff --git a/libide/ide-types.h b/libide/ide-types.h
index 036b35b..297d432 100644
--- a/libide/ide-types.h
+++ b/libide/ide-types.h
@@ -94,6 +94,8 @@ typedef struct _IdeRefactoryInterface          IdeRefactoryInterface;
 
 typedef struct _IdeScript                      IdeScript;
 
+typedef struct _IdeScriptManager               IdeScriptManager;
+
 typedef struct _IdeSearchContext               IdeSearchContext;
 
 typedef struct _IdeSearchEngine                IdeSearchEngine;
diff --git a/libide/ide.c b/libide/ide.c
index d56f88e..059d833 100644
--- a/libide/ide.c
+++ b/libide/ide.c
@@ -66,6 +66,7 @@ ide_init_ctor (void)
   g_io_extension_point_register (IDE_BUILD_SYSTEM_EXTENSION_POINT);
   g_io_extension_point_register (IDE_FILE_SETTINGS_EXTENSION_POINT);
   g_io_extension_point_register (IDE_LANGUAGE_EXTENSION_POINT);
+  g_io_extension_point_register (IDE_SCRIPT_EXTENSION_POINT);
   g_io_extension_point_register (IDE_SERVICE_EXTENSION_POINT);
   g_io_extension_point_register (IDE_VCS_EXTENSION_POINT);
 
diff --git a/libide/ide.h b/libide/ide.h
index 7dc3bd7..8e884f5 100644
--- a/libide/ide.h
+++ b/libide/ide.h
@@ -56,6 +56,7 @@ G_BEGIN_DECLS
 #include "ide-project-item.h"
 #include "ide-refactory.h"
 #include "ide-script.h"
+#include "ide-script-manager.h"
 #include "ide-search-context.h"
 #include "ide-search-engine.h"
 #include "ide-search-provider.h"


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