From e3f765064e6fb5c09134f2f15dbe275b608c6f79 Mon Sep 17 00:00:00 2001 From: Phlam Sicusa Date: Wed, 21 Feb 2024 17:09:11 +0800 Subject: [PATCH] add UnsafeSetId for entity hosts & storages --- Sia/Entities/DynEntityRef.cs | 8 ++++++-- Sia/Entities/Hosts/StorageEntityHost.cs | 20 ++----------------- Sia/Entities/Interfaces/IEntityHost.cs | 4 +--- Sia/Storages/Common/StorageBase.cs | 5 ++++- Sia/Storages/Common/UnversionedStorageBase.cs | 6 +++--- Sia/Storages/Interfaces/IStorage.cs | 3 ++- Sia/Systems/SystemLibrary.cs | 3 +++ Sia/Worlds/WrappedWorldEntityHost.cs | 13 +++--------- 8 files changed, 24 insertions(+), 38 deletions(-) diff --git a/Sia/Entities/DynEntityRef.cs b/Sia/Entities/DynEntityRef.cs index e1da462..2c20544 100644 --- a/Sia/Entities/DynEntityRef.cs +++ b/Sia/Entities/DynEntityRef.cs @@ -15,9 +15,13 @@ private class EntityMover(IEntityCreator creator) : IEntityMover var bundle = Bundle.Create( current.UnsafeCast().AsRef(), newComponent); + var id = current.Slot.Id; current.Dispose(); - return (creator.CreateEntity(bundle), - new EntityMover>(creator)); + + var newEntity = creator.CreateEntity(bundle); + newEntity.Host.UnsafeSetId(newEntity.Slot, id); + + return (newEntity, new EntityMover>(creator)); } } diff --git a/Sia/Entities/Hosts/StorageEntityHost.cs b/Sia/Entities/Hosts/StorageEntityHost.cs index 2ddf5e1..4ab458b 100644 --- a/Sia/Entities/Hosts/StorageEntityHost.cs +++ b/Sia/Entities/Hosts/StorageEntityHost.cs @@ -26,68 +26,52 @@ public class StorageEntityHost<[DynamicallyAccessedMembers(DynamicallyAccessedMe public TStorage Storage { get; } = managedStorage; - [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool ContainsCommon() => Descriptor.GetOffset() != -1; - [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool ContainsCommon(Type componentType) => Descriptor.GetOffset(componentType) != -1; - [MethodImpl(MethodImplOptions.AggressiveInlining)] EntityRef IEntityHost.Create() => Create(); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public virtual EntityRef Create() => new(Storage.AllocateSlot(), this); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public virtual EntityRef Create(in T initial) => new(Storage.AllocateSlot(initial), this); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public virtual void Release(scoped in StorageSlot slot) => Storage.Release(slot); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool IsValid(scoped in StorageSlot slot) => Storage.IsValid(slot); - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public EntityDescriptor GetDescriptor(scoped in StorageSlot slot) - => Descriptor; + public void UnsafeSetId(scoped in StorageSlot slot, int id) + => Storage.UnsafeSetId(slot, id); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe ref byte GetByteRef(scoped in StorageSlot slot) => ref Unsafe.AsRef(Unsafe.AsPointer(ref Storage.GetRef(slot))); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe ref byte UnsafeGetByteRef(scoped in StorageSlot slot) => ref Unsafe.AsRef(Unsafe.AsPointer(ref Storage.UnsafeGetRef(slot))); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public ref T GetRef(scoped in StorageSlot slot) => ref Storage.GetRef(slot); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public ref T UnsafeGetRef(scoped in StorageSlot slot) => ref Storage.UnsafeGetRef(slot); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public object Box(scoped in StorageSlot slot) => Storage.GetRef(slot); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public IEnumerator GetEnumerator() { foreach (var slot in Storage) { yield return new(slot, this); } } - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Dispose() { Storage.Dispose(); diff --git a/Sia/Entities/Interfaces/IEntityHost.cs b/Sia/Entities/Interfaces/IEntityHost.cs index 7ff8308..2d04e19 100644 --- a/Sia/Entities/Interfaces/IEntityHost.cs +++ b/Sia/Entities/Interfaces/IEntityHost.cs @@ -1,6 +1,3 @@ -using System.Runtime.CompilerServices; -using CommunityToolkit.HighPerformance.Buffers; - namespace Sia; public interface IEntityHost : IEnumerable, IDisposable @@ -20,6 +17,7 @@ public interface IEntityHost : IEnumerable, IDisposable ref byte GetByteRef(scoped in StorageSlot slot); ref byte UnsafeGetByteRef(scoped in StorageSlot slot); + void UnsafeSetId(scoped in StorageSlot slot, int id); object Box(scoped in StorageSlot slot); } diff --git a/Sia/Storages/Common/StorageBase.cs b/Sia/Storages/Common/StorageBase.cs index 942df65..e020ede 100644 --- a/Sia/Storages/Common/StorageBase.cs +++ b/Sia/Storages/Common/StorageBase.cs @@ -4,7 +4,6 @@ namespace Sia; using System.Collections.Generic; using System.Runtime.CompilerServices; using CommunityToolkit.HighPerformance; -using CommunityToolkit.HighPerformance.Buffers; public abstract class StorageBase : IStorage where T : struct @@ -86,6 +85,10 @@ public ref T GetRef(scoped in StorageSlot slot) public ref T UnsafeGetRef(scoped in StorageSlot slot) => ref GetRef(slot.Index); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void UnsafeSetId(scoped in StorageSlot slot, int id) + => _allocatedSlots.ValueSpan[slot.Index].Id = id; + protected abstract void Allocate(int slot); protected abstract void Release(int slot); protected abstract ref T GetRef(int slot); diff --git a/Sia/Storages/Common/UnversionedStorageBase.cs b/Sia/Storages/Common/UnversionedStorageBase.cs index af4f998..483a416 100644 --- a/Sia/Storages/Common/UnversionedStorageBase.cs +++ b/Sia/Storages/Common/UnversionedStorageBase.cs @@ -3,7 +3,6 @@ namespace Sia; using System.Collections; using System.Collections.Generic; using System.Runtime.CompilerServices; -using CommunityToolkit.HighPerformance.Buffers; public abstract class UnversionedStorageBase : IStorage where T : struct @@ -50,11 +49,12 @@ public void Release(scoped in StorageSlot slot) public bool IsValid(scoped in StorageSlot slot) => true; - [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void UnsafeSetId(scoped in StorageSlot slot, int id) + => _allocatedSlots.ValueSpan[slot.Index].Id = id; + public ref T GetRef(scoped in StorageSlot slot) => ref GetRef(slot.Index); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public ref T UnsafeGetRef(scoped in StorageSlot slot) => ref GetRef(slot.Index); diff --git a/Sia/Storages/Interfaces/IStorage.cs b/Sia/Storages/Interfaces/IStorage.cs index 8657731..3919c99 100644 --- a/Sia/Storages/Interfaces/IStorage.cs +++ b/Sia/Storages/Interfaces/IStorage.cs @@ -1,7 +1,6 @@ namespace Sia; using System.Runtime.CompilerServices; -using CommunityToolkit.HighPerformance.Buffers; public interface IStorage : IEnumerable, IDisposable { @@ -12,6 +11,8 @@ public interface IStorage : IEnumerable, IDisposable StorageSlot AllocateSlot(); void Release(scoped in StorageSlot slot); bool IsValid(scoped in StorageSlot slot); + + void UnsafeSetId(scoped in StorageSlot slot, int id); } public interface IStorage : IStorage diff --git a/Sia/Systems/SystemLibrary.cs b/Sia/Systems/SystemLibrary.cs index ef00255..aa911a6 100644 --- a/Sia/Systems/SystemLibrary.cs +++ b/Sia/Systems/SystemLibrary.cs @@ -85,6 +85,9 @@ public void Release(in StorageSlot slot) public bool IsValid(in StorageSlot slot) => Host.IsValid(slot); + public void UnsafeSetId(scoped in StorageSlot slot, int id) + => Host.UnsafeSetId(slot, id); + public ref byte GetByteRef(scoped in StorageSlot slot) => ref Host.GetByteRef(slot); diff --git a/Sia/Worlds/WrappedWorldEntityHost.cs b/Sia/Worlds/WrappedWorldEntityHost.cs index 05580fe..cf997bb 100644 --- a/Sia/Worlds/WrappedWorldEntityHost.cs +++ b/Sia/Worlds/WrappedWorldEntityHost.cs @@ -4,7 +4,6 @@ namespace Sia; using System.Collections; using System.Collections.Generic; using System.Runtime.CompilerServices; -using CommunityToolkit.HighPerformance.Buffers; public sealed record WrappedWorldEntityHost : IEntityHost, IReactiveEntityHost where T : struct @@ -72,34 +71,28 @@ public void Release(scoped in StorageSlot slot) OnEntityReleased?.Invoke(entity); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool IsValid(scoped in StorageSlot slot) => _host.IsValid(slot); - [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void UnsafeSetId(scoped in StorageSlot slot, int id) + => _host.UnsafeSetId(slot, id); + public unsafe ref byte GetByteRef(scoped in StorageSlot slot) => ref _host.GetByteRef(slot); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public unsafe ref byte UnsafeGetByteRef(scoped in StorageSlot slot) => ref _host.UnsafeGetByteRef(slot); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public ref T GetRef(scoped in StorageSlot slot) => ref _host.GetRef(slot); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public ref T UnsafeGetRef(scoped in StorageSlot slot) => ref _host.UnsafeGetRef(slot); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public object Box(scoped in StorageSlot slot) => _host.Box(slot); - [MethodImpl(MethodImplOptions.AggressiveInlining)] public IEnumerator GetEnumerator() => _host.GetEnumerator(); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] IEnumerator IEnumerable.GetEnumerator() => _host.GetEnumerator(); public void Dispose() => _host.Dispose();