/// <summary> /// ApplyAsync is called on the UI thread and its job is to update AppliedValue to be correct based on the changes that have come through data flow after being processed /// </summary> protected override async Task ApplyAsync(IProjectVersionedValue <DesignTimeInputSnapshot> value) { // Not using use the ThreadingService property because unit tests await JoinableFactory.SwitchToMainThreadAsync(); IProjectVersionedValue <DesignTimeInputSnapshot>?previous = AppliedValue; AppliedValue = value; // To avoid callers seeing an inconsistent state where there are no monikers, // we use BlockInitializeOnFirstAppliedValue to block on the first value // being applied. // // Due to that, and to avoid a deadlock when event handlers call back into us // while we're still initializing, we avoid firing the events the first time // a value is applied. if (previous != null) { DesignTimeInputSnapshot currentValue = value.Value; DesignTimeInputSnapshot previousValue = previous.Value; foreach (DesignTimeInputFileChange change in currentValue.ChangedInputs) { _buildManager.OnDesignTimeOutputDirty(_project.MakeRelative(change.File)); } foreach (string item in previousValue.Inputs.Except(currentValue.Inputs)) { _buildManager.OnDesignTimeOutputDeleted(_project.MakeRelative(item)); } } }
/// <summary> /// ApplyAsync is called on the UI thread and its job is to update AppliedValue to be correct based on the changes that have come through data flow after being processed /// </summary> protected override async Task ApplyAsync(IProjectVersionedValue <DesignTimeInputsDelta> value) { // Not using use the ThreadingService property because unit tests await JoinableFactory.SwitchToMainThreadAsync(); DesignTimeInputsDelta delta = value.Value; ImmutableHashSet <string>?removedFiles = AppliedValue?.Value.Inputs.Except(delta.Inputs); // As it happens the DesignTimeInputsDelta contains all of the state we need AppliedValue = value; foreach (DesignTimeInputFileChange change in delta.ChangedInputs) { _buildManager.OnDesignTimeOutputDirty(_project.MakeRelative(change.File)); } if (removedFiles != null) { foreach (string item in removedFiles) { _buildManager.OnDesignTimeOutputDeleted(_project.MakeRelative(item)); } } }
/// <summary> /// Called privately to actually fire the TempPE events and optionally recompile the TempPE library for the specified input /// </summary> private async Task FireTempPEDirtyAsync(string moniker, bool shouldCompile) { // Not using use the ThreadingService property because unit tests await _unconfiguredProjectServices.ThreadingService.SwitchToUIThread(); if (shouldCompile) { await ScheduleCompilationAsync(moniker, AppliedValue.Value, waitForCompletion : false, forceCompilation : true); } BuildManager.OnDesignTimeOutputDirty(moniker); }