Forge
csharpdeeb25a2
1using System.Collections.ObjectModel;
2using System.IO;
3using System.Threading;
4using System.Threading.Tasks;
5using CascadeIDE.Models;
6using CascadeIDE.ViewModels;
7using CommunityToolkit.Mvvm.ComponentModel;
8
9namespace CascadeIDE.Features.Workspace;
10
11/// <summary>
12/// Состояние сессии решения: путь, дерево, выбор; фоновая загрузка дерева.
13/// <see cref="MainWindowViewModel"/> — композитор: документы, редактор, сервисы после загрузки.
14/// </summary>
15public sealed partial class SolutionWorkspaceViewModel : ViewModelBase
16{
17 private long _loadVersion;
18
19 [ObservableProperty]
20 private string _solutionPath = "";
21
22 [ObservableProperty]
23 private string _solutionLoadError = "";
24
25 [ObservableProperty]
26 private ObservableCollection<SolutionItem> _solutionRoots = [];
27
28 [ObservableProperty]
29 private SolutionItem? _selectedSolutionItem;
30
31 public long CurrentLoadVersion => Interlocked.Read(ref _loadVersion);
32
33 public void Clear()
34 {
35 SelectedSolutionItem = null;
36 SolutionPath = "";
37 SolutionLoadError = "";
38 SolutionRoots.Clear();
39 }
40
41 /// <summary>
42 /// Загрузка дерева в пуле потоков; применение к VM — на UI (<see cref="MainWindowViewModel.LoadSolutionAsync"/>).
43 /// </summary>
44 public async Task<(SolutionItem? Root, string? NormalizedSolutionPath, string? Error, long LoadVersion)> LoadSolutionTreeAsync(
45 string path,
46 CancellationToken cancellationToken = default)
47 {
48 var loadVersion = Interlocked.Increment(ref _loadVersion);
49
50 try
51 {
52 var (root, error) = await Task.Run(() =>
53 {
54 var trimmed = path.Trim();
55 string normalizedProbe;
56 try
57 {
58 normalizedProbe = CanonicalFilePath.Normalize(trimmed);
59 }
60 catch
61 {
62 normalizedProbe = trimmed;
63 }
64
65 if (Directory.Exists(normalizedProbe))
66 {
67 var r = FolderWorkspaceTreeBuilder.TryBuild(normalizedProbe, out var err);
68 return (r, err);
69 }
70
71 var sln = SolutionParser.Load(trimmed, out var err2);
72 return (sln, err2);
73 }, cancellationToken).ConfigureAwait(false);
74
75 if (root is null)
76 return (null, null, error ?? "Не удалось загрузить решение.", loadVersion);
77
78 var normalizedSolutionPath = root.FullPath;
79 if (string.IsNullOrEmpty(normalizedSolutionPath))
80 {
81 try { normalizedSolutionPath = CanonicalFilePath.Normalize(path); }
82 catch { normalizedSolutionPath = path; }
83 }
84
85 return (root, normalizedSolutionPath, null, loadVersion);
86 }
87 catch (OperationCanceledException)
88 {
89 return (null, null, "Загрузка решения отменена.", loadVersion);
90 }
91 catch (Exception ex)
92 {
93 return (null, null, "Ошибка загрузки решения: " + ex.Message, loadVersion);
94 }
95 }
96}
97
View only · write via MCP/CIDE