From ca47896204482bf4a6979e3838bf7f09f61cebeb Mon Sep 17 00:00:00 2001 From: giy <giy@omp-system.ru> Date: Fri, 02 Sep 2022 14:16:56 +0300 Subject: [PATCH] Обновление до версии 2.9.0 --- QtVsTools.Package/QtMsBuild/QtProjectTracker.cs | 170 +++++++++++++++++--------------------------------------- 1 files changed, 51 insertions(+), 119 deletions(-) diff --git a/QtVsTools.Package/QtMsBuild/QtProjectTracker.cs b/QtVsTools.Package/QtMsBuild/QtProjectTracker.cs index 66db5c7..1d8e719 100644 --- a/QtVsTools.Package/QtMsBuild/QtProjectTracker.cs +++ b/QtVsTools.Package/QtMsBuild/QtProjectTracker.cs @@ -29,41 +29,41 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Threading.Tasks.Dataflow; -using Microsoft.Build.Evaluation; -using Microsoft.Build.Framework; using Microsoft.VisualStudio.ProjectSystem; using Microsoft.VisualStudio.ProjectSystem.Properties; +using Microsoft.VisualStudio.Shell; using Microsoft.VisualStudio.TaskStatusCenter; using Microsoft.VisualStudio.Threading; -using EnvDTE; +using Microsoft.VisualStudio.VCProjectEngine; + +using Task = System.Threading.Tasks.Task; namespace QtVsTools.QtMsBuild { + using Common; using Core; using VisualStudio; - using Thread = System.Threading.Thread; + using SubscriberAction = ActionBlock<IProjectVersionedValue<IProjectSubscriptionUpdate>>; class QtProjectTracker : Concurrent<QtProjectTracker> { - static ConcurrentDictionary<string, QtProjectTracker> _Instances; - static ConcurrentDictionary<string, QtProjectTracker> Instances => - StaticThreadSafeInit(() => _Instances, () => - _Instances = new ConcurrentDictionary<string, QtProjectTracker>()); + static LazyFactory StaticLazy { get; } = new LazyFactory(); - static PunisherQueue<QtProjectTracker> _InitQueue; - static PunisherQueue<QtProjectTracker> InitQueue => - StaticThreadSafeInit(() => _InitQueue, () => - _InitQueue = new PunisherQueue<QtProjectTracker>()); + static ConcurrentDictionary<string, QtProjectTracker> Instances => StaticLazy.Get(() => + Instances, () => new ConcurrentDictionary<string, QtProjectTracker>()); - static IVsTaskStatusCenterService _StatusCenter; - static IVsTaskStatusCenterService StatusCenter => StaticThreadSafeInit(() => _StatusCenter, - () => _StatusCenter = VsServiceProvider - .GetService<SVsTaskStatusCenterService, IVsTaskStatusCenterService>()); + static PunisherQueue<QtProjectTracker> InitQueue => StaticLazy.Get(() => + InitQueue, () => new PunisherQueue<QtProjectTracker>()); + + static IVsTaskStatusCenterService StatusCenter => StaticLazy.Get(() => + StatusCenter, () => VsServiceProvider + .GetService<SVsTaskStatusCenterService, IVsTaskStatusCenterService>()); static Task InitDispatcher { get; set; } static ITaskHandler2 InitStatus { get; set; } @@ -75,73 +75,37 @@ Initialized = new EventWaitHandle(false, EventResetMode.ManualReset); } - class Subscriber : IDisposable - { - public Subscriber(QtProjectTracker tracker, ConfiguredProject config) - { - Tracker = tracker; - Config = config; - Subscription = Config.Services.ProjectSubscription.JointRuleSource.SourceBlock - .LinkTo(new SubscriberAction(ProjectUpdateAsync), - ruleNames: new[] - { - "ClCompile", - "QtRule10_Settings", - "QtRule30_Moc", - "QtRule40_Rcc", - "QtRule60_Repc", - "QtRule50_Uic", - "QtRule_Translation", - "QtRule70_Deploy", - }, - initialDataAsNew: false - ); - } - - QtProjectTracker Tracker { get; set; } - ConfiguredProject Config { get; set; } - IDisposable Subscription { get; set; } - - public void Dispose() - { - Subscription?.Dispose(); - Subscription = null; - } - - async Task ProjectUpdateAsync(IProjectVersionedValue<IProjectSubscriptionUpdate> update) - { - await Tracker.OnProjectUpdateAsync(Config, update.Value); - } - } - public EnvDTE.Project Project { get; private set; } + public string ProjectPath { get; private set; } + public VCProject VcProject { get; private set; } public UnconfiguredProject UnconfiguredProject { get; private set; } - public EventWaitHandle Initialized { get; private set; } - List<Subscriber> Subscribers { get; set; } + public EventWaitHandle Initialized { get; } - public static bool IsTracked(EnvDTE.Project project) + public static bool IsTracked(string projectPath) { - return Instances.ContainsKey(project.FullName); + return Instances.ContainsKey(projectPath); } public static void Add(EnvDTE.Project project) { if (!QtVsToolsPackage.Instance.Options.ProjectTracking) return; - Get(project); + + ThreadHelper.ThrowIfNotOnUIThread(); + Get(project, project.FullName); } - public static QtProjectTracker Get(EnvDTE.Project project) + public static QtProjectTracker Get(EnvDTE.Project project, string projectPath) { lock (StaticCriticalSection) { - QtProjectTracker tracker = null; - if (Instances.TryGetValue(project.FullName, out tracker)) + if (Instances.TryGetValue(projectPath, out QtProjectTracker tracker)) return tracker; tracker = new QtProjectTracker { Project = project, + ProjectPath = projectPath }; - Instances[project.FullName] = tracker; + Instances[projectPath] = tracker; InitQueue.Enqueue(tracker); if (InitDispatcher == null) InitDispatcher = Task.Run(InitDispatcherLoopAsync); @@ -162,14 +126,17 @@ while (!QtVsToolsPackage.Instance.Zombied) { while (InitQueue.IsEmpty) await Task.Delay(100); - QtProjectTracker tracker; - if (InitQueue.TryDequeue(out tracker)) { + if (InitQueue.TryDequeue(out QtProjectTracker tracker)) { if (InitStatus == null) { - await QtVsToolsPackage.Instance.JoinableTaskFactory.SwitchToMainThreadAsync(); + await QtVsToolsPackage.Instance.JoinableTaskFactory + .SwitchToMainThreadAsync(); tracker.BeginInitStatus(); await TaskScheduler.Default; } else { + await QtVsToolsPackage.Instance.JoinableTaskFactory + .SwitchToMainThreadAsync(); tracker.UpdateInitStatus(0); + await TaskScheduler.Default; } await tracker.InitializeAsync(); } @@ -187,9 +154,12 @@ async Task InitializeAsync() { int p = 0; + await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); UpdateInitStatus(p += 10); - await QtVsToolsPackage.Instance.JoinableTaskFactory.SwitchToMainThreadAsync(); + VcProject = Project.Object as VCProject; + if (VcProject == null) + return; UpdateInitStatus(p += 10); var context = Project.Object as IVsBrowseObjectContext; @@ -211,57 +181,23 @@ Initialized.Set(); - Subscribers = new List<Subscriber>(); int n = configs.Count; int d = (100 - p) / (n * 2); foreach (var config in configs) { var configProject = await UnconfiguredProject.LoadConfiguredProjectAsync(config); UpdateInitStatus(p += d); - Subscribers.Add(new Subscriber(this, configProject)); - configProject.ProjectUnloading += OnProjectUnloading; + configProject.ProjectUnloading += OnProjectUnloadingAsync; if (QtVsToolsPackage.Instance.Options.BuildDebugInformation) { Messages.Print(string.Format( "{0:HH:mm:ss.FFF} QtProjectTracker({1}): Started tracking [{2}] {3}", DateTime.Now, Thread.CurrentThread.ManagedThreadId, - config.Name, - UnconfiguredProject.FullPath)); + config.Name, ProjectPath)); } UpdateInitStatus(p += d); } } - - async Task OnProjectUpdateAsync(ConfiguredProject config, IProjectSubscriptionUpdate update) - { - var changes = update.ProjectChanges.Values - .Where(x => x.Difference.AnyChanges) - .Select(x => x.Difference); - var changesCount = changes - .Select(x => x.AddedItems.Count - + x.ChangedItems.Count - + x.ChangedProperties.Count - + x.RemovedItems.Count - + x.RenamedItems.Count) - .Sum(); - var changedProps = changes.SelectMany(x => x.ChangedProperties); - if (changesCount == 0 - || (changesCount == 1 - && changedProps.Count() == 1 - && changedProps.First() == "QtLastBackgroundBuild")) { - return; - } - - if (QtVsToolsPackage.Instance.Options.BuildDebugInformation) { - Messages.Print(string.Format( - "{0:HH:mm:ss.FFF} QtProjectTracker({1}): Changed [{2}] {3}", - DateTime.Now, Thread.CurrentThread.ManagedThreadId, - config.ProjectConfiguration.Name, - config.UnconfiguredProject.FullPath)); - } - await QtProjectIntellisense.RefreshAsync(Project, config.ProjectConfiguration.Name); - } - - async Task OnProjectUnloading(object sender, EventArgs args) + async Task OnProjectUnloadingAsync(object sender, EventArgs args) { var project = sender as ConfiguredProject; if (project == null || project.Services == null) @@ -274,18 +210,16 @@ project.UnconfiguredProject.FullPath)); } lock (CriticalSection) { - if (Subscribers != null) { - Subscribers.ForEach(s => s.Dispose()); - Subscribers.Clear(); - Subscribers = null; - } - project.ProjectUnloading -= OnProjectUnloading; - Instances.TryRemove(Project.FullName, out QtProjectTracker tracker); + project.ProjectUnloading -= OnProjectUnloadingAsync; + Instances.TryRemove(project.UnconfiguredProject.FullPath, out QtProjectTracker _); } + await Task.Yield(); } void BeginInitStatus() { + ThreadHelper.ThrowIfNotOnUIThread(); + lock (StaticCriticalSection) { if (InitStatus != null) return; @@ -303,9 +237,8 @@ PercentComplete = 0 }) as ITaskHandler2; - } catch (Exception e) { - Messages.Print( - e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace); + } catch (Exception exception) { + exception.Log(); } InitStatus.RegisterTask(new Task(() => throw new InvalidOperationException())); } @@ -320,13 +253,12 @@ InitStatus.Progress.Report(new TaskProgressData { ProgressText = string.Format("{0} ({1} project(s) remaining)", - Project.Name, InitQueue.Count), + Path.GetFileNameWithoutExtension(ProjectPath), InitQueue.Count), CanBeCanceled = true, PercentComplete = percentComplete }); - } catch (Exception e) { - Messages.Print( - e.Message + "\r\n\r\nStacktrace:\r\n" + e.StackTrace); + } catch (Exception exception) { + exception.Log(); } } } -- Gitblit v1.9.1