Skip to content

Commit 7bb2025

Browse files
Add files via upload
1 parent a64d8f7 commit 7bb2025

3 files changed

Lines changed: 234 additions & 25 deletions

File tree

src/InputSources/IInputSource.cs

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
1-
// AzimuthConsole/InputSources/IInputSource.cs
2-
using AzimuthConsole.Commands;
3-
4-
namespace AzimuthConsole.InputSources
5-
{
6-
public class CommandReceivedEventArgs : EventArgs
7-
{
8-
public string Line { get; }
9-
public ICommandContext Context { get; }
10-
11-
public CommandReceivedEventArgs(string line, ICommandContext context)
12-
{
13-
Line = line;
14-
Context = context;
15-
}
16-
}
17-
18-
public interface IInputSource
19-
{
20-
string SourceId { get; }
21-
event EventHandler<CommandReceivedEventArgs>? CommandReceived;
22-
Task StartAsync();
23-
Task StopAsync();
24-
}
25-
}
1+
// AzimuthConsole/InputSources/IInputSource.cs
2+
using AzimuthConsole.Commands;
3+
4+
namespace AzimuthConsole.InputSources
5+
{
6+
public class CommandReceivedEventArgs : EventArgs
7+
{
8+
public string Line { get; }
9+
public ICommandContext Context { get; }
10+
11+
public CommandReceivedEventArgs(string line, ICommandContext context)
12+
{
13+
Line = line;
14+
Context = context;
15+
}
16+
}
17+
18+
public interface IInputSource
19+
{
20+
string SourceId { get; }
21+
event EventHandler<CommandReceivedEventArgs>? CommandReceived;
22+
Task StartAsync();
23+
Task StopAsync();
24+
}
25+
}
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
// AzimuthConsole/InputSources/TerminalInputSource.cs
2+
using AzimuthConsole.Commands;
3+
using AzimuthConsole.Contexts;
4+
using System.Text;
5+
6+
namespace AzimuthConsole.InputSources
7+
{
8+
public class TerminalInputSource : IInputSource
9+
{
10+
private readonly CancellationTokenSource _cts = new();
11+
private readonly TerminalContext _context = new();
12+
private readonly StringBuilder _inputBuffer = new();
13+
14+
public string SourceId => "terminal";
15+
public event EventHandler<CommandReceivedEventArgs>? CommandReceived;
16+
public event Action? OnToggleLogMode;
17+
18+
public Task StartAsync()
19+
{
20+
_ = ReadLoopAsync(_cts.Token);
21+
return Task.CompletedTask;
22+
}
23+
24+
public Task StopAsync()
25+
{
26+
_cts.Cancel();
27+
return Task.CompletedTask;
28+
}
29+
30+
public void PrintPrompt()
31+
{
32+
Console.Write("> ");
33+
}
34+
35+
private async Task ReadLoopAsync(CancellationToken ct)
36+
{
37+
PrintPrompt();
38+
39+
while (!ct.IsCancellationRequested)
40+
{
41+
if (Console.KeyAvailable)
42+
{
43+
var key = Console.ReadKey(true);
44+
45+
// F1 — Help
46+
if (key.Key == ConsoleKey.F1 && key.Modifiers == 0)
47+
{
48+
Console.WriteLine();
49+
CommandReceived?.Invoke(this, new CommandReceivedEventArgs("HELP", _context));
50+
PrintPrompt();
51+
continue;
52+
}
53+
54+
// F12 — переключение режима логирования
55+
if (key.Key == ConsoleKey.F12 && key.Modifiers == 0)
56+
{
57+
OnToggleLogMode?.Invoke();
58+
continue;
59+
}
60+
61+
// Ctrl+L — очистка экрана
62+
if (key.Key == ConsoleKey.L && key.Modifiers == ConsoleModifiers.Control)
63+
{
64+
Console.Clear();
65+
_inputBuffer.Clear();
66+
PrintPrompt();
67+
continue;
68+
}
69+
70+
// В ReadLoopAsync:
71+
72+
// Ctrl+N — OCON
73+
if (key.Key == ConsoleKey.N && key.Modifiers == ConsoleModifiers.Control)
74+
{
75+
Console.WriteLine();
76+
CommandReceived?.Invoke(this, new CommandReceivedEventArgs("OCON", _context));
77+
PrintPrompt();
78+
continue;
79+
}
80+
81+
// Ctrl+Shift+N — CCON
82+
if (key.Key == ConsoleKey.N && key.Modifiers == (ConsoleModifiers.Control | ConsoleModifiers.Shift))
83+
{
84+
Console.WriteLine();
85+
CommandReceived?.Invoke(this, new CommandReceivedEventArgs("CCON", _context));
86+
PrintPrompt();
87+
continue;
88+
}
89+
90+
// Ctrl+I — RITG
91+
if (key.Key == ConsoleKey.I && key.Modifiers == ConsoleModifiers.Control)
92+
{
93+
Console.WriteLine();
94+
CommandReceived?.Invoke(this, new CommandReceivedEventArgs("RITG", _context));
95+
PrintPrompt();
96+
continue;
97+
}
98+
99+
// Ctrl+Shift+I — PITG
100+
if (key.Key == ConsoleKey.I && key.Modifiers == (ConsoleModifiers.Control | ConsoleModifiers.Shift))
101+
{
102+
Console.WriteLine();
103+
CommandReceived?.Invoke(this, new CommandReceivedEventArgs("PITG", _context));
104+
PrintPrompt();
105+
continue;
106+
}
107+
108+
// Ctrl+E — Exit
109+
if (key.Key == ConsoleKey.E && key.Modifiers == ConsoleModifiers.Control)
110+
{
111+
Console.WriteLine();
112+
CommandReceived?.Invoke(this, new CommandReceivedEventArgs("EXIT", _context));
113+
PrintPrompt();
114+
continue;
115+
}
116+
117+
// Enter — отправка команды
118+
if (key.Key == ConsoleKey.Enter)
119+
{
120+
Console.WriteLine();
121+
var line = _inputBuffer.ToString();
122+
_inputBuffer.Clear();
123+
124+
if (!string.IsNullOrWhiteSpace(line))
125+
CommandReceived?.Invoke(this, new CommandReceivedEventArgs(line, _context));
126+
127+
PrintPrompt();
128+
continue;
129+
}
130+
131+
// Backspace
132+
if (key.Key == ConsoleKey.Backspace && _inputBuffer.Length > 0)
133+
{
134+
_inputBuffer.Remove(_inputBuffer.Length - 1, 1);
135+
Console.Write("\b \b");
136+
continue;
137+
}
138+
139+
// Обычные символы
140+
if (!char.IsControl(key.KeyChar))
141+
{
142+
_inputBuffer.Append(key.KeyChar);
143+
Console.Write(key.KeyChar);
144+
}
145+
}
146+
147+
await Task.Delay(10, ct);
148+
}
149+
}
150+
}
151+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// AzimuthConsole/InputSources/UdpRctrlInputSource.cs
2+
using System.Net;
3+
using System.Net.Sockets;
4+
using System.Text;
5+
using AzimuthConsole.Commands;
6+
using AzimuthConsole.Contexts;
7+
8+
namespace AzimuthConsole.InputSources
9+
{
10+
public class UdpRctrlInputSource : IInputSource
11+
{
12+
private readonly int _port;
13+
private UdpClient? _udp;
14+
private CancellationTokenSource? _cts;
15+
16+
public string SourceId => "rctrl";
17+
public event EventHandler<CommandReceivedEventArgs>? CommandReceived;
18+
19+
public UdpRctrlInputSource(int port)
20+
{
21+
_port = port;
22+
}
23+
24+
public async Task StartAsync()
25+
{
26+
_cts = new CancellationTokenSource();
27+
_udp = new UdpClient(_port);
28+
await Task.Run(() => ReceiveLoop(_cts.Token));
29+
}
30+
31+
public Task StopAsync()
32+
{
33+
_cts?.Cancel();
34+
_udp?.Close();
35+
_udp?.Dispose();
36+
return Task.CompletedTask;
37+
}
38+
39+
private async Task ReceiveLoop(CancellationToken ct)
40+
{
41+
while (!ct.IsCancellationRequested && _udp != null)
42+
{
43+
try
44+
{
45+
var result = await _udp.ReceiveAsync(ct);
46+
var line = Encoding.ASCII.GetString(result.Buffer).Trim();
47+
if (!string.IsNullOrWhiteSpace(line))
48+
{
49+
var ctx = new UdpRctrlContext(_udp, result.RemoteEndPoint);
50+
CommandReceived?.Invoke(this, new CommandReceivedEventArgs(line, ctx));
51+
}
52+
}
53+
catch (OperationCanceledException) { }
54+
catch (ObjectDisposedException) { }
55+
}
56+
}
57+
}
58+
}

0 commit comments

Comments
 (0)