Exemplo n.º 1
0
            public TestTempPEBuildManager(IFileSystem fileSystem)
                : base(IProjectThreadingServiceFactory.Create(),
                       IUnconfiguredProjectCommonServicesFactory.Create(threadingService: IProjectThreadingServiceFactory.Create()),
                       IActiveWorkspaceProjectContextHostFactory.Create(),
                       IActiveConfiguredProjectSubscriptionServiceFactory.Create(),
                       null,
                       fileSystem,
                       IProjectFaultHandlerServiceFactory.Create(),
                       null)
            {
                BuildManager = new TestBuildManager(this);

                AppliedValue = new ProjectVersionedValue <DesignTimeInputsItem>(new DesignTimeInputsItem()
                {
                    OutputPath = "TempPE"
                }, ImmutableDictionary <NamedIdentity, IComparable> .Empty);
            }
Exemplo n.º 2
0
        /// <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(DesignTimeInputsDelta value)
        {
            // Not using use the ThreadingService property because unit tests
            await _unconfiguredProjectServices.ThreadingService.SwitchToUIThread();

            DesignTimeInputsItem previousValue = AppliedValue?.Value ?? new DesignTimeInputsItem();

            // Calculate the new value
            ImmutableHashSet <string>          newDesignTimeInputs;
            ImmutableHashSet <string>          newSharedDesignTimeInputs;
            ImmutableDictionary <string, uint> newCookies;
            ImmutableDictionary <string, ITaskDelayScheduler> newSchedulers;
            var  addedDesignTimeInputs            = new List <string>();
            var  removedDesignTimeInputs          = new List <string>();
            bool hasRemovedDesignTimeSharedInputs = false;
            bool hasAddedDesignTimeSharedInputs   = false;

            if (value.HasFileChanges)
            {
                var designTimeInputs       = previousValue.Inputs.ToBuilder();
                var designTimeSharedInputs = previousValue.SharedInputs.ToBuilder();
                var cookies    = previousValue.Cookies.ToBuilder();
                var schedulers = previousValue.TaskSchedulers.ToBuilder();

                foreach (string item in value.AddedItems)
                {
                    if (designTimeInputs.Add(item))
                    {
                        addedDesignTimeInputs.Add(item);
                        schedulers.Add(item, CreateTaskScheduler());
                    }
                }

                foreach (string item in value.RemovedItems)
                {
                    if (designTimeInputs.Remove(item))
                    {
                        removedDesignTimeInputs.Add(item);
                        // We only unsubscribe from file changes if there is no other reason to care about this file
                        if (TryGetValueIfUnused(item, cookies, designTimeSharedInputs, out _))
                        {
                            cookies.Remove(item);
                        }
                        if (TryGetValueIfUnused(item, schedulers, designTimeSharedInputs, out ITaskDelayScheduler scheduler))
                        {
                            schedulers.Remove(item);
                            scheduler.Dispose();
                        }
                    }
                }

                foreach (string item in value.AddedSharedItems)
                {
                    if (designTimeSharedInputs.Add(item))
                    {
                        hasAddedDesignTimeSharedInputs = true;
                        if (!schedulers.ContainsKey(item))
                        {
                            schedulers.Add(item, CreateTaskScheduler());
                        }
                    }
                }

                foreach (string item in value.RemovedSharedItems)
                {
                    if (designTimeSharedInputs.Remove(item))
                    {
                        hasRemovedDesignTimeSharedInputs = true;
                        if (TryGetValueIfUnused(item, cookies, designTimeInputs, out _))
                        {
                            cookies.Remove(item);
                        }
                        if (TryGetValueIfUnused(item, schedulers, designTimeInputs, out ITaskDelayScheduler scheduler))
                        {
                            schedulers.Remove(item);
                            scheduler.Dispose();
                        }
                    }
                }

                newDesignTimeInputs       = designTimeInputs.ToImmutable();
                newSharedDesignTimeInputs = designTimeSharedInputs.ToImmutable();
                newCookies    = cookies.ToImmutable();
                newSchedulers = schedulers.ToImmutable();
            }
            else
            {
                // If there haven't been file changes we can just flow our previous collections to the new version to avoid roundtriping our collections to builders and back
                newDesignTimeInputs       = previousValue.Inputs;
                newSharedDesignTimeInputs = previousValue.SharedInputs;
                newCookies    = previousValue.Cookies;
                newSchedulers = previousValue.TaskSchedulers;
            }

            // Apply our new value
            AppliedValue = new ProjectVersionedValue <DesignTimeInputsItem>(new DesignTimeInputsItem
            {
                Inputs       = newDesignTimeInputs,
                SharedInputs = newSharedDesignTimeInputs,
                // We always need an output path, so if it hasn't changed we just reuse the previous value
                OutputPath     = value.OutputPath ?? previousValue.OutputPath,
                Cookies        = newCookies,
                TaskSchedulers = newSchedulers
            }, value.DataSourceVersions);

            // Project properties changes cause all PEs to be dirty and recompile if this isn't the first update
            if (value.HasProjectPropertyChanges)
            {
                foreach (string item in newDesignTimeInputs)
                {
                    await FireTempPEDirtyAsync(item, value.ShouldCompile);
                }
            }
            else
            {
                // Individual inputs dirty their PEs and possibly recompile
                foreach (string item in addedDesignTimeInputs)
                {
                    await FireTempPEDirtyAsync(item, value.ShouldCompile);
                }
            }

            // Shared items cause all TempPEs to be dirty, but don't recompile, to match legacy behaviour
            if (hasRemovedDesignTimeSharedInputs || hasAddedDesignTimeSharedInputs)
            {
                // adding or removing shared design time inputs dirties things but doesn't recompile
                foreach (string item in newDesignTimeInputs)
                {
                    // We don't want to fire again if we already fired above and compiled
                    if (!addedDesignTimeInputs.Contains(item))
                    {
                        await FireTempPEDirtyAsync(item, false);
                    }
                }
            }

            foreach (string item in removedDesignTimeInputs)
            {
                BuildManager.OnDesignTimeOutputDeleted(item);
            }
Exemplo n.º 3
0
        /// <summary>
        /// InitializeInnerCoreAsync is responsible for setting an initial AppliedValue. This value will be used by any UI thread calls that may happen
        /// before the first data flow blocks have been processed. If this method doesn't set a value then the system will block until the first blocks
        /// have been applied.
        /// </summary>
        protected override Task InitializeInnerCoreAsync(CancellationToken cancellationToken)
        {
            AppliedValue = new ProjectVersionedValue <DesignTimeInputsItem>(new DesignTimeInputsItem(), ImmutableDictionary.Create <NamedIdentity, IComparable>());

            return(Task.CompletedTask);
        }