private void TransactionDone(object sender, TransactionEventArgs e) { if (e.Transaction.Operations.Count == 0) { return; } var dirtying = e.Transaction.Operations.SelectMany(Presentation.Dirtiables.DirtiableManager.GetDirtyingOperations); var dirtiables = new HashSet <AssetViewModel>(dirtying.SelectMany(x => x.Dirtiables.OfType <AssetViewModel>())); if (dirtiables.Count > 0) { session.NotifyAssetPropertiesChanged(dirtiables); } Dispatcher.Invoke(() => transactions.Add(new TransactionViewModel(ServiceProvider, e.Transaction))); }
private async Task PullSourceFileChanges() { var sourceTracker = session.SourceTracker; var bufferBlock = new BufferBlock <IReadOnlyList <SourceFileChangedData> >(); var changedAssets = new HashSet <AssetViewModel>(); var sourceFileChanges = new List <SourceFileChangedData>(); using (sourceTracker.SourceFileChanged.LinkTo(bufferBlock)) { sourceTracker.EnableTracking = true; while (!IsDestroyed) { // Await for source file changes await bufferBlock.OutputAvailableAsync(cancel.Token); if (cancel.IsCancellationRequested) { return; } // Try as much as possible to process all changes at once IList <IReadOnlyList <SourceFileChangedData> > changes; bufferBlock.TryReceiveAll(out changes); sourceFileChanges.AddRange(changes.SelectMany(x => x)); if (sourceFileChanges.Count == 0) { continue; } for (var i = 0; i < sourceFileChanges.Count; i++) { var sourceFileChange = sourceFileChanges[i]; // Look first in the assets of the session, then in the list of deleted assets. var asset = sessionViewModel.GetAssetById(sourceFileChange.AssetId) ?? sessionViewModel.AllPackages.SelectMany(x => x.DeletedAssets).FirstOrDefault(x => x.Id == sourceFileChange.AssetId); if (asset == null) { continue; } // We care only about changes that needs to update if (sourceFileChange.NeedUpdate) { switch (sourceFileChange.Type) { case SourceFileChangeType.Asset: // The asset itself has changed and now references a new source asset.Sources.UpdateUsedHashes(sourceFileChange.Files); break; case SourceFileChangeType.SourceFile: // A source file referenced by the asset has changed asset.Sources.ComputeNeedUpdateFromSource(); break; default: throw new ArgumentOutOfRangeException(); } } // The asset has been updated, remove the change data from the list sourceFileChanges.RemoveAt(i--); if (!asset.IsDeleted) { // We will notify only for undeleted assets changedAssets.Add(asset); } } // Notify all changed assets at once. if (changedAssets.Count > 0) { sessionViewModel.NotifyAssetPropertiesChanged(changedAssets.ToList()); changedAssets.Clear(); } } } }