-
Notifications
You must be signed in to change notification settings - Fork 0
/
X32Client.cs
129 lines (99 loc) · 3.34 KB
/
X32Client.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Suhock.Osc;
using Suhock.X32.Nodes;
namespace Suhock.X32;
public sealed class X32Client : IX32Client
{
public const int DefaultPort = 10023;
private readonly IOscQueryClient _queryClient;
public event EventHandler<OscMessage>? MessageReceived;
public event EventHandler<OscMessage>? MessageSent;
public ILogger<X32Client>? Logger { get; init; }
public X32Client(string address, int port = DefaultPort) : this(
new OscClient(new UdpClientConnection(address, port)))
{
}
public X32Client(IOscClient oscClient) : this(new OscQueryClient(oscClient))
{
}
public X32Client(IOscQueryClient queryClient)
{
_queryClient = queryClient;
_queryClient.MessageSent += (_, msg) =>
{
LogSend(msg);
MessageSent?.Invoke(this, msg);
};
_queryClient.MessageReceived += (_, msg) =>
{
LogReceive(msg);
MessageReceived?.Invoke(this, msg);
};
Root = new RootNode(queryClient, new OscMessageFactory());
}
public RootNode Root { get; }
public void Run()
{
_queryClient.Start();
}
public void Send(OscMessage msg)
{
LogSend(msg);
_queryClient.Send(msg);
}
public Task SendAsync(OscMessage msg) => SendAsync(msg, CancellationToken.None);
public async Task SendAsync(OscMessage msg, CancellationToken cancellationToken)
{
LogSend(msg);
await _queryClient.SendAsync(msg, cancellationToken).ConfigureAwait(false);
}
public Task Subscribe(CancellationToken cancellationToken)
{
async Task MessageLoop()
{
while (true)
{
await Root.XRemote().ConfigureAwait(false);
await Task.Delay(2000, cancellationToken).ConfigureAwait(false);
if (cancellationToken.IsCancellationRequested)
{
break;
}
}
}
return Task.Run(MessageLoop, cancellationToken);
}
public OscMessage Query(OscMessage msg) => Query(msg, 1000);
public OscMessage Query(OscMessage msg, int timeout) => Query(msg, msg.Address, timeout);
public OscMessage Query(OscMessage msg, string responseAddress, int timeout)
{
ThrowIfQueryClientNotListening();
return _queryClient.Query(msg, responseAddress, timeout);
}
public Task<OscMessage> QueryAsync(OscMessage msg, CancellationToken cancellationToken) =>
QueryAsync(msg, msg.Address, cancellationToken);
private void LogSend(OscMessage msg)
{
Logger?.LogInformation("Sending: {msg}", msg);
}
private void LogReceive(OscMessage msg)
{
Logger?.LogInformation("Receive: {msg}", msg);
}
public async Task<OscMessage> QueryAsync(OscMessage msg, string responseAddress,
CancellationToken cancellationToken)
{
ThrowIfQueryClientNotListening();
return await _queryClient.QueryAsync(msg, responseAddress, cancellationToken);
}
private void ThrowIfQueryClientNotListening()
{
if (!_queryClient.IsRunning)
{
throw new InvalidOperationException("Not listening");
}
}
}