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
a11a5a928a
commit
b97643c161
|
@ -25,6 +25,7 @@ using MonoMac.AppKit;
|
||||||
|
|
||||||
using Mono.Unix.Native;
|
using Mono.Unix.Native;
|
||||||
using SparkleLib;
|
using SparkleLib;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace SparkleShare {
|
namespace SparkleShare {
|
||||||
|
|
||||||
|
@ -58,22 +59,50 @@ namespace SparkleShare {
|
||||||
SparkleRepoBase.UseCustomWatcher = true;
|
SparkleRepoBase.UseCustomWatcher = true;
|
||||||
this.watcher = new SparkleMacWatcher (Program.Controller.FoldersPath);
|
this.watcher = new SparkleMacWatcher (Program.Controller.FoldersPath);
|
||||||
|
|
||||||
this.watcher.Changed += delegate (string path) {
|
this.watcher.Changed += OnFilesChanged;
|
||||||
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++;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 ();
|
private delegate void FileActivityTask ();
|
||||||
|
|
||||||
|
|
|
@ -40,10 +40,10 @@ namespace SparkleShare {
|
||||||
|
|
||||||
public sealed class SparkleMacWatcher : IDisposable {
|
public sealed class SparkleMacWatcher : IDisposable {
|
||||||
|
|
||||||
public delegate void ChangedEventHandler (string path);
|
public delegate void ChangedEventHandler (List<string> path);
|
||||||
public event ChangedEventHandler Changed;
|
public event ChangedEventHandler Changed;
|
||||||
|
|
||||||
public string Path { get; private set; }
|
public string BasePath { get; private set; }
|
||||||
|
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
|
@ -74,7 +74,7 @@ namespace SparkleShare {
|
||||||
|
|
||||||
public SparkleMacWatcher (string path)
|
public SparkleMacWatcher (string path)
|
||||||
{
|
{
|
||||||
Path = path;
|
BasePath = path;
|
||||||
m_callback = DoCallback;
|
m_callback = DoCallback;
|
||||||
|
|
||||||
NSString [] s = new NSString [1];
|
NSString [] s = new NSString [1];
|
||||||
|
@ -151,16 +151,21 @@ namespace SparkleShare {
|
||||||
|
|
||||||
var handler = Changed;
|
var handler = Changed;
|
||||||
if (handler != null) {
|
if (handler != null) {
|
||||||
if (paths [0].Length >= Path.Length) {
|
List<string> filteredPaths = new List<string> ();
|
||||||
string path = paths [0];
|
foreach (var path in paths) {
|
||||||
path = path.Substring (Path.Length);
|
if (path.Length > BasePath.Length) {
|
||||||
path = path.Trim ("/".ToCharArray ());
|
var t = path.Substring (BasePath.Length);
|
||||||
|
t = t.Trim ("/".ToCharArray ());
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace (path))
|
if (!string.IsNullOrWhiteSpace (t))
|
||||||
handler (path);
|
filteredPaths.Add(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(filteredPaths.Count > 0)
|
||||||
|
handler (filteredPaths);
|
||||||
|
}
|
||||||
|
|
||||||
GC.KeepAlive (this);
|
GC.KeepAlive (this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,10 +30,36 @@ namespace SparkleShare {
|
||||||
public SparkleRepoBase [] Repositories {
|
public SparkleRepoBase [] Repositories {
|
||||||
get {
|
get {
|
||||||
lock (this.repo_lock)
|
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 SparkleConfig Config { get; private set; }
|
||||||
public bool RepositoriesLoaded { get; private set; }
|
public bool RepositoriesLoaded { get; private set; }
|
||||||
|
@ -155,7 +181,8 @@ namespace SparkleShare {
|
||||||
private FileSystemWatcher watcher;
|
private FileSystemWatcher watcher;
|
||||||
private Object repo_lock = new Object ();
|
private Object repo_lock = new Object ();
|
||||||
private Object check_repos_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;
|
private bool lost_folders_path = false;
|
||||||
|
|
||||||
|
|
||||||
|
@ -464,17 +491,16 @@ namespace SparkleShare {
|
||||||
"Local and server versions were kept.");
|
"Local and server versions were kept.");
|
||||||
};
|
};
|
||||||
|
|
||||||
this.repositories.Add (repo);
|
AddRepository (repo);
|
||||||
this.repositories.Sort ((x, y) => string.Compare (x.Name, y.Name));
|
|
||||||
repo.Initialize ();
|
repo.Initialize ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void RemoveRepository (string folder_path)
|
private void RemoveRepository (string folder_path)
|
||||||
{
|
{
|
||||||
foreach (SparkleRepoBase repo in this.repositories) {
|
foreach (SparkleRepoBase repo in this.sortedRepositories) {
|
||||||
if (repo.LocalPath.Equals (folder_path)) {
|
if (repo.LocalPath.Equals (folder_path)) {
|
||||||
this.repositories.Remove (repo);
|
RemoveRepository (repo);
|
||||||
repo.Dispose ();
|
repo.Dispose ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue