Forge
csharpdeeb25a2
1using CascadeIDE.Contracts;
2
3namespace CascadeIDE.Features.Terminal.DataAcquisition;
4
5/// <summary>Lifecycle wrapper for ConPTY/redirected integrated shell session.</summary>
6[IoBoundary]
7internal sealed class IntegratedTerminalSessionHost : IDisposable
8{
9 private readonly Func<string?> _getSolutionPath;
10 private IIntegratedShellSession? _session;
11 private bool _disposed;
12
13 public IntegratedTerminalSessionHost(Func<string?> getSolutionPath) =>
14 _getSolutionPath = getSolutionPath;
15
16 public event Action<byte[]>? OutputReceived;
17
18 public event Action<int>? SessionExited;
19
20 public string? ActiveShellDisplayName { get; private set; }
21
22 public void EnsureStarted()
23 {
24 ObjectDisposedException.ThrowIf(_disposed, this);
25 if (_session is not null)
26 return;
27
28 var workingDirectory = IntegratedShellLaunch.ResolveWorkingDirectory(_getSolutionPath());
29 var launch = IntegratedShellLaunch.ResolveLaunchConfiguration(workingDirectory);
30 ActiveShellDisplayName = launch.DisplayName;
31
32 _session = IntegratedShellLaunch.CreateSession(launch);
33 _session.DataReceived += OnDataReceived;
34 _session.Exited += OnSessionExited;
35 }
36
37 public void SendInput(byte[] input)
38 {
39 ObjectDisposedException.ThrowIf(_disposed, this);
40 if (input.Length == 0)
41 return;
42
43 EnsureStarted();
44 _session!.Send(input);
45 }
46
47 public void Resize(int cols, int rows)
48 {
49 ObjectDisposedException.ThrowIf(_disposed, this);
50 if (_session is null || cols <= 0 || rows <= 0)
51 return;
52
53 _session.Resize(cols, rows);
54 }
55
56 public void Dispose()
57 {
58 if (_disposed)
59 return;
60
61 _disposed = true;
62 if (_session is not null)
63 {
64 _session.DataReceived -= OnDataReceived;
65 _session.Exited -= OnSessionExited;
66 _session.Dispose();
67 _session = null;
68 }
69 }
70
71 private void OnDataReceived(byte[] data)
72 {
73 if (data.Length == 0)
74 return;
75
76 OutputReceived?.Invoke(data);
77 }
78
79 private void OnSessionExited(int exitCode)
80 {
81 SessionExited?.Invoke(exitCode);
82 if (_session is not null)
83 {
84 _session.DataReceived -= OnDataReceived;
85 _session.Exited -= OnSessionExited;
86 _session.Dispose();
87 _session = null;
88 }
89 }
90}
91
View only · write via MCP/CIDE