unmanaged component store
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
408dd9bfeb
commit
255760a3d7
|
@ -8,7 +8,7 @@ namespace Encompass
|
||||||
{
|
{
|
||||||
private Dictionary<Type, TypedComponentStore> _stores = new Dictionary<Type, TypedComponentStore>(512);
|
private Dictionary<Type, TypedComponentStore> _stores = new Dictionary<Type, TypedComponentStore>(512);
|
||||||
public ComponentBitSet ComponentBitSet { get; private set; }
|
public ComponentBitSet ComponentBitSet { get; private set; }
|
||||||
private Dictionary<Type, int> _typeToIndex;
|
private readonly Dictionary<Type, int> _typeToIndex;
|
||||||
|
|
||||||
public ComponentStore(Dictionary<Type, int> typeToIndex)
|
public ComponentStore(Dictionary<Type, int> typeToIndex)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
using System;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
internal unsafe class FixedArray<T> : IDisposable where T : unmanaged
|
||||||
|
{
|
||||||
|
private void* _buffer;
|
||||||
|
|
||||||
|
public int Length { get; private set; }
|
||||||
|
|
||||||
|
public T this[int i]
|
||||||
|
{
|
||||||
|
get { return ReadElement(_buffer, i); }
|
||||||
|
set { WriteElement(_buffer, i, value); }
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe FixedArray(int length, bool clearMemory = false)
|
||||||
|
{
|
||||||
|
var bufferSize = Marshal.SizeOf<T>() * length;
|
||||||
|
_buffer = (void*)Alloc(bufferSize);
|
||||||
|
|
||||||
|
if (clearMemory)
|
||||||
|
{
|
||||||
|
Memset(_buffer, 0, bufferSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
Length = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ref T ByRef(int i)
|
||||||
|
{
|
||||||
|
return ref *(T*)((byte*)_buffer + i * sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
void IDisposable.Dispose()
|
||||||
|
{
|
||||||
|
Free((IntPtr)_buffer);
|
||||||
|
_buffer = null;
|
||||||
|
Length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static T ReadElement(void* buffer, int i)
|
||||||
|
{
|
||||||
|
return *(T*)((byte*)buffer + i * sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void WriteElement(void* buffer, int i, T value)
|
||||||
|
{
|
||||||
|
*(T*)((byte*)buffer + i * sizeof(T)) = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private unsafe static IntPtr Alloc(int size)
|
||||||
|
{
|
||||||
|
return Marshal.AllocHGlobal(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
public unsafe static void Free(IntPtr ptr)
|
||||||
|
{
|
||||||
|
if (ptr != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
Marshal.FreeHGlobal(ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private unsafe static void Memset(void* ptr, byte value, int count)
|
||||||
|
{
|
||||||
|
Unsafe.InitBlock(ptr, value, (uint)count);
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,11 +14,11 @@ namespace Encompass
|
||||||
public abstract void ClearPriorities();
|
public abstract void ClearPriorities();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class TypedComponentStore<TComponent> : TypedComponentStore where TComponent : unmanaged
|
internal unsafe class TypedComponentStore<TComponent> : TypedComponentStore where TComponent : unmanaged
|
||||||
{
|
{
|
||||||
private readonly Dictionary<int, int> _indices = new Dictionary<int, int>(512);
|
private readonly Dictionary<int, int> _indices = new Dictionary<int, int>(512);
|
||||||
private readonly Dictionary<int, int> _priorities = new Dictionary<int, int>(512);
|
private readonly Dictionary<int, int> _priorities = new Dictionary<int, int>(512);
|
||||||
private readonly TComponent[] _components = new TComponent[512];
|
private readonly FixedArray<TComponent> _components = new FixedArray<TComponent>(512); // TODO: allow specify size
|
||||||
private readonly IDManager _idManager = new IDManager();
|
private readonly IDManager _idManager = new IDManager();
|
||||||
|
|
||||||
public override int Count { get => _indices.Count; }
|
public override int Count { get => _indices.Count; }
|
||||||
|
@ -26,8 +26,7 @@ namespace Encompass
|
||||||
public unsafe ref readonly TComponent Get(int entityID)
|
public unsafe ref readonly TComponent Get(int entityID)
|
||||||
{
|
{
|
||||||
if (!_indices.ContainsKey(entityID)) { throw new Exceptions.NoComponentOfTypeOnEntityException("No component of type {0} exists on Entity with ID {1}", typeof(TComponent), entityID); }
|
if (!_indices.ContainsKey(entityID)) { throw new Exceptions.NoComponentOfTypeOnEntityException("No component of type {0} exists on Entity with ID {1}", typeof(TComponent), entityID); }
|
||||||
ref var refVal = ref _components[_indices[entityID]];
|
return ref _components.ByRef(_indices[entityID]);
|
||||||
return ref Unsafe.AsRef<TComponent>(Unsafe.AsPointer(ref refVal));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe void Set(int entityID, TComponent component)
|
public unsafe void Set(int entityID, TComponent component)
|
||||||
|
@ -54,7 +53,7 @@ namespace Encompass
|
||||||
_indices[entityID] = _idManager.NextID();
|
_indices[entityID] = _idManager.NextID();
|
||||||
}
|
}
|
||||||
|
|
||||||
_components[_indices[entityID]] = Unsafe.AsRef<TComponent>(Unsafe.AsPointer(ref component));
|
_components[_indices[entityID]] = component;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Remove(int entityID, int priority)
|
public override bool Remove(int entityID, int priority)
|
||||||
|
|
|
@ -48,7 +48,8 @@ namespace Tests
|
||||||
foreach (var addComponentTestMessage in ReadMessages<AddComponentTestMessage>())
|
foreach (var addComponentTestMessage in ReadMessages<AddComponentTestMessage>())
|
||||||
{
|
{
|
||||||
Assert.IsTrue(HasComponent<MockComponent>(addComponentTestMessage.entity));
|
Assert.IsTrue(HasComponent<MockComponent>(addComponentTestMessage.entity));
|
||||||
Assert.That(GetComponent<MockComponent>(addComponentTestMessage.entity), Is.EqualTo(addComponentTestMessage.mockComponent));
|
var gottenComponent = GetComponent<MockComponent>(addComponentTestMessage.entity);
|
||||||
|
gottenComponent.Should().BeEquivalentTo(addComponentTestMessage.mockComponent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue