Skip to content

Commit

Permalink
fix: Observe C# file changes
Browse files Browse the repository at this point in the history
  • Loading branch information
jeromelaban committed Nov 28, 2021
1 parent bcaa4fb commit 5abdebd
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ namespace Uno.UI.RemoteControl.Host.HotReload
{
partial class ServerHotReloadProcessor : IServerProcessor, IDisposable
{
private FileSystemWatcher[] _solutionWatchers;
private CompositeDisposable _solutionWatcherEventsDisposable;

private Task<(Solution, WatchHotReloadService)>? _initializeTask;
private Solution _currentSolution;
private WatchHotReloadService _hotReloadService;
Expand All @@ -33,6 +36,8 @@ partial class ServerHotReloadProcessor : IServerProcessor, IDisposable

private void InitializeMetadataUpdater(ConfigureServer configureServer)
{
Debugger.Launch();

_ = bool.TryParse(_remoteControlServer.GetServerConfiguration("metadata-updates"), out _useRoslynHotReload);

if (_useRoslynHotReload)
Expand All @@ -43,11 +48,78 @@ private void InitializeMetadataUpdater(ConfigureServer configureServer)
}
}

private void InitializeInner(ConfigureServer configureServer) => _initializeTask = Task.Run(() =>
CompilationWorkspaceProvider.CreateWorkspaceAsync(configureServer.ProjectPath, _reporter, configureServer.MetadataUpdateCapabilities, CancellationToken.None),
CancellationToken.None);
private void InitializeInner(ConfigureServer configureServer) => _initializeTask = Task.Run(
async () =>
{
var result = await CompilationWorkspaceProvider.CreateWorkspaceAsync(configureServer.ProjectPath, _reporter, configureServer.MetadataUpdateCapabilities, CancellationToken.None);

ObserveSolutionPaths(result.Item1);

return result;
},
CancellationToken.None);

private void ObserveSolutionPaths(Solution solution)
{
_solutionWatchers = solution.Projects
.SelectMany(p => p.Documents.Select(d => Path.GetDirectoryName(d.FilePath)))
.Distinct()
.Select(p => new FileSystemWatcher
{
Path = p,
Filter = "*.*",
NotifyFilter = NotifyFilters.LastWrite |
NotifyFilters.Attributes |
NotifyFilters.Size |
NotifyFilters.CreationTime |
NotifyFilters.FileName,
EnableRaisingEvents = true,
IncludeSubdirectories = false
})
.ToArray();

_solutionWatcherEventsDisposable = new CompositeDisposable();

foreach (var watcher in _solutionWatchers)
{
// Create an observable instead of using the FromEventPattern which
// does not register to events properly.
// Renames are required for the WriteTemporary->DeleteOriginal->RenameToOriginal that
// Visual Studio uses to save files.

var changes = Observable.Create<string>(o =>
{

void changed(object s, FileSystemEventArgs args) => o.OnNext(args.FullPath);
void renamed(object s, RenamedEventArgs args) => o.OnNext(args.FullPath);

watcher.Changed += changed;
watcher.Created += changed;
watcher.Renamed += renamed;

return Disposable.Create(() =>
{
watcher.Changed -= changed;
watcher.Created -= changed;
watcher.Renamed -= renamed;
});
});

var disposable = changes
.Buffer(TimeSpan.FromMilliseconds(250))
.Subscribe(filePaths =>
{
#if NET6_0_OR_GREATER
ProcessMetadataChanges(filePaths.Distinct());
#endif
}, e => Console.WriteLine($"Error {e}"));

_solutionWatcherEventsDisposable.Add(disposable);

}
}

private void ProcessMetadataChanges(IList<string> filePaths)
private void ProcessMetadataChanges(IEnumerable<string> filePaths)
{
if (_useRoslynHotReload)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,6 @@ private async Task ProcessConfigureServer(ConfigureServer configureServer)
.Buffer(TimeSpan.FromMilliseconds(250))
.Subscribe(filePaths =>
{
#if NET6_0_OR_GREATER
ProcessMetadataChanges(filePaths);
#endif

foreach (var file in filePaths.Distinct().Where(f => Path.GetExtension(f).Equals(".xaml", StringComparison.OrdinalIgnoreCase)))
{
OnXamlFileChanged(file);
Expand Down Expand Up @@ -150,6 +146,17 @@ public void Dispose()
watcher.Dispose();
}
}

#if NET6_0_OR_GREATER
_solutionWatcherEventsDisposable?.Dispose();
if (_solutionWatchers != null)
{
foreach (var watcher in _solutionWatchers)
{
watcher.Dispose();
}
}
#endif
}
}
}

0 comments on commit 5abdebd

Please sign in to comment.