move backend to subfolder

This commit is contained in:
Vinzenz Schroeter 2024-04-21 12:38:03 +02:00
parent d4d1f2f981
commit 8d09663eff
80 changed files with 98 additions and 88 deletions

View file

@ -0,0 +1,17 @@
namespace DisplayCommands.Internals;
internal enum DisplayCommand : ushort
{
Clear = 0x0002,
Cp437Data = 0x0003,
CharBrightness = 0x0005,
Brightness = 0x0007,
HardReset = 0x000b,
FadeOut = 0x000d,
[Obsolete("ignored by display code")] BitmapLegacy = 0x0010,
BitmapLinear = 0x0012,
BitmapLinearWin = 0x0013,
BitmapLinearAnd = 0x0014,
BitmapLinearOr = 0x0015,
BitmapLinearXor = 0x0016
}

View file

@ -0,0 +1,126 @@
using System.Buffers;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using Microsoft.Extensions.Options;
namespace DisplayCommands.Internals;
internal sealed class DisplayConnection(IOptions<DisplayConfiguration> options) : IDisplayConnection, IDisposable
{
private readonly ArrayPool<byte> _arrayPool = ArrayPool<byte>.Shared;
private readonly UdpClient _udpClient = new(options.Value.Hostname, options.Value.Port);
public ValueTask SendClearAsync()
{
var header = new HeaderWindow { Command = (ushort)DisplayCommand.Clear };
return SendAsync(header, Memory<byte>.Empty);
}
public ValueTask SendCp437DataAsync(ushort x, ushort y, Cp437Grid grid)
{
var header = new HeaderWindow
{
Command = (ushort)DisplayCommand.Cp437Data,
Height = grid.Height,
Width = grid.Width,
PosX = x,
PosY = y
};
return SendAsync(header, grid.Data);
}
public ValueTask SendCharBrightnessAsync(ushort x, ushort y, ByteGrid luma)
{
var header = new HeaderWindow
{
Command = (ushort)DisplayCommand.CharBrightness,
PosX = x,
PosY = y,
Height = luma.Height,
Width = luma.Width
};
return SendAsync(header, luma.Data);
}
public async ValueTask SendBrightnessAsync(byte brightness)
{
var header = new HeaderWindow { Command = (ushort)DisplayCommand.Brightness };
var payloadBuffer = _arrayPool.Rent(1);
var payload = payloadBuffer.AsMemory(0, 1);
payload.Span[0] = brightness;
await SendAsync(header, payload);
_arrayPool.Return(payloadBuffer);
}
public ValueTask SendHardResetAsync()
{
var header = new HeaderWindow { Command = (ushort)DisplayCommand.HardReset };
return SendAsync(header, Memory<byte>.Empty);
}
public async ValueTask SendFadeOutAsync(byte loops)
{
var header = new HeaderWindow { Command = (ushort)DisplayCommand.FadeOut };
var payloadBuffer = _arrayPool.Rent(1);
var payload = payloadBuffer.AsMemory(0, 1);
payload.Span[0] = loops;
await SendAsync(header, payload);
_arrayPool.Return(payloadBuffer);
}
public ValueTask SendBitmapLinearWindowAsync(ushort x, ushort y, PixelGrid pixels)
{
var header = new HeaderWindow
{
Command = (ushort)DisplayCommand.BitmapLinearWin,
PosX = x,
PosY = y,
Width = (ushort)(pixels.Width / 8),
Height = pixels.Height
};
return SendAsync(header, pixels.Data);
}
public string GetLocalIPv4()
{
using var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0);
socket.Connect(options.Value.Hostname, options.Value.Port);
var endPoint = socket.LocalEndPoint as IPEndPoint ?? throw new NotSupportedException();
return endPoint.Address.ToString();
}
private async ValueTask SendAsync(HeaderWindow header, Memory<byte> payload)
{
int headerSize;
unsafe
{
// because we specified the struct layout, no platform-specific padding will be added and this is be safe.
headerSize = sizeof(HeaderWindow);
}
Debug.Assert(headerSize == 10);
var messageSize = headerSize + payload.Length;
var buffer = _arrayPool.Rent(messageSize);
var message = buffer.AsMemory(0, messageSize);
MemoryMarshal.Write(message.Span, header);
payload.CopyTo(message[headerSize..]);
await _udpClient.SendAsync(message);
_arrayPool.Return(buffer);
}
public void Dispose() => _udpClient.Dispose();
}

View file

@ -0,0 +1,10 @@
namespace DisplayCommands.Internals;
internal enum DisplaySubCommand : ushort
{
BitmapNormal = 0x0,
BitmapCompressZ = 0x677a,
BitmapCompressBz = 0x627a,
BitmapCompressLz = 0x6c7a,
BitmapCompressZs = 0x7a73
}

View file

@ -0,0 +1,19 @@
using System.Runtime.InteropServices;
using EndiannessSourceGenerator;
namespace DisplayCommands.Internals;
[StructEndianness(IsLittleEndian = false)]
[StructLayout(LayoutKind.Sequential, Pack = 16, Size = 10)]
internal partial struct HeaderBitmap
{
private ushort _command;
private ushort _offset;
private ushort _length;
private ushort _subCommand;
private ushort _reserved;
}

View file

@ -0,0 +1,19 @@
using System.Runtime.InteropServices;
using EndiannessSourceGenerator;
namespace DisplayCommands.Internals;
[StructEndianness(IsLittleEndian = false)]
[StructLayout(LayoutKind.Sequential, Pack = 16, Size = 10)]
internal partial struct HeaderWindow
{
private ushort _command;
private ushort _posX;
private ushort _posY;
private ushort _width;
private ushort _height;
}