remove locking from other connections too
This commit is contained in:
parent
0e93b1356f
commit
d9e9c28976
|
@ -27,8 +27,6 @@ internal sealed class ClientScreenServerConnection(
|
||||||
? null
|
? null
|
||||||
: new PlayerScreenData(logger, player);
|
: new PlayerScreenData(logger, player);
|
||||||
|
|
||||||
protected override ValueTask HandleMessageLockedAsync(Memory<byte> buffer) => throw new UnreachableException();
|
|
||||||
|
|
||||||
protected override ValueTask HandleMessageAsync(Memory<byte> _)
|
protected override ValueTask HandleMessageAsync(Memory<byte> _)
|
||||||
{
|
{
|
||||||
if (_wantsFrameOnTick != 0)
|
if (_wantsFrameOnTick != 0)
|
||||||
|
|
|
@ -23,7 +23,7 @@ internal sealed class ControlsServerConnection(
|
||||||
Shoot = 0x05
|
Shoot = 0x05
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override ValueTask HandleMessageLockedAsync(Memory<byte> buffer)
|
protected override ValueTask HandleMessageAsync(Memory<byte> buffer)
|
||||||
{
|
{
|
||||||
var type = (MessageType)buffer.Span[0];
|
var type = (MessageType)buffer.Span[0];
|
||||||
var control = (InputType)buffer.Span[1];
|
var control = (InputType)buffer.Span[1];
|
||||||
|
|
|
@ -11,37 +11,37 @@ internal sealed class PlayerInfoConnection(
|
||||||
MapEntityManager entityManager
|
MapEntityManager entityManager
|
||||||
) : WebsocketServerConnection(logger, new ByteChannelWebSocket(rawSocket, logger, 0))
|
) : WebsocketServerConnection(logger, new ByteChannelWebSocket(rawSocket, logger, 0))
|
||||||
{
|
{
|
||||||
private bool _wantsInfoOnTick = true;
|
private int _wantsInfoOnTick = 1;
|
||||||
private byte[] _lastMessage = [];
|
private byte[]? _lastMessage = null;
|
||||||
|
private byte[]? _nextMessage = null;
|
||||||
|
|
||||||
protected override ValueTask HandleMessageLockedAsync(Memory<byte> buffer)
|
protected override ValueTask HandleMessageAsync(Memory<byte> buffer)
|
||||||
{
|
{
|
||||||
var response = GetMessageToSend();
|
var next = Interlocked.Exchange(ref _nextMessage, null);
|
||||||
if (response == null)
|
if (next != null)
|
||||||
{
|
return SendAndDisposeAsync(next);
|
||||||
Logger.LogTrace("cannot respond directly, increasing wanted frames");
|
|
||||||
_wantsInfoOnTick = true;
|
|
||||||
return ValueTask.CompletedTask;
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.LogTrace("responding directly");
|
_wantsInfoOnTick = 1;
|
||||||
return Socket.SendTextAsync(response);
|
return ValueTask.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ValueTask OnGameTickAsync() => LockedAsync(() =>
|
public async ValueTask OnGameTickAsync()
|
||||||
{
|
{
|
||||||
if (!_wantsInfoOnTick)
|
await Task.Yield();
|
||||||
return ValueTask.CompletedTask;
|
|
||||||
|
|
||||||
var response = GetMessageToSend();
|
var response = GetMessageToSend();
|
||||||
if (response == null)
|
var wantsNow = Interlocked.Exchange(ref _wantsInfoOnTick, 0) != 0;
|
||||||
return ValueTask.CompletedTask;
|
|
||||||
|
|
||||||
Logger.LogTrace("responding indirectly");
|
if (wantsNow)
|
||||||
return Socket.SendTextAsync(response);
|
{
|
||||||
});
|
await SendAndDisposeAsync(response);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
private byte[]? GetMessageToSend()
|
Interlocked.Exchange(ref _nextMessage, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte[] GetMessageToSend()
|
||||||
{
|
{
|
||||||
var tank = entityManager.GetCurrentTankOfPlayer(player);
|
var tank = entityManager.GetCurrentTankOfPlayer(player);
|
||||||
|
|
||||||
|
@ -53,11 +53,14 @@ internal sealed class PlayerInfoConnection(
|
||||||
}
|
}
|
||||||
|
|
||||||
var info = new PlayerInfo(player.Name, player.Scores, player.Controls.ToDisplayString(), tankInfo);
|
var info = new PlayerInfo(player.Name, player.Scores, player.Controls.ToDisplayString(), tankInfo);
|
||||||
var response = JsonSerializer.SerializeToUtf8Bytes(info, AppSerializerContext.Default.PlayerInfo);
|
|
||||||
|
|
||||||
if (response.SequenceEqual(_lastMessage))
|
// TODO: switch to async version with pre-allocated buffer / IMemoryOwner
|
||||||
return null;
|
return JsonSerializer.SerializeToUtf8Bytes(info, AppSerializerContext.Default.PlayerInfo);
|
||||||
|
}
|
||||||
|
|
||||||
return _lastMessage = response;
|
private async ValueTask SendAndDisposeAsync(byte[] data)
|
||||||
|
{
|
||||||
|
await Socket.SendTextAsync(data);
|
||||||
|
Interlocked.Exchange(ref _lastMessage, data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,10 +22,7 @@ internal abstract class WebsocketServerConnection(
|
||||||
Logger.LogTrace("done receiving");
|
Logger.LogTrace("done receiving");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual ValueTask HandleMessageAsync(Memory<byte> buffer)
|
protected abstract ValueTask HandleMessageAsync(Memory<byte> buffer);
|
||||||
=> LockedAsync(() => HandleMessageLockedAsync(buffer));
|
|
||||||
|
|
||||||
protected abstract ValueTask HandleMessageLockedAsync(Memory<byte> buffer);
|
|
||||||
|
|
||||||
protected async ValueTask LockedAsync(Func<ValueTask> action)
|
protected async ValueTask LockedAsync(Func<ValueTask> action)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue