Forge
csharpdeeb25a2
1using System.Collections.ObjectModel;
2using CascadeIDE.Cockpit.Channels.WorkspaceHealth;
3using CascadeIDE.Cockpit.Composition.HostSurface;
4using CascadeIDE.Cockpit.Composition.WorkspaceHealth;
5using CascadeIDE.Cockpit.ComputingUnits.IdeHealth;
6using CascadeIDE.Cockpit.DataBus;
7
8namespace CascadeIDE.ViewModels;
9
10/// <summary>Связка с Workspace Health.</summary>
11public partial class MainWindowViewModel
12{
13 /// <summary>Свойства, читающие кэш после <see cref="RebuildIdeHealth"/>; держать в одном месте с циклом notify.</summary>
14 private static readonly string[] IdeHealthRebuildPresentationNames =
15 [
16 nameof(IdeHealthMountPayload),
17 nameof(PfdIdeHealthMountContext),
18 nameof(MfdIdeHealthMountContext),
19 nameof(IdeHealthBuildText),
20 nameof(IdeHealthBuildCockpitShort),
21 nameof(IdeHealthTestsText),
22 nameof(IdeHealthTestsCockpitShort),
23 nameof(IdeHealthDebugText),
24 nameof(IdeHealthDebugCockpitShort),
25 ];
26
27 private bool _inIdeHealthRebuild;
28 private IdeHealthInputSnapshot? _lastIdeHealthInputSnapshot;
29 private IdeHealthStatusMountPayload? _lastIdeHealthMountPayload;
30
31 /// <summary>Упорядоченные сегменты для <see cref="Views.WorkspaceHealthStripView"/> (поверхность); строит <see cref="IIdeHealthSurfaceCompositor"/> из снимка канала (ADR 0036 п.1→п.3).</summary>
32 public ObservableCollection<IdeHealthSegment> IdeHealthSegments { get; } = new();
33
34 /// <summary>Сид DataBus + отображаемых строк git до первого <see cref="RefreshGitSummaryAsync"/> (ADR 0099).</summary>
35 private void SeedIdeHealthDataBus()
36 {
37 _ideDataBus.Publish(new StartupProjectPathChanged(StartupProjectCsprojFullPath));
38 _ideDataBus.Publish(new GitStateChanged(Chrome.WorkspaceHealthGitText, Chrome.WorkspaceHealthGitCockpitShort));
39 _ideDataBus.Publish(new IdeHostStateChanged(
40 CSharpLspProcessActive: false,
41 MarkdownLspProcessActive: false,
42 CSharpLspHostPresent: false,
43 MarkdownLspHostPresent: false));
44 }
45
46 /// <summary>Каноническое LSP-состояние C#/MD для DataBus, IDE Health (страт C) и ER; только с UI thread.</summary>
47 private IdeHostStateChanged CaptureIdeHostLspState() =>
48 new(
49 CSharpLspProcessActive: _csharpLspHost is { IsActive: true },
50 MarkdownLspProcessActive: _markdownLspHost is { IsActive: true },
51 CSharpLspHostPresent: _csharpLspHost != null,
52 MarkdownLspHostPresent: _markdownLspHost != null);
53
54 /// <summary>Публикация в IDE DataBus и сразу <see cref="RebuildIdeHealth"/>; вызывать с UI thread (обработчики <see cref="IdeHealthSnapshotUnit"/> согласованы с <see cref="RebuildIdeHealth"/>, ADR 0099).</summary>
55 private void PublishToIdeDataBusAndRebuild<T>(T evt)
56 {
57 _ideDataBus.Publish(evt);
58 RebuildIdeHealth();
59 }
60
61 /// <summary>Состояние сборки на шину после await с <c>ConfigureAwait(false)</c>; гарантирует пересбор полосы IDE Health на UI-потоке.</summary>
62 internal Task PublishIdeBuildStateOnUiAsync(BuildStateChanged e) =>
63 UiScheduler.Default.InvokeAsync(() => PublishToIdeDataBusAndRebuild(e));
64
65 /// <summary>LSP → шина + пересбор полосы; вызывать с UI thread.</summary>
66 private void PublishIdeHostLspToDataBusAndRebuild() =>
67 PublishToIdeDataBusAndRebuild(CaptureIdeHostLspState());
68
69 /// <summary>Один вход для git → шина + пересбор полосы (без дублирования по <see cref="UiChromeViewModel.WorkspaceHealthGitText"/>).</summary>
70 private void PublishGitToIdeDataBusAndRebuildIdeHealth() =>
71 PublishToIdeDataBusAndRebuild(
72 new GitStateChanged(Chrome.WorkspaceHealthGitText, Chrome.WorkspaceHealthGitCockpitShort));
73
74 /// <summary>Освободить подписки канала (при закрытии окна). Идемпотентно.</summary>
75 public void ReleaseWorkspaceHealthChannel()
76 {
77 if (_workspaceHealth is IDisposable d)
78 d.Dispose();
79 }
80
81 private void RebuildIdeHealth()
82 {
83 if (_inIdeHealthRebuild)
84 return;
85 _inIdeHealthRebuild = true;
86 try
87 {
88 var snapshot = _workspaceHealth.Build(IdeHealthChannelContext.Default);
89 _lastIdeHealthInputSnapshot = snapshot;
90 _lastIdeHealthMountPayload = new IdeHealthStatusMountPayload(
91 snapshot.Solution.Build.CockpitShort,
92 snapshot.Solution.Tests.CockpitShort,
93 snapshot.Solution.Debug.CockpitShort,
94 SafetyLevel);
95 _workspaceHealthSurfaceCompositor.Compose(
96 IdeHealthSegments,
97 snapshot,
98 new IdeHealthSurfaceDecision(Enabled: true));
99 foreach (var name in IdeHealthRebuildPresentationNames)
100 OnPropertyChanged(name);
101 }
102 finally
103 {
104 _inIdeHealthRebuild = false;
105 }
106 }
107}
108
View only · write via MCP/CIDE