the mac file watcher gets a list of changed paths
this change does propagate the complete list of changes
This commit is contained in:
parent
f303a1ea8f
commit
c26dc8318f
|
@ -25,6 +25,7 @@ using MonoMac.AppKit;
|
|||
|
||||
using Mono.Unix.Native;
|
||||
using SparkleLib;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SparkleShare {
|
||||
|
||||
|
@ -58,22 +59,50 @@ namespace SparkleShare {
|
|||
SparkleRepoBase.UseCustomWatcher = true;
|
||||
this.watcher = new SparkleMacWatcher (Program.Controller.FoldersPath);
|
||||
|
||||
this.watcher.Changed += delegate (string path) {
|
||||
FileSystemEventArgs fse_args = new FileSystemEventArgs (WatcherChangeTypes.Changed, path, "Unknown_File");
|
||||
FileActivityTask [] tasks = new FileActivityTask [Repositories.Length];
|
||||
|
||||
// FIXME: There are cases where the wrong repo is triggered, so
|
||||
// we trigger all of them for now. Causes only slightly more overhead
|
||||
int i = 0;
|
||||
foreach (SparkleRepoBase repo in Repositories) {
|
||||
tasks [i] = MacActivityTask (repo, fse_args);
|
||||
tasks [i] ();
|
||||
i++;
|
||||
}
|
||||
};
|
||||
|
||||
this.watcher.Changed += OnFilesChanged;
|
||||
}
|
||||
|
||||
private void OnFilesChanged(List<string> changedFilesInBasedir)
|
||||
{
|
||||
Dictionary<SparkleRepoBase, List<string>> changeDict = new Dictionary<SparkleRepoBase, List<string>> ();
|
||||
|
||||
foreach (string file in changedFilesInBasedir) {
|
||||
string repo_name;
|
||||
int pathSepIndex = file.IndexOf (Path.DirectorySeparatorChar);
|
||||
|
||||
if (pathSepIndex >= 0)
|
||||
repo_name = file.Substring (0, pathSepIndex);
|
||||
else
|
||||
repo_name = file;
|
||||
|
||||
repo_name = Path.GetFileNameWithoutExtension (repo_name);
|
||||
|
||||
SparkleRepoBase repo = GetRepositoryByName (repo_name);
|
||||
if (repo == null)
|
||||
continue;
|
||||
|
||||
List<string> changes;
|
||||
|
||||
if (changeDict.ContainsKey (repo))
|
||||
changes = changeDict [repo];
|
||||
else {
|
||||
changes = new List<string> ();
|
||||
changeDict.Add (repo, changes);
|
||||
}
|
||||
|
||||
changes.Add (Path.Combine (SparkleConfig.DefaultConfig.FoldersPath, file));
|
||||
}
|
||||
|
||||
foreach (SparkleRepoBase repo in changeDict.Keys) {
|
||||
foreach (string file in changeDict[repo]) {
|
||||
FileActivityTask task = MacActivityTask (
|
||||
repo,
|
||||
new FileSystemEventArgs(WatcherChangeTypes.Changed, file, "unknown")
|
||||
);
|
||||
task ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private delegate void FileActivityTask ();
|
||||
|
||||
|
|
|
@ -40,10 +40,10 @@ namespace SparkleShare {
|
|||
|
||||
public sealed class SparkleMacWatcher : IDisposable {
|
||||
|
||||
public delegate void ChangedEventHandler (string path);
|
||||
public delegate void ChangedEventHandler (List<string> path);
|
||||
public event ChangedEventHandler Changed;
|
||||
|
||||
public string Path { get; private set; }
|
||||
public string BasePath { get; private set; }
|
||||
|
||||
|
||||
[Flags]
|
||||
|
@ -74,7 +74,7 @@ namespace SparkleShare {
|
|||
|
||||
public SparkleMacWatcher (string path)
|
||||
{
|
||||
Path = path;
|
||||
BasePath = path;
|
||||
m_callback = DoCallback;
|
||||
|
||||
NSString [] s = new NSString [1];
|
||||
|
@ -151,14 +151,19 @@ namespace SparkleShare {
|
|||
|
||||
var handler = Changed;
|
||||
if (handler != null) {
|
||||
if (paths [0].Length >= Path.Length) {
|
||||
string path = paths [0];
|
||||
path = path.Substring (Path.Length);
|
||||
path = path.Trim ("/".ToCharArray ());
|
||||
List<string> filteredPaths = new List<string> ();
|
||||
foreach (var path in paths) {
|
||||
if (path.Length > BasePath.Length) {
|
||||
var t = path.Substring (BasePath.Length);
|
||||
t = t.Trim ("/".ToCharArray ());
|
||||
|
||||
if (!string.IsNullOrWhiteSpace (path))
|
||||
handler (path);
|
||||
if (!string.IsNullOrWhiteSpace (t))
|
||||
filteredPaths.Add(t);
|
||||
}
|
||||
}
|
||||
|
||||
if(filteredPaths.Count > 0)
|
||||
handler (filteredPaths);
|
||||
}
|
||||
|
||||
GC.KeepAlive (this);
|
||||
|
|
|
@ -30,10 +30,36 @@ namespace SparkleShare {
|
|||
public SparkleRepoBase [] Repositories {
|
||||
get {
|
||||
lock (this.repo_lock)
|
||||
return this.repositories.GetRange (0, this.repositories.Count).ToArray ();
|
||||
return this.sortedRepositories.GetRange (0, this.sortedRepositories.Count).ToArray ();
|
||||
}
|
||||
}
|
||||
|
||||
private void AddRepository(SparkleRepoBase repo)
|
||||
{
|
||||
lock (this.repo_lock) {
|
||||
sortedRepositories.Add (repo);
|
||||
repositoryDict.Add (repo.Name, repo);
|
||||
sortedRepositories.Sort ((x, y) => string.Compare (x.Name, y.Name));
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveRepository(SparkleRepoBase repo)
|
||||
{
|
||||
lock (this.repo_lock) {
|
||||
sortedRepositories.Remove (repo);
|
||||
repositoryDict.Remove (repo.Name);
|
||||
}
|
||||
}
|
||||
|
||||
public SparkleRepoBase GetRepositoryByName(string name)
|
||||
{
|
||||
lock (this.repo_lock) {
|
||||
if(repositoryDict.ContainsKey(name))
|
||||
return repositoryDict [name];
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public SparkleConfig Config { get; private set; }
|
||||
public bool RepositoriesLoaded { get; private set; }
|
||||
|
@ -155,7 +181,8 @@ namespace SparkleShare {
|
|||
private FileSystemWatcher watcher;
|
||||
private Object repo_lock = new Object ();
|
||||
private Object check_repos_lock = new Object ();
|
||||
private List<SparkleRepoBase> repositories = new List<SparkleRepoBase> ();
|
||||
private List<SparkleRepoBase> sortedRepositories = new List<SparkleRepoBase> ();
|
||||
private Dictionary<string, SparkleRepoBase> repositoryDict = new Dictionary<string, SparkleRepoBase> ();
|
||||
private bool lost_folders_path = false;
|
||||
|
||||
|
||||
|
@ -464,17 +491,16 @@ namespace SparkleShare {
|
|||
"Local and server versions were kept.");
|
||||
};
|
||||
|
||||
this.repositories.Add (repo);
|
||||
this.repositories.Sort ((x, y) => string.Compare (x.Name, y.Name));
|
||||
AddRepository (repo);
|
||||
repo.Initialize ();
|
||||
}
|
||||
|
||||
|
||||
private void RemoveRepository (string folder_path)
|
||||
{
|
||||
foreach (SparkleRepoBase repo in this.repositories) {
|
||||
foreach (SparkleRepoBase repo in this.sortedRepositories) {
|
||||
if (repo.LocalPath.Equals (folder_path)) {
|
||||
this.repositories.Remove (repo);
|
||||
RemoveRepository (repo);
|
||||
repo.Dispose ();
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue