[gnome-builder/wip/libide: 92/237] libide: add IdeUnsavedFile abstraction



commit d642bf1f85cee9314df57f6cbdd3c7c175636bf5
Author: Christian Hergert <christian hergert me>
Date:   Wed Feb 11 17:03:52 2015 -0800

    libide: add IdeUnsavedFile abstraction
    
    This gives us a boxed type for accessing a specific file. It is
    immutable to make it easy to pass to worker threads that need to perform
    work based on the GBytes content. Such an example is clang.
    
    We track sequence numbers so that we can potentially skip work in the
    future if nothing has changed.

 libide/Makefile.am         |    3 +
 libide/ide-private.h       |   39 +++++++++++++++
 libide/ide-types.h         |    3 +
 libide/ide-unsaved-file.c  |  114 ++++++++++++++++++++++++++++++++++++++++++++
 libide/ide-unsaved-file.h  |   37 ++++++++++++++
 libide/ide-unsaved-files.c |   61 +++++++++++++++++++++++
 libide/ide-unsaved-files.h |   40 ++++++++-------
 libide/ide.h               |    1 +
 8 files changed, 279 insertions(+), 19 deletions(-)
---
diff --git a/libide/Makefile.am b/libide/Makefile.am
index adfb3ed..e12e7c5 100644
--- a/libide/Makefile.am
+++ b/libide/Makefile.am
@@ -60,6 +60,7 @@ libide_la_SOURCES = \
        libide/ide-language.h \
        libide/ide-object.c \
        libide/ide-object.h \
+       libide/ide-private.h \
        libide/ide-process.h \
        libide/ide-project-file.c \
        libide/ide-project-file.h \
@@ -85,6 +86,8 @@ libide_la_SOURCES = \
        libide/ide-test-case.h \
        libide/ide-test-suite.h \
        libide/ide-types.h \
+       libide/ide-unsaved-file.c \
+       libide/ide-unsaved-file.h \
        libide/ide-unsaved-files.c \
        libide/ide-unsaved-files.h \
        libide/ide-vcs.c \
diff --git a/libide/ide-private.h b/libide/ide-private.h
new file mode 100644
index 0000000..c7b4a16
--- /dev/null
+++ b/libide/ide-private.h
@@ -0,0 +1,39 @@
+/* ide-private.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_PRIVATE_H
+#define IDE_PRIVATE_H
+
+#include <clang-c/Index.h>
+
+#include "ide-clang-translation-unit.h"
+#include "ide-types.h"
+
+G_BEGIN_DECLS
+
+IdeUnsavedFile *_ide_unsaved_file_new (GFile  *file,
+                                       GBytes *content,
+                                       gint64  sequence);
+
+IdeClangTranslationUnit *_ide_clang_translation_unit_new (IdeContext        *contxt,
+                                                          CXTranslationUnit  tu,
+                                                          gint64             sequence);
+
+G_END_DECLS
+
+#endif /* IDE_PRIVATE_H */
diff --git a/libide/ide-types.h b/libide/ide-types.h
index f84d938..f2379f2 100644
--- a/libide/ide-types.h
+++ b/libide/ide-types.h
@@ -118,6 +118,9 @@ typedef struct _IdeTestSuite                   IdeTestSuite;
 typedef struct _IdeTestSuiteInterface          IdeTestSuiteInterface;
 
 typedef struct _IdeUnsavedFiles                IdeUnsavedFiles;
+
+typedef struct _IdeUnsavedFile                 IdeUnsavedFile;
+
 typedef struct _IdeVcs                         IdeVcs;
 
 G_END_DECLS
diff --git a/libide/ide-unsaved-file.c b/libide/ide-unsaved-file.c
new file mode 100644
index 0000000..3ef1853
--- /dev/null
+++ b/libide/ide-unsaved-file.c
@@ -0,0 +1,114 @@
+/* ide-unsaved-file.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 "ide-unsaved-file.h"
+
+struct _IdeUnsavedFile
+{
+  volatile gint  ref_count;
+  GBytes        *content;
+  GFile         *file;
+  gint64         sequence;
+};
+
+IdeUnsavedFile *
+_ide_unsaved_file_new (GFile  *file,
+                       GBytes *content,
+                       gint64  sequence)
+{
+  IdeUnsavedFile *ret;
+
+  g_return_val_if_fail (G_IS_FILE (file), NULL);
+  g_return_val_if_fail (content, NULL);
+
+  ret = g_slice_new0 (IdeUnsavedFile);
+  ret->ref_count = 1;
+  ret->file = g_object_ref (file);
+  ret->content = g_bytes_ref (content);
+  ret->sequence = sequence;
+
+  return ret;
+}
+
+GType
+ide_unsaved_file_get_type (void)
+{
+  static gsize type_id;
+
+  if (g_once_init_enter (&type_id))
+    {
+      gsize _type_id;
+
+      type_id = g_boxed_type_register_static (
+          "IdeUnsavedFile",
+          (GBoxedCopyFunc)ide_unsaved_file_ref,
+          (GBoxedFreeFunc)ide_unsaved_file_unref);
+      g_once_init_leave (&type_id, _type_id);
+    }
+
+  return type_id;
+}
+
+gint64
+ide_unsaved_file_get_sequence (IdeUnsavedFile *self)
+{
+  g_return_val_if_fail (self, -1);
+
+  return self->sequence;
+}
+
+IdeUnsavedFile *
+ide_unsaved_file_ref (IdeUnsavedFile *self)
+{
+  g_return_val_if_fail (self, NULL);
+  g_return_val_if_fail (self->ref_count > 0, NULL);
+
+  g_atomic_int_inc (&self->ref_count);
+
+  return self;
+}
+
+void
+ide_unsaved_file_unref (IdeUnsavedFile *self)
+{
+  g_return_if_fail (self);
+  g_return_if_fail (self->ref_count > 0);
+
+  if (g_atomic_int_dec_and_test (&self->ref_count))
+    {
+      g_clear_pointer (&self->content, g_bytes_unref);
+      g_clear_object (&self->file);
+      g_slice_free (IdeUnsavedFile, self);
+    }
+}
+
+GBytes *
+ide_unsaved_file_get_content (IdeUnsavedFile *self)
+{
+  g_return_val_if_fail (self, NULL);
+
+  return self->content;
+}
+
+GFile *
+ide_unsaved_file_get_file (IdeUnsavedFile *self)
+{
+  g_return_val_if_fail (self, NULL);
+
+  return self->file;
+}
diff --git a/libide/ide-unsaved-file.h b/libide/ide-unsaved-file.h
new file mode 100644
index 0000000..9593a96
--- /dev/null
+++ b/libide/ide-unsaved-file.h
@@ -0,0 +1,37 @@
+/* ide-unsaved-file.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_UNSAVED_FILE_H
+#define IDE_UNSAVED_FILE_H
+
+#include <gio/gio.h>
+
+#include "ide-types.h"
+
+G_BEGIN_DECLS
+
+GType           ide_unsaved_file_get_type     (void);
+IdeUnsavedFile *ide_unsaved_file_ref          (IdeUnsavedFile *self);
+void            ide_unsaved_file_unref        (IdeUnsavedFile *self);
+GBytes         *ide_unsaved_file_get_content  (IdeUnsavedFile *self);
+GFile          *ide_unsaved_file_get_file     (IdeUnsavedFile *self);
+gint64          ide_unsaved_file_get_sequence (IdeUnsavedFile *file);
+
+G_END_DECLS
+
+#endif /* IDE_UNSAVED_FILE_H */
diff --git a/libide/ide-unsaved-files.c b/libide/ide-unsaved-files.c
index ee682fc..b5dfaa7 100644
--- a/libide/ide-unsaved-files.c
+++ b/libide/ide-unsaved-files.c
@@ -20,11 +20,14 @@
 
 #include "ide-context.h"
 #include "ide-global.h"
+#include "ide-private.h"
 #include "ide-project.h"
+#include "ide-unsaved-file.h"
 #include "ide-unsaved-files.h"
 
 typedef struct
 {
+  gint64  sequence;
   GFile  *file;
   GBytes *content;
 } UnsavedFile;
@@ -32,6 +35,7 @@ typedef struct
 typedef struct
 {
   GPtrArray *unsaved_files;
+  gint64     sequence;
 } IdeUnsavedFilesPrivate;
 
 typedef struct
@@ -408,6 +412,8 @@ ide_unsaved_files_update (IdeUnsavedFiles *self,
   g_return_if_fail (IDE_IS_UNSAVED_FILES (self));
   g_return_if_fail (G_IS_FILE (file));
 
+  priv->sequence++;
+
   if (!content)
     {
       ide_unsaved_files_remove (self, file);
@@ -424,6 +430,7 @@ ide_unsaved_files_update (IdeUnsavedFiles *self,
             {
               g_clear_pointer (&unsaved->content, g_bytes_unref);
               unsaved->content = g_bytes_ref (content);
+              unsaved->sequence = priv->sequence;
             }
 
           /*
@@ -442,10 +449,64 @@ ide_unsaved_files_update (IdeUnsavedFiles *self,
   unsaved = g_slice_new0 (UnsavedFile);
   unsaved->file = g_object_ref (file);
   unsaved->content = g_bytes_ref (content);
+  unsaved->sequence = priv->sequence;
 
   g_ptr_array_insert (priv->unsaved_files, 0, unsaved);
 }
 
+/**
+ * ide_unsaved_files_get_unsaved_files:
+ *
+ * This retrieves all of the unsaved file buffers known to the context.
+ * These are handy if you need to pass modified state to parsers such as
+ * clang.
+ *
+ * Call g_ptr_array_unref() on the resulting #GPtrArray when no longer in use.
+ *
+ * If you would like to hold onto an unsaved file instance, call
+ * ide_unsaved_file_ref() to increment it's reference count.
+ *
+ * Returns: (transfer container) (element-type IdeUnsavedFile*): A #GPtrArray
+ *   containing #IdeUnsavedFile elements.
+ */
+GPtrArray *
+ide_unsaved_files_get_unsaved_files (IdeUnsavedFiles *self)
+{
+  IdeUnsavedFilesPrivate *priv;
+  GPtrArray *ar;
+  gsize i;
+
+  g_return_val_if_fail (IDE_IS_UNSAVED_FILES (self), NULL);
+
+  priv = ide_unsaved_files_get_instance_private (self);
+
+  ar = g_ptr_array_new ();
+  g_ptr_array_set_free_func (ar, (GDestroyNotify)ide_unsaved_file_unref);
+
+  for (i = 0; i < priv->unsaved_files->len; i++)
+    {
+      IdeUnsavedFile *item;
+      UnsavedFile *uf;
+
+      uf = g_ptr_array_index (priv->unsaved_files, i);
+      item = _ide_unsaved_file_new (uf->file, uf->content, uf->sequence);
+
+      g_ptr_array_add (ar, item);
+    }
+
+  return ar;
+}
+
+gint64
+ide_unsaved_files_get_sequence (IdeUnsavedFiles *self)
+{
+  IdeUnsavedFilesPrivate *priv = ide_unsaved_files_get_instance_private (self);
+
+  g_return_val_if_fail (IDE_IS_UNSAVED_FILES (self), -1);
+
+  return priv->sequence;
+}
+
 static void
 ide_unsaved_files_finalize (GObject *object)
 {
diff --git a/libide/ide-unsaved-files.h b/libide/ide-unsaved-files.h
index a9f8d3e..7f99722 100644
--- a/libide/ide-unsaved-files.h
+++ b/libide/ide-unsaved-files.h
@@ -32,25 +32,27 @@ struct _IdeUnsavedFiles
   IdeObject parent_instance;
 };
 
-void     ide_unsaved_files_update         (IdeUnsavedFiles      *self,
-                                           GFile                *file,
-                                           GBytes               *content);
-void     ide_unsaved_files_remove         (IdeUnsavedFiles      *self,
-                                           GFile                *file);
-void     ide_unsaved_files_save_async     (IdeUnsavedFiles      *files,
-                                           GCancellable         *cancellable,
-                                           GAsyncReadyCallback   callback,
-                                           gpointer              user_data);
-gboolean ide_unsaved_files_save_finish    (IdeUnsavedFiles      *files,
-                                           GAsyncResult         *result,
-                                           GError              **error);
-void     ide_unsaved_files_restore_async  (IdeUnsavedFiles      *files,
-                                           GCancellable         *cancellable,
-                                           GAsyncReadyCallback   callback,
-                                           gpointer              user_data);
-gboolean ide_unsaved_files_restore_finish (IdeUnsavedFiles      *files,
-                                           GAsyncResult         *result,
-                                           GError              **error);
+void       ide_unsaved_files_update            (IdeUnsavedFiles      *self,
+                                                GFile                *file,
+                                                GBytes               *content);
+void       ide_unsaved_files_remove            (IdeUnsavedFiles      *self,
+                                                GFile                *file);
+void       ide_unsaved_files_save_async        (IdeUnsavedFiles      *files,
+                                                GCancellable         *cancellable,
+                                                GAsyncReadyCallback   callback,
+                                                gpointer              user_data);
+gboolean   ide_unsaved_files_save_finish       (IdeUnsavedFiles      *files,
+                                                GAsyncResult         *result,
+                                                GError              **error);
+void       ide_unsaved_files_restore_async     (IdeUnsavedFiles      *files,
+                                                GCancellable         *cancellable,
+                                                GAsyncReadyCallback   callback,
+                                                gpointer              user_data);
+gboolean   ide_unsaved_files_restore_finish    (IdeUnsavedFiles      *files,
+                                                GAsyncResult         *result,
+                                                GError              **error);
+GPtrArray *ide_unsaved_files_get_unsaved_files (IdeUnsavedFiles      *files);
+gint64     ide_unsaved_files_get_sequence      (IdeUnsavedFiles      *files);
 
 G_END_DECLS
 
diff --git a/libide/ide.h b/libide/ide.h
index 3762263..92593e6 100644
--- a/libide/ide.h
+++ b/libide/ide.h
@@ -67,6 +67,7 @@ G_BEGIN_DECLS
 #include "ide-test-case.h"
 #include "ide-test-suite.h"
 #include "ide-types.h"
+#include "ide-unsaved-file.h"
 #include "ide-unsaved-files.h"
 #include "ide-vcs.h"
 


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