Initial stage class with enumeration of status files

This commit is contained in:
Jesse van den Kieboom 2013-06-23 19:46:08 +02:00
parent a7c0856019
commit b7306286a3
3 changed files with 208 additions and 1 deletions

View file

@ -59,7 +59,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 = \

View file

@ -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;
}
}
}

188
libgitg/gitg-stage.vala Normal file
View file

@ -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