[gitg] Merge CommitModel in a single class
- From: Paolo Borelli <pborelli src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gitg] Merge CommitModel in a single class
- Date: Sun, 23 Jun 2013 15:01:49 +0000 (UTC)
commit 7c160ffa7b40f9ca716c31f1f5579818b9a2a657
Author: Paolo Borelli <pborelli gnome org>
Date: Sun Jun 23 16:49:40 2013 +0200
Merge CommitModel in a single class
Simplifies hierarchy in preparation for merging libgitg and libgitg-gtk
libgitg-gtk/gitg-gtk-commit-model.vala | 326 ++++++++++++++++++++++++++++-
libgitg/Makefile.am | 3 +-
libgitg/gitg-commit-model.vala | 356 --------------------------------
plugins/history/gitg-history.vala | 4 +-
4 files changed, 320 insertions(+), 369 deletions(-)
---
diff --git a/libgitg-gtk/gitg-gtk-commit-model.vala b/libgitg-gtk/gitg-gtk-commit-model.vala
index 6616398..acb0c97 100644
--- a/libgitg-gtk/gitg-gtk-commit-model.vala
+++ b/libgitg-gtk/gitg-gtk-commit-model.vala
@@ -61,20 +61,328 @@ namespace GitgGtk
}
}
- public class CommitModel : Gitg.CommitModel, Gtk.TreeModel
+ public class CommitModel : Object, Gtk.TreeModel
{
+ private Gitg.Repository d_repository;
+ private Cancellable? d_cancellable;
+ private Gitg.Commit[] d_ids;
+ private Thread<void*>? d_thread;
+ private Ggit.RevisionWalker? d_walker;
+ private uint d_advertized_size;
+ private uint d_idleid;
+ private Gitg.Lanes d_lanes;
+ private Ggit.SortMode d_sortmode;
+
+ private Ggit.OId[] d_include;
+ private Ggit.OId[] d_exclude;
+
private uint d_size;
private int d_stamp;
+ public uint limit { get; set; }
+
+ public Ggit.SortMode sort_mode
+ {
+ get { return d_sortmode; }
+ set
+ {
+ if (d_sortmode != value)
+ {
+ d_sortmode = value;
+ reload();
+ }
+ }
+ }
+
+ [Notify]
+ public Gitg.Repository repository
+ {
+ get { return d_repository; }
+ set
+ {
+ cancel();
+
+ d_walker = null;
+ d_repository = value;
+ }
+ }
+
+ public signal void started();
+ public signal void update(uint added);
+ public signal void finished();
+
public CommitModel(Gitg.Repository? repository)
{
Object(repository: repository);
}
- protected override void emit_started()
+ construct
+ {
+ d_lanes = new Gitg.Lanes();
+ d_cancellable = new Cancellable();
+ d_cancellable.cancel();
+
+ d_sortmode = Ggit.SortMode.TIME | Ggit.SortMode.TOPOLOGICAL;
+ }
+
+ ~CommitModel()
+ {
+ cancel();
+ }
+
+ private void cancel()
+ {
+ if (!d_cancellable.is_cancelled())
+ {
+ d_cancellable.cancel();
+
+ d_thread.join();
+ d_thread = null;
+ }
+
+ if (d_idleid != 0)
+ {
+ Source.remove(d_idleid);
+ d_idleid = 0;
+ }
+
+ d_ids = new Gitg.Commit[0];
+ d_advertized_size = 0;
+
+ emit_started();
+ finished();
+ }
+
+ public void reload()
+ {
+ cancel();
+
+ if (d_include.length == 0)
+ {
+ return;
+ }
+
+ walk.begin((obj, res) => {
+ walk.end(res);
+
+ d_cancellable.cancel();
+ if (d_thread != null)
+ {
+ d_thread.join();
+ d_thread = null;
+ }
+ });
+ }
+
+ public uint size()
+ {
+ return d_advertized_size;
+ }
+
+ public new Gitg.Commit? @get(uint idx)
+ {
+ Gitg.Commit? ret;
+
+ if (idx >= d_advertized_size)
+ {
+ return null;
+ }
+
+ lock(d_ids)
+ {
+ ret = d_ids[idx];
+ }
+
+ return ret;
+ }
+
+ public void set_include(Ggit.OId[] ids)
+ {
+ d_include = ids;
+ }
+
+ public void set_exclude(Ggit.OId[] ids)
+ {
+ d_exclude = ids;
+ }
+
+ private void notify_batch(bool isend)
+ {
+ lock(d_idleid)
+ {
+ if (d_idleid != 0)
+ {
+ Source.remove(d_idleid);
+ d_idleid = 0;
+ }
+ }
+
+ uint newsize = d_ids.length;
+
+ d_idleid = Idle.add(() => {
+ lock(d_idleid)
+ {
+ if (d_idleid == 0)
+ {
+ return false;
+ }
+
+ d_idleid = 0;
+
+ uint added = newsize - d_advertized_size;
+ d_advertized_size = newsize;
+
+ emit_update(added);
+
+ if (isend)
+ {
+ finished();
+ }
+ }
+
+ return false;
+ });
+ }
+
+ private async void walk()
+ {
+ Ggit.OId[] included = d_include;
+ Ggit.OId[] excluded = d_exclude;
+
+ uint limit = this.limit;
+
+ SourceFunc cb = walk.callback;
+
+ ThreadFunc<void*> run = () => {
+ if (d_walker == null)
+ {
+ try
+ {
+ d_walker = new Ggit.RevisionWalker(d_repository);
+ }
+ catch
+ {
+ notify_batch(true);
+ return null;
+ }
+ }
+
+ d_walker.reset();
+ d_walker.set_sort_mode(d_sortmode);
+
+ foreach (Ggit.OId oid in included)
+ {
+ try
+ {
+ d_walker.push(oid);
+ } catch {};
+ }
+
+ foreach (Ggit.OId oid in excluded)
+ {
+ try
+ {
+ d_walker.hide(oid);
+ } catch {};
+ }
+
+ uint size;
+
+ // Pre-allocate array to store commits
+ lock(d_ids)
+ {
+ d_ids = new Gitg.Commit[1000];
+
+ size = d_ids.length;
+
+ d_ids.length = 0;
+ d_advertized_size = 0;
+ }
+
+ Timer timer = new Timer();
+
+ while (true)
+ {
+ Ggit.OId? id;
+ Gitg.Commit? commit;
+
+ if (d_cancellable.is_cancelled())
+ {
+ break;
+ }
+
+ try
+ {
+ id = d_walker.next();
+
+ if (id == null)
+ {
+ break;
+ }
+
+ commit = d_repository.lookup(id, typeof(Gitg.Commit)) as
Gitg.Commit;
+ } catch { break; }
+
+ // Add the id
+ if (d_ids.length == size)
+ {
+ lock(d_ids)
+ {
+ var oldlen = d_ids.length;
+
+ size *= 2;
+
+ d_ids.resize((int)size);
+ d_ids.length = oldlen;
+ }
+ }
+
+ d_ids += commit;
+
+ int mylane;
+ var lanes = d_lanes.next(commit, out mylane);
+
+ commit.update_lanes((owned)lanes, mylane);
+
+ if (timer.elapsed() >= 200)
+ {
+ notify_batch(false);
+ timer.start();
+ }
+
+ if (limit > 0 && d_ids.length == limit)
+ {
+ break;
+ }
+ }
+
+ notify_batch(true);
+
+ Idle.add((owned)cb);
+ return null;
+ };
+
+ try
+ {
+ d_cancellable.reset();
+ emit_started();
+ d_thread = new Thread<void*>.try("gitg-history-walk", (owned)run);
+ yield;
+ }
+ catch
+ {
+ finished();
+
+ d_cancellable.cancel();
+ d_thread = null;
+ }
+ }
+
+ private void emit_started()
{
clear();
- base.emit_started();
+ d_lanes.reset();
+ started();
}
private void clear()
@@ -93,7 +401,7 @@ namespace GitgGtk
++d_stamp;
}
- protected override void emit_update(uint added)
+ private void emit_update(uint added)
{
var path = new Gtk.TreePath.from_indices(d_size);
@@ -110,7 +418,7 @@ namespace GitgGtk
path.next();
}
- base.emit_update(added);
+ update(added);
}
public Type get_column_type(int index)
@@ -169,7 +477,7 @@ namespace GitgGtk
return_if_fail(iter.stamp == d_stamp);
uint idx = (uint)(ulong)iter.user_data;
- Gitg.Commit? commit = base[idx];
+ Gitg.Commit? commit = this[idx];
val.init(get_column_type(column));
@@ -227,7 +535,7 @@ namespace GitgGtk
uint idx = (uint)(ulong)iter.user_data;
- return base[idx];
+ return this[idx];
}
public Gitg.Commit? commit_from_path(Gtk.TreePath path)
@@ -239,7 +547,7 @@ namespace GitgGtk
return null;
}
- return base[(uint)indices[0]];
+ return this[(uint)indices[0]];
}
public bool iter_children(out Gtk.TreeIter iter, Gtk.TreeIter? parent)
@@ -322,4 +630,4 @@ namespace GitgGtk
}
}
-// vi:ts=4
+// ex:set ts=4 noet
diff --git a/libgitg/Makefile.am b/libgitg/Makefile.am
index 237861e..b7e337d 100644
--- a/libgitg/Makefile.am
+++ b/libgitg/Makefile.am
@@ -40,8 +40,7 @@ VALA_FILES = \
gitg-lanes.vala \
gitg-color.vala \
gitg-init.vala \
- gitg-commit.vala \
- gitg-commit-model.vala
+ gitg-commit.vala
# Ignore all warnings for vala code...
libgitg_1_0_la_CFLAGS = \
diff --git a/plugins/history/gitg-history.vala b/plugins/history/gitg-history.vala
index d335fff..a45256b 100644
--- a/plugins/history/gitg-history.vala
+++ b/plugins/history/gitg-history.vala
@@ -116,7 +116,7 @@ namespace GitgHistory
}
}
- private void on_commit_model_started(Gitg.CommitModel model)
+ private void on_commit_model_started(GitgGtk.CommitModel model)
{
if (d_insertsig == 0)
{
@@ -140,7 +140,7 @@ namespace GitgHistory
}
}
- private void on_commit_model_finished(Gitg.CommitModel model)
+ private void on_commit_model_finished(GitgGtk.CommitModel model)
{
if (d_insertsig != 0)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]