This commit is contained in:
2023-07-29 10:58:06 +03:00
parent 0a8d761cc1
commit c01b748031
16 changed files with 133 additions and 118 deletions
+1 -1
View File
@@ -1,12 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<LangVersion>10</LangVersion> <LangVersion>10</LangVersion>
<RootNamespace>Ragon.Client.Simulation</RootNamespace> <RootNamespace>Ragon.Client.Simulation</RootNamespace>
<Authors>Eduard Kargin (Edmand46)</Authors> <Authors>Eduard Kargin (Edmand46)</Authors>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' "> <PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
+3 -10
View File
@@ -60,7 +60,7 @@ namespace Ragon.Client
_sceneId = sceneId; _sceneId = sceneId;
} }
internal void Attach(RagonClient client, ushort entityId, ushort entityType, bool hasAuthority, RagonPlayer owner, RagonPayload payload) internal void Attach(RagonClient client, ushort entityId, ushort entityType, bool hasAuthority, RagonPlayer owner)
{ {
Type = entityType; Type = entityType;
Id = entityId; Id = entityId;
@@ -70,7 +70,6 @@ namespace Ragon.Client
HasAuthority = hasAuthority; HasAuthority = hasAuthority;
_client = client; _client = client;
_spawnPayload = payload;
Attached?.Invoke(this); Attached?.Invoke(this);
} }
@@ -96,15 +95,9 @@ namespace Ragon.Client
return payload; return payload;
} }
public void AttachPayload(IRagonPayload? payload) public void AttachPayload(RagonPayload payload)
{ {
if (payload == null) return; _spawnPayload = payload;
var buffer = new RagonBuffer();
payload.Serialize(buffer);
_spawnPayload = new RagonPayload();
_spawnPayload.Read(buffer);
} }
public T GetAttachPayload<T>() where T : IRagonPayload, new() public T GetAttachPayload<T>() where T : IRagonPayload, new()
+3 -7
View File
@@ -19,7 +19,7 @@ using Ragon.Protocol;
namespace Ragon.Client; namespace Ragon.Client;
public struct RagonPayload public class RagonPayload
{ {
private readonly uint[] _data = new uint[128]; private readonly uint[] _data = new uint[128];
private readonly int _size = 0; private readonly int _size = 0;
@@ -32,16 +32,12 @@ public struct RagonPayload
public void Read(RagonBuffer buffer) public void Read(RagonBuffer buffer)
{ {
var readOnlySpan = _data.AsSpan(); buffer.ReadArray(_data, _size);
buffer.ReadSpan(ref readOnlySpan, _size);
} }
public void Write(RagonBuffer buffer) public void Write(RagonBuffer buffer)
{ {
ReadOnlySpan<uint> readOnlySpan = _data.AsSpan(); buffer.WriteArray(_data, _size);
buffer.WriteSpan(ref readOnlySpan, _size);
} }
public override string ToString() public override string ToString()
@@ -23,16 +23,18 @@ internal class EntityCreateHandler : Handler
private readonly RagonClient _client; private readonly RagonClient _client;
private readonly RagonPlayerCache _playerCache; private readonly RagonPlayerCache _playerCache;
private readonly RagonEntityCache _entityCache; private readonly RagonEntityCache _entityCache;
private readonly IRagonEntityListener _entityListener;
public EntityCreateHandler( public EntityCreateHandler(
RagonClient client, RagonClient client,
RagonPlayerCache playerCache, RagonPlayerCache playerCache,
RagonEntityCache entityCache RagonEntityCache entityCache,
IRagonEntityListener entityListener
) )
{ {
_client = client; _client = client;
_entityCache = entityCache; _entityCache = entityCache;
_playerCache = playerCache; _playerCache = playerCache;
_entityListener = entityListener;
} }
public void Handle(RagonBuffer buffer) public void Handle(RagonBuffer buffer)
@@ -52,7 +54,13 @@ internal class EntityCreateHandler : Handler
} }
var hasAuthority = _playerCache.Local.Id == player.Id; var hasAuthority = _playerCache.Local.Id == player.Id;
var entity = _entityCache.OnCreate(attachId, entityType, 0, entityId, hasAuthority); var entity = _entityCache.TryGetEntity(attachId, entityType, 0, entityId, hasAuthority, out var hasCreated);
entity.Attach(_client, entityId, entityType, hasAuthority, player, payload);
entity.AttachPayload(payload);
if (hasCreated)
_entityListener.OnEntityCreated(entity);
entity.Attach(_client, entityId, entityType, hasAuthority, player);
} }
} }
@@ -53,8 +53,9 @@ internal class PlayerLeftHandler : Handler
toDeleteIds[i] = entityId; toDeleteIds[i] = entityId;
} }
var emptyPayload = new RagonPayload(0);
foreach (var id in toDeleteIds) foreach (var id in toDeleteIds)
_entityCache.OnDestroy(id, new RagonPayload()); _entityCache.OnDestroy(id, emptyPayload);
} }
} }
} }
+44 -16
View File
@@ -22,19 +22,22 @@ namespace Ragon.Client;
internal class SnapshotHandler : Handler internal class SnapshotHandler : Handler
{ {
private RagonClient _client; private readonly IRagonEntityListener _entityListener;
private RagonListenerList _listenerList; private readonly RagonClient _client;
private RagonEntityCache _entityCache; private readonly RagonListenerList _listenerList;
private RagonPlayerCache _playerCache; private readonly RagonEntityCache _entityCache;
private readonly RagonPlayerCache _playerCache;
public SnapshotHandler( public SnapshotHandler(
RagonClient ragonClient, RagonClient ragonClient,
RagonListenerList listenerList, RagonListenerList listenerList,
RagonEntityCache entityCache, RagonEntityCache entityCache,
RagonPlayerCache playerCache RagonPlayerCache playerCache,
IRagonEntityListener entityListener
) )
{ {
_client = ragonClient; _client = ragonClient;
_entityListener = entityListener;
_listenerList = listenerList; _listenerList = listenerList;
_entityCache = entityCache; _entityCache = entityCache;
_playerCache = playerCache; _playerCache = playerCache;
@@ -49,9 +52,12 @@ internal class SnapshotHandler : Handler
var playerPeerId = buffer.ReadUShort(); var playerPeerId = buffer.ReadUShort();
var playerId = buffer.ReadString(); var playerId = buffer.ReadString();
var playerName = buffer.ReadString(); var playerName = buffer.ReadString();
_playerCache.AddPlayer(playerPeerId, playerId, playerName); _playerCache.AddPlayer(playerPeerId, playerId, playerName);
RagonLog.Trace($"Player {playerPeerId} - {playerId} - {playerName}");
} }
var dynamicEntities = buffer.ReadUShort(); var dynamicEntities = buffer.ReadUShort();
RagonLog.Trace("Dynamic Entities: " + dynamicEntities); RagonLog.Trace("Dynamic Entities: " + dynamicEntities);
for (var i = 0; i < dynamicEntities; i++) for (var i = 0; i < dynamicEntities; i++)
@@ -60,16 +66,27 @@ internal class SnapshotHandler : Handler
var entityId = buffer.ReadUShort(); var entityId = buffer.ReadUShort();
var ownerPeerId = buffer.ReadUShort(); var ownerPeerId = buffer.ReadUShort();
var payloadSize = buffer.ReadUShort(); var payloadSize = buffer.ReadUShort();
var player = _playerCache.GetPlayerByPeer(ownerPeerId);
var payload = new RagonPayload(payloadSize); var payload = new RagonPayload(payloadSize);
payload.Read(buffer); payload.Read(buffer);
RagonLog.Trace($"Entity {entityType} - {entityId} - {ownerPeerId} - {payloadSize}");
var player = _playerCache.GetPlayerByPeer(ownerPeerId);
if (player == null)
{
RagonLog.Error($"Player not found with peerId: ${ownerPeerId}");
return;
}
var hasAuthority = _playerCache.Local.Id == player.Id; var hasAuthority = _playerCache.Local.Id == player.Id;
var entity = _entityCache.OnCreate(0, entityType, 0, entityId, hasAuthority); var entity = _entityCache.TryGetEntity(0, entityType, 0, entityId, hasAuthority, out _);
entity.Read(buffer); entity.Read(buffer);
entity.Attach(_client, entityId, entityType, hasAuthority, player, payload); entity.AttachPayload(payload);
_entityListener.OnEntityCreated(entity);
entity.Attach(_client, entityId, entityType, hasAuthority, player);
} }
var staticEntities = buffer.ReadUShort(); var staticEntities = buffer.ReadUShort();
@@ -81,18 +98,29 @@ internal class SnapshotHandler : Handler
var staticId = buffer.ReadUShort(); var staticId = buffer.ReadUShort();
var ownerPeerId = buffer.ReadUShort(); var ownerPeerId = buffer.ReadUShort();
var payloadSize = buffer.ReadUShort(); var payloadSize = buffer.ReadUShort();
var player = _playerCache.GetPlayerByPeer(ownerPeerId);
var payload = new RagonPayload(payloadSize); var payload = new RagonPayload(payloadSize);
payload.Read(buffer); payload.Read(buffer);
RagonLog.Trace($"Entity {entityType} - {entityId} - {ownerPeerId} - {payloadSize}");
var player = _playerCache.GetPlayerByPeer(ownerPeerId);
if (player == null)
{
RagonLog.Error($"Player not found with peerId: ${ownerPeerId}");
return;
}
var hasAuthority = _playerCache.Local.Id == player.Id; var hasAuthority = _playerCache.Local.Id == player.Id;
var entity = _entityCache.OnCreate(0, entityType, staticId, entityId, hasAuthority); var entity = _entityCache.TryGetEntity(0, entityType, staticId, entityId, hasAuthority, out _);
entity.Read(buffer); entity.Read(buffer);
entity.Attach(_client, entityId, entityType, hasAuthority, player, payload); entity.AttachPayload(payload);
_entityListener.OnEntityCreated(entity);
entity.Attach(_client, entityId, entityType, hasAuthority, player);
} }
_listenerList.OnJoined(); _listenerList.OnJoined();
} }
} }
+3 -3
View File
@@ -99,7 +99,7 @@ namespace Ragon.Client
_session = new RagonSession(this, _readBuffer); _session = new RagonSession(this, _readBuffer);
_playerCache = new RagonPlayerCache(); _playerCache = new RagonPlayerCache();
_entityCache = new RagonEntityCache(this, _playerCache, _entityListener, _sceneCollector); _entityCache = new RagonEntityCache(this, _playerCache, _sceneCollector);
_handlers = new Handler[byte.MaxValue]; _handlers = new Handler[byte.MaxValue];
_handlers[(byte)RagonOperation.AUTHORIZED_SUCCESS] = new AuthorizeSuccessHandler(_listenerList); _handlers[(byte)RagonOperation.AUTHORIZED_SUCCESS] = new AuthorizeSuccessHandler(_listenerList);
@@ -112,11 +112,11 @@ namespace Ragon.Client
_handlers[(byte)RagonOperation.PLAYER_JOINED] = new PlayerJoinHandler(_playerCache, _listenerList); _handlers[(byte)RagonOperation.PLAYER_JOINED] = new PlayerJoinHandler(_playerCache, _listenerList);
_handlers[(byte)RagonOperation.PLAYER_LEAVED] = new PlayerLeftHandler(_entityCache, _playerCache, _listenerList); _handlers[(byte)RagonOperation.PLAYER_LEAVED] = new PlayerLeftHandler(_entityCache, _playerCache, _listenerList);
_handlers[(byte)RagonOperation.LOAD_SCENE] = new SceneLoadHandler(this, _listenerList); _handlers[(byte)RagonOperation.LOAD_SCENE] = new SceneLoadHandler(this, _listenerList);
_handlers[(byte)RagonOperation.CREATE_ENTITY] = new EntityCreateHandler(this, _playerCache, _entityCache); _handlers[(byte)RagonOperation.CREATE_ENTITY] = new EntityCreateHandler(this, _playerCache, _entityCache, _entityListener);
_handlers[(byte)RagonOperation.REMOVE_ENTITY] = new EntityRemoveHandler(_entityCache); _handlers[(byte)RagonOperation.REMOVE_ENTITY] = new EntityRemoveHandler(_entityCache);
_handlers[(byte)RagonOperation.REPLICATE_ENTITY_STATE] = new StateEntityHandler(_entityCache); _handlers[(byte)RagonOperation.REPLICATE_ENTITY_STATE] = new StateEntityHandler(_entityCache);
_handlers[(byte)RagonOperation.REPLICATE_ENTITY_EVENT] = new EntityEventHandler(this, _playerCache, _entityCache); _handlers[(byte)RagonOperation.REPLICATE_ENTITY_EVENT] = new EntityEventHandler(this, _playerCache, _entityCache);
_handlers[(byte)RagonOperation.SNAPSHOT] = new SnapshotHandler(this, _listenerList, _entityCache, _playerCache); _handlers[(byte)RagonOperation.SNAPSHOT] = new SnapshotHandler(this, _listenerList, _entityCache, _playerCache, _entityListener);
var protocolRaw = RagonVersion.Parse(protocol); var protocolRaw = RagonVersion.Parse(protocol);
_connection.Connect(address, port, protocolRaw); _connection.Connect(address, port, protocolRaw);
+35 -33
View File
@@ -26,7 +26,6 @@ public sealed class RagonEntityCache
private readonly Dictionary<uint, RagonEntity> _sceneEntities = new(); private readonly Dictionary<uint, RagonEntity> _sceneEntities = new();
private readonly RagonClient _client; private readonly RagonClient _client;
private readonly IRagonEntityListener _entityListener;
private readonly IRagonSceneCollector _sceneCollector; private readonly IRagonSceneCollector _sceneCollector;
private readonly RagonPlayerCache _playerCache; private readonly RagonPlayerCache _playerCache;
@@ -35,12 +34,10 @@ public sealed class RagonEntityCache
public RagonEntityCache( public RagonEntityCache(
RagonClient client, RagonClient client,
RagonPlayerCache playerCache, RagonPlayerCache playerCache,
IRagonEntityListener listener,
IRagonSceneCollector sceneCollector IRagonSceneCollector sceneCollector
) )
{ {
_client = client; _client = client;
_entityListener = listener;
_sceneCollector = sceneCollector; _sceneCollector = sceneCollector;
_playerCache = playerCache; _playerCache = playerCache;
} }
@@ -50,7 +47,7 @@ public sealed class RagonEntityCache
return _entityMap.TryGetValue(id, out entity); return _entityMap.TryGetValue(id, out entity);
} }
public void Create(RagonEntity entity, IRagonPayload? spawnPayload) public void Create(RagonEntity entity, RagonPayload spawnPayload)
{ {
var attachId = (ushort)(_playerCache.Local.PeerId + _localEntitiesCounter++); var attachId = (ushort)(_playerCache.Local.PeerId + _localEntitiesCounter++);
var buffer = _client.Buffer; var buffer = _client.Buffer;
@@ -63,7 +60,7 @@ public sealed class RagonEntityCache
entity.State.WriteInfo(buffer); entity.State.WriteInfo(buffer);
spawnPayload?.Serialize(buffer); spawnPayload.Write(buffer);
_pendingEntities.Add(attachId, entity); _pendingEntities.Add(attachId, entity);
@@ -84,7 +81,7 @@ public sealed class RagonEntityCache
_client.Reliable.Send(sendData); _client.Reliable.Send(sendData);
} }
public void Destroy(RagonEntity entity, IRagonPayload? destroyPayload) public void Destroy(RagonEntity entity, RagonPayload destroyPayload)
{ {
if (!entity.IsAttached) if (!entity.IsAttached)
{ {
@@ -98,7 +95,7 @@ public sealed class RagonEntityCache
buffer.WriteOperation(RagonOperation.REMOVE_ENTITY); buffer.WriteOperation(RagonOperation.REMOVE_ENTITY);
buffer.WriteUShort(entity.Id); buffer.WriteUShort(entity.Id);
destroyPayload?.Serialize(buffer); destroyPayload.Write(buffer);
var sendData = buffer.ToArray(); var sendData = buffer.ToArray();
_client.Reliable.Send(sendData); _client.Reliable.Send(sendData);
@@ -162,61 +159,66 @@ public sealed class RagonEntityCache
internal void Cleanup() internal void Cleanup()
{ {
var payload = new RagonPayload(); var payload = new RagonPayload(0);
foreach (var ent in _entityList) foreach (var ent in _entityList)
ent.Detach(payload); ent.Detach(payload);
_entityMap.Clear(); _entityMap.Clear();
_entityList.Clear(); _entityList.Clear();
} }
internal RagonEntity OnCreate(ushort attachId, ushort entityType, ushort sceneId, ushort entityId, bool hasAuthority) internal RagonEntity TryGetEntity(ushort attachId, ushort entityType, ushort sceneId, ushort entityId, bool hasAuthority, out bool hasCreated)
{ {
if (sceneId > 0) if (sceneId > 0)
{ {
if (_sceneEntities.TryGetValue(sceneId, out var entity)) if (_sceneEntities.TryGetValue(sceneId, out var sceneEntity))
{ {
_entityMap.Add(entityId, entity); _entityMap.Add(entityId, sceneEntity);
if (hasAuthority) if (hasAuthority)
_entityList.Add(entity); _entityList.Add(sceneEntity);
return entity; hasCreated = false;
return sceneEntity;
} }
} }
if (_pendingEntities.Remove(attachId, out var existsEntity)) if (_pendingEntities.TryGetValue(attachId, out var pendingEntity))
{ {
_entityMap.Add(entityId, existsEntity); _pendingEntities.Remove(attachId);
_entityMap.Add(entityId, pendingEntity);
if (hasAuthority) if (hasAuthority)
_entityList.Add(existsEntity); _entityList.Add(pendingEntity);
return existsEntity; hasCreated = false;
return pendingEntity;
} }
else
{
var entity = new RagonEntity(entityType, sceneId);
_entityMap.Add(entityId, entity);
if (hasAuthority) var entity = new RagonEntity(entityType, sceneId);
_entityList.Add(entity);
_entityMap.Add(entityId, entity);
if (hasAuthority)
_entityList.Add(entity);
_entityListener.OnEntityCreated(entity); hasCreated = true;
return entity; return entity;
}
} }
internal void OnDestroy(ushort entityId, RagonPayload payload) internal void OnDestroy(ushort entityId, RagonPayload payload)
{ {
if (_entityMap.Remove(entityId, out var ragonEntity)) if (_entityMap.TryGetValue(entityId, out var entity))
{ {
_entityList.Remove(ragonEntity); _entityMap.Remove(entityId);
_entityList.Remove(entity);
ragonEntity.Detach(payload); entity.Detach(payload);
} }
} }
@@ -244,7 +246,7 @@ public sealed class RagonEntityCache
_entityList.Add(entity); _entityList.Add(entity);
else else
_entityList.Remove(entity); _entityList.Remove(entity);
entity.OnOwnershipChanged(player); entity.OnOwnershipChanged(player);
} }
else else
+2 -1
View File
@@ -64,9 +64,10 @@ public sealed class RagonPlayerCache
public void RemovePlayer(string playerId) public void RemovePlayer(string playerId)
{ {
if (_playersById.Remove(playerId, out var player)) if (_playersById.TryGetValue(playerId, out var player))
{ {
_players.Remove(player); _players.Remove(player);
_playersById.Remove(playerId);
_playersByConnection.Remove(player.PeerId); _playersByConnection.Remove(player.PeerId);
} }
} }
+2 -2
View File
@@ -55,10 +55,10 @@ namespace Ragon.Client
public void SceneLoaded() => _scene.SceneLoaded(); public void SceneLoaded() => _scene.SceneLoaded();
public void CreateEntity(RagonEntity entity) => CreateEntity(entity, null); public void CreateEntity(RagonEntity entity) => CreateEntity(entity, null);
public void CreateEntity(RagonEntity entity, IRagonPayload? payload) => _entityCache.Create(entity, payload); public void CreateEntity(RagonEntity entity, RagonPayload payload) => _entityCache.Create(entity, payload);
public void TransferEntity(RagonEntity entity, RagonPlayer player) => _entityCache.Transfer(entity, player); public void TransferEntity(RagonEntity entity, RagonPlayer player) => _entityCache.Transfer(entity, player);
public void DestroyEntity(RagonEntity entityId) => DestroyEntity(entityId, null); public void DestroyEntity(RagonEntity entityId) => DestroyEntity(entityId, null);
public void DestroyEntity(RagonEntity entityId, IRagonPayload? payload) => _entityCache.Destroy(entityId, payload); public void DestroyEntity(RagonEntity entityId, RagonPayload payload) => _entityCache.Destroy(entityId, payload);
} }
} }
+1 -1
View File
@@ -13,7 +13,7 @@
<RepositoryUrl>https://github.com/edmand46/Ragon</RepositoryUrl> <RepositoryUrl>https://github.com/edmand46/Ragon</RepositoryUrl>
<RepositoryType>Source</RepositoryType> <RepositoryType>Source</RepositoryType>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression> <PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<TargetFramework>netstandard2.1</TargetFramework> <TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
+18 -20
View File
@@ -58,7 +58,6 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Text; using System.Text;
@@ -245,7 +244,7 @@ namespace Ragon.Protocol
if (currentBucketIndex + 1 >= _buckets.Length) if (currentBucketIndex + 1 >= _buckets.Length)
Resize(1); Resize(1);
_buckets[currentBucketIndex] = (uint)result; _buckets[currentBucketIndex] = (uint)result;
_buckets[currentBucketIndex + 1] = (uint)(result >> 32); _buckets[currentBucketIndex + 1] = (uint)(result >> 32);
@@ -292,13 +291,13 @@ namespace Ragon.Protocol
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ReadSpan(ref Span<uint> data, int size) public void ReadArray(uint[] data, int size)
{ {
var used = _read & 0x0000001F; var used = _read & 0x0000001F;
var index = _read >> 5; var index = _read >> 5;
var limit = (size + 32 - 1) / 32; var limit = (size + 32 - 1) / 32;
var capacity = size; var capacity = size;
for (int i = 0; i < limit; i++) for (int i = 0; i < limit; i++)
{ {
var dataSize = capacity > 32 ? 32 : capacity; var dataSize = capacity > 32 ? 32 : capacity;
@@ -306,23 +305,24 @@ namespace Ragon.Protocol
var bucketRaw = (ulong)_buckets[index]; var bucketRaw = (ulong)_buckets[index];
if (index + 1 < _buckets.Length) if (index + 1 < _buckets.Length)
bucketRaw |= (ulong)_buckets[index + 1] << 32; bucketRaw |= (ulong)_buckets[index + 1] << 32;
var bucket = bucketRaw >> used; var bucket = bucketRaw >> used;
var result = bucket & mask; var result = bucket & mask;
data[i] = (uint)result; data[i] = (uint)result;
if (i + 1 < data.Length) if (i + 1 < data.Length)
data[i + 1] = (uint)(result >> 32); data[i + 1] = (uint)(result >> 32);
index += 1; index += 1;
capacity -= dataSize; capacity -= dataSize;
} }
_read += size; _read += size;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void WriteSpan(ref ReadOnlySpan<uint> data, int size) public void WriteArray(uint[] data, int size)
{ {
var used = _write & 0x0000001F; var used = _write & 0x0000001F;
var index = _write >> 5; var index = _write >> 5;
@@ -330,20 +330,20 @@ namespace Ragon.Protocol
if (index + limit >= _buckets.Length) if (index + limit >= _buckets.Length)
Resize(size); Resize(size);
for (var i = 0; i < limit; i += 1) for (var i = 0; i < limit; i += 1)
{ {
var prepared = (ulong) data[i] << used; var prepared = (ulong)data[i] << used;
var mask = (1UL << used) - 1; var mask = (1UL << used) - 1;
var scratch = _buckets[index] & mask; var scratch = _buckets[index] & mask;
var result = scratch | prepared; var result = scratch | prepared;
_buckets[index] = (uint)result; _buckets[index] = (uint)result;
_buckets[index + 1] = (uint)(result >> 32); _buckets[index + 1] = (uint)(result >> 32);
index += 1; index += 1;
} }
_write += size; _write += size;
} }
@@ -356,17 +356,15 @@ namespace Ragon.Protocol
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void FromBuffer(RagonBuffer buffer, int size) public void FromBuffer(RagonBuffer buffer, int size)
{ {
ReadOnlySpan<uint> data = buffer._buckets.AsSpan(); WriteArray(buffer._buckets, size);
WriteSpan(ref data, size);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToBuffer(RagonBuffer buffer, int size) public void ToBuffer(RagonBuffer buffer, int size)
{ {
var data = buffer._buckets.AsSpan(); ReadArray(buffer._buckets, size);
ReadSpan(ref data, size);
} }
public void FromArray(byte[] data) public void FromArray(byte[] data)
{ {
var length = data.Length; var length = data.Length;
+2 -5
View File
@@ -39,15 +39,12 @@ public class RagonEvent
public void Read(RagonBuffer buffer) public void Read(RagonBuffer buffer)
{ {
var readOnlySpan = _data.AsSpan(); buffer.ReadArray(_data, buffer.Capacity);
_size = buffer.Capacity;
buffer.ReadSpan(ref readOnlySpan, _size);
} }
public void Write(RagonBuffer buffer) public void Write(RagonBuffer buffer)
{ {
if (_size == 0) return; if (_size == 0) return;
ReadOnlySpan<uint> readOnlySpan = _data.AsSpan(); buffer.WriteArray(_data, _size);
buffer.WriteSpan(ref readOnlySpan, _size);
} }
} }
+2 -8
View File
@@ -28,19 +28,13 @@ public class RagonPayload
public void Read(RagonBuffer buffer) public void Read(RagonBuffer buffer)
{ {
var readOnlySpan = _data.AsSpan();
_size = buffer.Capacity; _size = buffer.Capacity;
buffer.ReadArray(_data, _size);
buffer.ReadSpan(ref readOnlySpan, _size);
} }
public void Write(RagonBuffer buffer) public void Write(RagonBuffer buffer)
{ {
if (_size == 0) return; if (_size == 0) return;
buffer.WriteArray(_data, _size);
ReadOnlySpan<uint> readOnlySpan = _data.AsSpan();
buffer.WriteSpan(ref readOnlySpan, _size);
} }
} }
+3 -5
View File
@@ -37,15 +37,14 @@ public class RagonProperty : RagonPayload
public void Read(RagonBuffer buffer) public void Read(RagonBuffer buffer)
{ {
var readOnlySpan = _data.AsSpan();
if (IsFixed) if (IsFixed)
{ {
buffer.ReadSpan(ref readOnlySpan, Size); buffer.ReadArray(_data, Size);
} }
else else
{ {
Size = (int) buffer.Read(); Size = (int) buffer.Read();
buffer.ReadSpan(ref readOnlySpan, Size); buffer.ReadArray(_data, Size);
} }
IsDirty = true; IsDirty = true;
@@ -53,8 +52,7 @@ public class RagonProperty : RagonPayload
public void Write(RagonBuffer buffer) public void Write(RagonBuffer buffer)
{ {
ReadOnlySpan<uint> readOnlySpan = _data.AsSpan(); buffer.WriteArray(_data, Size);
buffer.WriteSpan(ref readOnlySpan, Size);
} }
public void Clear() public void Clear()
@@ -42,7 +42,6 @@ public sealed class SceneLoadedOperation : IRagonOperation
if (player == owner) if (player == owner)
{ {
var statics = reader.ReadUShort(); var statics = reader.ReadUShort();
for (var staticIndex = 0; staticIndex < statics; staticIndex++) for (var staticIndex = 0; staticIndex < statics; staticIndex++)
{ {