109 lines
2.7 KiB
Beef
109 lines
2.7 KiB
Beef
|
namespace Theater_ECS;
|
||
|
|
||
|
using System;
|
||
|
using System.Threading;
|
||
|
using System.Collections;
|
||
|
|
||
|
class ComponentManager
|
||
|
{
|
||
|
private Monitor _Lock = new .() ~ delete _;
|
||
|
|
||
|
private int_cosize _ComponentSize = -1;
|
||
|
private readonly int _IndexSize = sizeof(int_cosize);
|
||
|
|
||
|
private int_cosize _Next = 0;
|
||
|
private List<uint8> _Data = null ~ delete _;
|
||
|
private List<int_cosize> _Available = new .() ~ delete _;
|
||
|
private HashSet<int_cosize> _Deleted = new .() ~ delete _;
|
||
|
|
||
|
///Make the component manager useable for a specific type of component
|
||
|
public void Initialize<T>(int_cosize count) where T : struct
|
||
|
{
|
||
|
_ComponentSize = sizeof(T);
|
||
|
_Data = new .( //So that we dont have to realloc as frequently
|
||
|
(_IndexSize + _ComponentSize) * count
|
||
|
);
|
||
|
}
|
||
|
|
||
|
///Creates space for a new component instance and returns a pointer to it
|
||
|
public (Component, void*) Create(Entity owner)
|
||
|
{
|
||
|
if (_Available.Count > 0)
|
||
|
{
|
||
|
var idx = _Available.PopFront();
|
||
|
_Deleted.Remove(idx);
|
||
|
|
||
|
*(int_cosize*)(void*)&_Data[idx * (_ComponentSize + _IndexSize)] = owner;
|
||
|
void* toReturn = (void*)&_Data[idx * (_ComponentSize + _IndexSize) + _IndexSize];
|
||
|
return (
|
||
|
idx,
|
||
|
toReturn
|
||
|
);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Grow();
|
||
|
*(int_cosize*)(void*)(_Data.Ptr + (_Next * (_ComponentSize + _IndexSize))) = owner;
|
||
|
//This calculates to the next biggest position + the offset of the index
|
||
|
void* toReturn = (void*)(_Data.Ptr + (_Next * (_ComponentSize + _IndexSize) + _IndexSize));
|
||
|
return (
|
||
|
_Next++,
|
||
|
toReturn
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
///Remove an entry, and returns a pointer to the removed object, if you want to
|
||
|
public Result<void*> Remove(int_cosize idx)
|
||
|
{
|
||
|
if (idx >= _Next || _Deleted.Contains(idx))
|
||
|
return .Err;
|
||
|
|
||
|
*(int_cosize*)(void*)&_Data[idx * (_ComponentSize + _IndexSize)] = -1;
|
||
|
|
||
|
_Deleted.Add(idx);
|
||
|
|
||
|
return .Ok(
|
||
|
(void*)(_Data.Ptr + idx * (_ComponentSize + _IndexSize) + _IndexSize)
|
||
|
);
|
||
|
}
|
||
|
|
||
|
public int_cosize Count
|
||
|
{
|
||
|
get
|
||
|
{
|
||
|
return (.)(_Data.Count / (_ComponentSize + _IndexSize));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
public Span<(Entity, T)> GetAll<T>() where T : struct
|
||
|
{
|
||
|
return .((.)(void*)_Data.Ptr, Count);
|
||
|
}
|
||
|
|
||
|
[Unchecked]
|
||
|
public T* Get<T>(int_cosize idx) where T : struct
|
||
|
{
|
||
|
return (T*)(void*)(_Data.Ptr + idx * (_ComponentSize + _IndexSize) + _IndexSize);
|
||
|
}
|
||
|
|
||
|
[Unchecked]
|
||
|
public void GetEntities(List<Entity> list)
|
||
|
{
|
||
|
var ec = (_Data.Count / (_ComponentSize + _IndexSize));
|
||
|
list.GrowUninitialized(ec);
|
||
|
for (int i < ec)
|
||
|
*(list.Ptr + (i)) = *(Entity*)(void*)(_Data.Ptr +i * (_ComponentSize + _IndexSize));
|
||
|
}
|
||
|
|
||
|
public void Use() => _Lock.Enter();
|
||
|
public void StopUsing() => _Lock.Exit();
|
||
|
|
||
|
|
||
|
public void Grow(int_cosize amount = 1)
|
||
|
{ //Make more size useable
|
||
|
_Data.GrowUninitialized((_ComponentSize + _IndexSize) * amount);
|
||
|
}
|
||
|
|
||
|
}
|