[gitg/commit: 1/7] Initial stage class with enumeration of status files



commit d8cd7daee6e19a6040618125658b0600bd7e0105
Author: Jesse van den Kieboom <jessevdk gmail com>
Date:   Sun Jun 23 19:46:08 2013 +0200

    Initial stage class with enumeration of status files

 libgitg/Makefile.am          |    3 +-
 libgitg/gitg-repository.vala |   18 ++++
 libgitg/gitg-stage.vala      |  188 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 208 insertions(+), 1 deletions(-)
---
diff --git a/libgitg/Makefile.am b/libgitg/Makefile.am
index 0b9ea99..1b1c32b 100644
--- a/libgitg/Makefile.am
+++ b/libgitg/Makefile.am
@@ -58,7 +58,8 @@ VALA_FILES =                                  \
        gitg-diff-view-request-diff.vala        \
        gitg-dash-view.vala                     \
        gitg-when-mapped.vala                   \
-       gitg-progress-bin.vala
+       gitg-progress-bin.vala                  \
+       gitg-stage.vala
 
 # Ignore all warnings for vala code...
 libgitg_1_0_la_CFLAGS =                \
diff --git a/libgitg/gitg-repository.vala b/libgitg/gitg-repository.vala
index 4144eeb..f46d3c1 100644
--- a/libgitg/gitg-repository.vala
+++ b/libgitg/gitg-repository.vala
@@ -23,6 +23,7 @@ namespace Gitg
 public class Repository : Ggit.Repository
 {
        private HashTable<Ggit.OId, SList<Gitg.Ref>> d_refs;
+       private weak Stage ?d_stage;
 
        public string? name {
                owned get {
@@ -144,6 +145,23 @@ public class Repository : Ggit.Repository
        {
                return base.get_head() as Ref;
        }
+
+       public Stage get_stage()
+       {
+               Stage ret;
+
+               if (d_stage == null)
+               {
+                       ret = new Stage(this);
+                       d_stage = ret;
+               }
+               else
+               {
+                       ret = d_stage;
+               }
+
+               return (owned)ret;
+       }
 }
 
 }
diff --git a/libgitg/gitg-stage.vala b/libgitg/gitg-stage.vala
new file mode 100644
index 0000000..5dba8f9
--- /dev/null
+++ b/libgitg/gitg-stage.vala
@@ -0,0 +1,188 @@
+/*
+ * This file is part of gitg
+ *
+ * Copyright (C) 2012 - Jesse van den Kieboom
+ *
+ * gitg 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.
+ *
+ * gitg 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 gitg. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Gitg
+{
+
+public class StageStatusFile
+{
+       private string d_path;
+       private Ggit.StatusFlags d_flags;
+
+       public StageStatusFile(string path, Ggit.StatusFlags flags)
+       {
+               d_path = path;
+               d_flags = flags;
+       }
+
+       public string path
+       {
+               get { return d_path; }
+       }
+
+       public Ggit.StatusFlags flags
+       {
+               get { return d_flags; }
+       }
+}
+
+public class StageStatusEnumerator
+{
+       private Repository d_repository;
+       private Thread<void *> d_thread;
+       private StageStatusFile[] d_files;
+       private int d_offset;
+       private int d_callback_num;
+       private Cancellable d_cancellable;
+       private SourceFunc d_callback;
+
+       internal StageStatusEnumerator(Repository repository)
+       {
+               d_repository = repository;
+
+               d_files = new StageStatusFile[100];
+               d_files.length = 0;
+               d_cancellable = new Cancellable();
+
+               try
+               {
+                       d_thread = new Thread<void *>.try("gitg-status-enumerator", run_status);
+               } catch {}
+       }
+
+       ~StageStatusEnumerator()
+       {
+               lock (d_files)
+               {
+                       if (d_cancellable != null)
+                       {
+                               d_cancellable.cancel();
+                       }
+               }
+
+               d_thread.join();
+       }
+
+       private void *run_status()
+       {
+               try
+               {
+                       d_repository.file_status_foreach(null, (path, flags) => {
+                               lock (d_files)
+                               {
+                                       d_files += new StageStatusFile(path, flags);
+
+                                       if (d_callback != null && d_files.length >= d_callback_num)
+                                       {
+                                               var cb = (owned)d_callback;
+                                               d_callback = null;
+
+                                               Idle.add((owned)cb);
+                                       }
+                               }
+
+                               if (d_cancellable.is_cancelled())
+                               {
+                                       return 1;
+                               }
+
+                               return 0;
+                       });
+               } catch {}
+
+               lock (d_files)
+               {
+                       d_cancellable = null;
+               }
+
+               return null;
+       }
+
+       private StageStatusFile[] fill_files(int num)
+       {
+               int n = 0;
+
+               StageStatusFile[] ret = new StageStatusFile[int.min(num, d_files.length - d_offset)];
+               ret.length = 0;
+
+               // d_files is already locked here, so it's safe to access
+               while (d_offset < d_files.length)
+               {
+                       if (n == num)
+                       {
+                               break;
+                       }
+
+                       ret += d_files[d_offset];
+                       d_offset++;
+
+                       ++n;
+               }
+
+               return ret;
+       }
+
+       public async StageStatusFile[] next_files(int num)
+       {
+               SourceFunc callback = next_files.callback;
+               StageStatusFile[] ret;
+
+               lock (d_files)
+               {
+                       if (d_cancellable == null)
+                       {
+                               // Already finished
+                               return fill_files(num);
+                       }
+                       else
+                       {
+                               d_callback = (owned)callback;
+                               d_callback_num = num;
+                       }
+               }
+
+               yield;
+
+               lock (d_files)
+               {
+                       ret = fill_files(num);
+               }
+
+               return ret;
+       }
+}
+
+public class Stage
+{
+       private Repository d_repository;
+
+       internal Stage(Repository repository)
+       {
+               d_repository = repository;
+       }
+
+       public StageStatusEnumerator file_status()
+       {
+               return new StageStatusEnumerator(d_repository);
+       }
+}
+
+}
+
+// ex:set ts=4 noet


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