remove allocation on raw data replication

This commit is contained in:
2023-10-13 10:58:15 +03:00
parent e25f42f9ff
commit d2577e5d1f
2 changed files with 40 additions and 31 deletions
+28 -18
View File
@@ -19,8 +19,31 @@ using Ragon.Protocol;
namespace Ragon.Client namespace Ragon.Client
{ {
public sealed class RagonEntity: IDisposable public sealed class RagonEntity : IDisposable
{ {
private class EventSubscription : IDisposable
{
private List<Action<RagonPlayer, IRagonEvent>> _callbacks;
private List<Action<RagonPlayer, IRagonEvent>> _localCallbacks;
private Action<RagonPlayer, IRagonEvent> _callback;
public EventSubscription(
List<Action<RagonPlayer, IRagonEvent>> callbacks,
List<Action<RagonPlayer, IRagonEvent>> localCallbacks,
Action<RagonPlayer, IRagonEvent> callback)
{
_callbacks = callbacks;
_localCallbacks = localCallbacks;
_callback = callback;
}
public void Dispose()
{
_callbacks.Remove(_callback);
_localCallbacks.Remove(_callback);
}
}
private delegate void OnEventDelegate(RagonPlayer player, RagonBuffer serializer); private delegate void OnEventDelegate(RagonPlayer player, RagonBuffer serializer);
private RagonClient _client; private RagonClient _client;
@@ -189,19 +212,18 @@ namespace Ragon.Client
_client.Reliable.Send(sendData); _client.Reliable.Send(sendData);
} }
public Action<RagonPlayer, IRagonEvent> OnEvent<TEvent>(Action<RagonPlayer, TEvent> callback) where TEvent : IRagonEvent, new() public IDisposable OnEvent<TEvent>(Action<RagonPlayer, TEvent> callback) where TEvent : IRagonEvent, new()
{ {
var t = new TEvent(); var t = new TEvent();
var eventCode = _client.Event.GetEventCode(t); var eventCode = _client.Event.GetEventCode(t);
var action = (RagonPlayer player, IRagonEvent eventData) => callback.Invoke(player, (TEvent)eventData); var action = (RagonPlayer player, IRagonEvent eventData) => callback.Invoke(player, (TEvent)eventData);
if (!_listeners.TryGetValue(eventCode, out var callbacks)) if (!_listeners.TryGetValue(eventCode, out var callbacks))
{ {
callbacks = new List<Action<RagonPlayer, IRagonEvent>>(); callbacks = new List<Action<RagonPlayer, IRagonEvent>>();
_listeners.Add(eventCode, callbacks); _listeners.Add(eventCode, callbacks);
} }
if (!_localListeners.TryGetValue(eventCode, out var localCallbacks)) if (!_localListeners.TryGetValue(eventCode, out var localCallbacks))
{ {
localCallbacks = new List<Action<RagonPlayer, IRagonEvent>>(); localCallbacks = new List<Action<RagonPlayer, IRagonEvent>>();
@@ -222,19 +244,7 @@ namespace Ragon.Client
}); });
} }
return action; return new EventSubscription(callbacks, localCallbacks, action);
}
public void OffEvent<TEvent>(Action<RagonPlayer, IRagonEvent> callback) where TEvent : IRagonEvent, new()
{
var t = new TEvent();
var eventCode = _client.Event.GetEventCode(t);
if (_listeners.TryGetValue(eventCode, out var callbacks))
callbacks.Remove(callback);
if (_localListeners.TryGetValue(eventCode, out var localCallbacks))
localCallbacks.Remove(callback);
} }
internal void Write(RagonBuffer buffer) internal void Write(RagonBuffer buffer)
@@ -30,21 +30,20 @@ public sealed class RoomDataOperation : BaseOperation
{ {
var player = context.RoomPlayer; var player = context.RoomPlayer;
var room = context.Room; var room = context.Room;
var data = Reader.RawData; var data = Reader.RawData;
var dataSize = data.Length - 1;
Writer.Clear(); var headerSize = 3;
Writer.WriteOperation(RagonOperation.REPLICATE_RAW_DATA); var size = headerSize + dataSize;
Writer.WriteUShort(player.Connection.Id);
var playerData = Writer.ToArray();
var payloadData = data;
var size = playerData.Length + payloadData.Length;
var sendData = new byte[size]; var sendData = new byte[size];
var peerId = player.Connection.Id;
Array.Copy(playerData, 0, sendData, 0, playerData.Length);
Array.Copy(payloadData, 1, sendData, playerData.Length, payloadData.Length - 1); sendData[0] = (byte)RagonOperation.REPLICATE_RAW_DATA;
sendData[1] = (byte)peerId;
sendData[2] = (byte)(peerId >> 8);
Array.Copy(data, 1, sendData, headerSize, dataSize);
room.Broadcast(sendData, channel); room.Broadcast(sendData, channel);
} }
} }