From b97643c1617ad3fe768f6bc5a3c008d78198f670 Mon Sep 17 00:00:00 2001 From: Markus Stoll Date: Tue, 21 Oct 2014 14:21:03 +0200 Subject: [PATCH 1/2] the mac file watcher gets a list of changed paths this change does propagate the complete list of changes --- SparkleShare/Mac/SparkleController.cs | 57 ++++++++++++++++++++------- SparkleShare/Mac/SparkleMacWatcher.cs | 23 ++++++----- SparkleShare/SparkleControllerBase.cs | 38 +++++++++++++++--- 3 files changed, 89 insertions(+), 29 deletions(-) diff --git a/SparkleShare/Mac/SparkleController.cs b/SparkleShare/Mac/SparkleController.cs index c105a54d..eab7a150 100755 --- a/SparkleShare/Mac/SparkleController.cs +++ b/SparkleShare/Mac/SparkleController.cs @@ -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 changedFilesInBasedir) + { + Dictionary> changeDict = new Dictionary> (); + + 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 changes; + + if (changeDict.ContainsKey (repo)) + changes = changeDict [repo]; + else { + changes = new List (); + 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 (); diff --git a/SparkleShare/Mac/SparkleMacWatcher.cs b/SparkleShare/Mac/SparkleMacWatcher.cs index 305e5449..2365f6bb 100755 --- a/SparkleShare/Mac/SparkleMacWatcher.cs +++ b/SparkleShare/Mac/SparkleMacWatcher.cs @@ -40,10 +40,10 @@ namespace SparkleShare { public sealed class SparkleMacWatcher : IDisposable { - public delegate void ChangedEventHandler (string path); + public delegate void ChangedEventHandler (List 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 filteredPaths = new List (); + 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); diff --git a/SparkleShare/SparkleControllerBase.cs b/SparkleShare/SparkleControllerBase.cs index 9af0626c..338c8cc2 100644 --- a/SparkleShare/SparkleControllerBase.cs +++ b/SparkleShare/SparkleControllerBase.cs @@ -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 repositories = new List (); + private List sortedRepositories = new List (); + private Dictionary repositoryDict = new Dictionary (); 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; } From 8fd411472422c938b463f8df8949c59db64b6cdd Mon Sep 17 00:00:00 2001 From: Markus Stoll Date: Tue, 21 Oct 2014 14:40:04 +0200 Subject: [PATCH 2/2] coding style --- SparkleShare/Mac/SparkleController.cs | 22 +++++++++++----------- SparkleShare/Mac/SparkleMacWatcher.cs | 8 ++++---- SparkleShare/SparkleControllerBase.cs | 22 +++++++++++----------- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/SparkleShare/Mac/SparkleController.cs b/SparkleShare/Mac/SparkleController.cs index eab7a150..bfecb958 100755 --- a/SparkleShare/Mac/SparkleController.cs +++ b/SparkleShare/Mac/SparkleController.cs @@ -62,16 +62,16 @@ namespace SparkleShare { this.watcher.Changed += OnFilesChanged; } - private void OnFilesChanged(List changedFilesInBasedir) + private void OnFilesChanged(List changed_files_in_basedir) { - Dictionary> changeDict = new Dictionary> (); + Dictionary> change_dict = new Dictionary> (); - foreach (string file in changedFilesInBasedir) { + foreach (string file in changed_files_in_basedir) { string repo_name; - int pathSepIndex = file.IndexOf (Path.DirectorySeparatorChar); + int path_sep_index = file.IndexOf (Path.DirectorySeparatorChar); - if (pathSepIndex >= 0) - repo_name = file.Substring (0, pathSepIndex); + if (path_sep_index >= 0) + repo_name = file.Substring (0, path_sep_index); else repo_name = file; @@ -83,18 +83,18 @@ namespace SparkleShare { List changes; - if (changeDict.ContainsKey (repo)) - changes = changeDict [repo]; + if (change_dict.ContainsKey (repo)) + changes = change_dict [repo]; else { changes = new List (); - changeDict.Add (repo, changes); + change_dict.Add (repo, changes); } changes.Add (Path.Combine (SparkleConfig.DefaultConfig.FoldersPath, file)); } - foreach (SparkleRepoBase repo in changeDict.Keys) { - foreach (string file in changeDict[repo]) { + foreach (SparkleRepoBase repo in change_dict.Keys) { + foreach (string file in change_dict[repo]) { FileActivityTask task = MacActivityTask ( repo, new FileSystemEventArgs(WatcherChangeTypes.Changed, file, "unknown") diff --git a/SparkleShare/Mac/SparkleMacWatcher.cs b/SparkleShare/Mac/SparkleMacWatcher.cs index 2365f6bb..0d6cf797 100755 --- a/SparkleShare/Mac/SparkleMacWatcher.cs +++ b/SparkleShare/Mac/SparkleMacWatcher.cs @@ -151,19 +151,19 @@ namespace SparkleShare { var handler = Changed; if (handler != null) { - List filteredPaths = new List (); + List filtered_paths = new List (); foreach (var path in paths) { if (path.Length > BasePath.Length) { var t = path.Substring (BasePath.Length); t = t.Trim ("/".ToCharArray ()); if (!string.IsNullOrWhiteSpace (t)) - filteredPaths.Add(t); + filtered_paths.Add(t); } } - if(filteredPaths.Count > 0) - handler (filteredPaths); + if(filtered_paths.Count > 0) + handler (filtered_paths); } GC.KeepAlive (this); diff --git a/SparkleShare/SparkleControllerBase.cs b/SparkleShare/SparkleControllerBase.cs index 338c8cc2..e2e56946 100644 --- a/SparkleShare/SparkleControllerBase.cs +++ b/SparkleShare/SparkleControllerBase.cs @@ -30,32 +30,32 @@ namespace SparkleShare { public SparkleRepoBase [] Repositories { get { lock (this.repo_lock) - return this.sortedRepositories.GetRange (0, this.sortedRepositories.Count).ToArray (); + return this.sorted_repositories.GetRange (0, this.sorted_repositories.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)); + sorted_repositories.Add (repo); + repository_dict.Add (repo.Name, repo); + sorted_repositories.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); + sorted_repositories.Remove (repo); + repository_dict.Remove (repo.Name); } } public SparkleRepoBase GetRepositoryByName(string name) { lock (this.repo_lock) { - if(repositoryDict.ContainsKey(name)) - return repositoryDict [name]; + if(repository_dict.ContainsKey(name)) + return repository_dict [name]; return null; } @@ -181,8 +181,8 @@ namespace SparkleShare { private FileSystemWatcher watcher; private Object repo_lock = new Object (); private Object check_repos_lock = new Object (); - private List sortedRepositories = new List (); - private Dictionary repositoryDict = new Dictionary (); + private List sorted_repositories = new List (); + private Dictionary repository_dict = new Dictionary (); private bool lost_folders_path = false; @@ -498,7 +498,7 @@ namespace SparkleShare { private void RemoveRepository (string folder_path) { - foreach (SparkleRepoBase repo in this.sortedRepositories) { + foreach (SparkleRepoBase repo in this.sorted_repositories) { if (repo.LocalPath.Equals (folder_path)) { RemoveRepository (repo); repo.Dispose ();