reworkpool system/ add new pools

This commit is contained in:
Mikhail 2023-04-21 03:16:05 +08:00
parent 905cd3033a
commit 3a15b93da5
10 changed files with 353 additions and 333 deletions

View File

@ -53,16 +53,16 @@ namespace DCFApixels.DragonECS
public override inc_<TComponent> Include<TComponent>() where TComponent : struct public override inc_<TComponent> Include<TComponent>() where TComponent : struct
{ {
_inc.Add(_world.GetComponentID<TComponent>()); _inc.Add(_world.GetComponentID<TComponent>());
return new inc_<TComponent>(_world.GetOrCreatePool<TComponent>()); return new inc_<TComponent>(_world.GetPool<TComponent, EcsPool<TComponent>>());
} }
public override exc_<TComponent> Exclude<TComponent>() where TComponent : struct public override exc_<TComponent> Exclude<TComponent>() where TComponent : struct
{ {
_exc.Add(_world.GetComponentID<TComponent>()); _exc.Add(_world.GetComponentID<TComponent>());
return new exc_<TComponent>(_world.GetOrCreatePool<TComponent>()); return new exc_<TComponent>(_world.GetPool<TComponent, EcsPool<TComponent>>());
} }
public override opt_<TComponent> Optional<TComponent>() where TComponent : struct public override opt_<TComponent> Optional<TComponent>() where TComponent : struct
{ {
return new opt_<TComponent>(_world.GetOrCreatePool<TComponent>()); return new opt_<TComponent>(_world.GetPool<TComponent, EcsPool<TComponent>>());
} }
private void End(out EcsQueryMask mask) private void End(out EcsQueryMask mask)
@ -93,7 +93,8 @@ namespace DCFApixels.DragonECS
private ProfilerMarker _getEnumerator = new ProfilerMarker("EcsGraphQuery.Execute"); private ProfilerMarker _getEnumerator = new ProfilerMarker("EcsGraphQuery.Execute");
protected sealed override void OnBuildAfter() protected sealed override void OnBuildAfter()
{ {
attachPool = World.GetOrCreatePool<Edge>(); throw new NotImplementedException();
// attachPool = World.GetPool<Edge>();
} }
public sealed override void Execute() public sealed override void Execute()
{ {

View File

@ -81,80 +81,4 @@ namespace DCFApixels.DragonECS
public static implicit operator opt_<TComponent>(EcsQueryBuilderBase buider) => buider.Optional<TComponent>(); public static implicit operator opt_<TComponent>(EcsQueryBuilderBase buider) => buider.Optional<TComponent>();
} }
#endregion #endregion
// #region select_readonly
// [StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)]
// public readonly struct inc_readonly_<T> : IEcsQueryReadonlyField<T>
// where T : struct
// {
// internal readonly EcsPool<T> pool;
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// internal inc_readonly_(EcsPool<T> pool) => this.pool = pool;
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public ref T Read(ent entityID) => ref pool.Read(entityID.uniqueID);
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public bool Has(ent entityID) => pool.Has(entityID.uniqueID);
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
//
// public static implicit operator inc_readonly_<T>(EcsQueryBuilderBase buider) => buider.Include<T>();
// public static implicit operator inc_readonly_<T>(inc_<T> o) => new inc_readonly_<T>(o.pool);
// }
//
// [StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)]
// public readonly struct exc_readonly_<T> : IEcsQueryReadonlyField<T>
// where T : struct
// {
// internal readonly EcsPool<T> pool;
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// internal exc_readonly_(EcsPool<T> pool) => this.pool = pool;
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public ref T Read(ent entityID) => ref pool.Read(entityID.uniqueID);
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public bool Has(ent entityID) => pool.Has(entityID.uniqueID);
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
//
// public static implicit operator exc_readonly_<T>(EcsQueryBuilderBase buider) => buider.Exclude<T>();
// public static implicit operator exc_readonly_<T>(exc_<T> o) => new exc_readonly_<T>(o.pool);
// }
//
// [StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)]
// public readonly struct opt_readonly_<T> : IEcsQueryReadonlyField<T>
// where T : struct
// {
// internal readonly EcsPool<T> pool;
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// internal opt_readonly_(EcsPool<T> pool) => this.pool = pool;
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public ref T Read(ent entityID) => ref pool.Read(entityID.uniqueID);
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public bool Has(ent entityID) => pool.Has(entityID.uniqueID);
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
//
// public static implicit operator opt_readonly_<T>(EcsQueryBuilderBase buider) => buider.Optional<T>();
// public static implicit operator opt_readonly_<T>(opt_<T> o) => new opt_readonly_<T>(o.pool);
// }
// #endregion
//
// #region join
// [StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)]
// public readonly struct attach : IEcsQueryField<Edge>
// {
// internal readonly EcsPool<Edge> pool;
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// internal attach(EcsPool<Edge> pool) => this.pool = pool;
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public ref Edge Add(ent entityID) => ref pool.Add(entityID.uniqueID);
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public ref Edge Write(ent entityID) => ref pool.Write(entityID.uniqueID);
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public ref Edge Read(ent entityID) => ref pool.Read(entityID.uniqueID);
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public bool Has(ent entityID) => pool.Has(entityID.uniqueID);
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public void Del(ent entityID) => pool.Del(entityID.uniqueID);
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public static implicit operator attach(EcsQueryBuilderBase buider) => buider.Include<Edge>();
// public static implicit operator attach(inc_<Edge> o) => new attach(o.pool);
// }
// #endregion
} }

View File

@ -41,7 +41,7 @@ namespace DCFApixels.DragonECS
private int[] _delEntBuffer; private int[] _delEntBuffer;
private int _delEntBufferCount; private int _delEntBufferCount;
private IEcsPool[] _pools; private EcsPoolBase[] _pools;
private EcsNullPool _nullPool; private EcsNullPool _nullPool;
private EcsQueryBase[] _queries; private EcsQueryBase[] _queries;
@ -55,7 +55,7 @@ namespace DCFApixels.DragonECS
private IEcsEntityDestroy _entityDestry; private IEcsEntityDestroy _entityDestry;
#region GetterMethods #region GetterMethods
public ReadOnlySpan<IEcsPool> GetAllPools() => new ReadOnlySpan<IEcsPool>(_pools); public ReadOnlySpan<EcsPoolBase> GetAllPools() => new ReadOnlySpan<EcsPoolBase>(_pools);
public int GetComponentID<T>() => WorldMetaStorage.GetComponentId<T>(_worldArchetypeID);////ComponentType<TWorldArchetype>.uniqueID; public int GetComponentID<T>() => WorldMetaStorage.GetComponentId<T>(_worldArchetypeID);////ComponentType<TWorldArchetype>.uniqueID;
#endregion #endregion
@ -83,7 +83,7 @@ namespace DCFApixels.DragonECS
if (!_pipeline.IsInit) pipline.Init(); if (!_pipeline.IsInit) pipline.Init();
_entityDispenser = new IntDispenser(0); _entityDispenser = new IntDispenser(0);
_nullPool = EcsNullPool.instance; _nullPool = EcsNullPool.instance;
_pools = new IEcsPool[512]; _pools = new EcsPoolBase[512];
ArrayUtility.Fill(_pools, _nullPool); ArrayUtility.Fill(_pools, _nullPool);
_gens = new short[512]; _gens = new short[512];
@ -121,7 +121,7 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region GetPool #region GetPool
public IEcsPool<TComponent> GetOrCreatePool<TComponent>(Func<EcsWorld, IEcsPool> builder) where TComponent : struct public TPool GetPool<TComponent, TPool>() where TComponent : struct where TPool : EcsPoolBase, new()
{ {
int uniqueID = WorldMetaStorage.GetComponentId<TComponent>(_worldArchetypeID); int uniqueID = WorldMetaStorage.GetComponentId<TComponent>(_worldArchetypeID);
@ -133,9 +133,15 @@ namespace DCFApixels.DragonECS
} }
if (_pools[uniqueID] == _nullPool) if (_pools[uniqueID] == _nullPool)
_pools[uniqueID] = builder(this); {
var pool = new TPool();
_pools[uniqueID] = pool;
pool.InvokeInit(this);
return (IEcsPool<TComponent>)_pools[uniqueID]; //EcsDebug.Print(pool.GetType().FullName);
}
return (TPool)_pools[uniqueID];
} }
#endregion #endregion
@ -202,7 +208,7 @@ namespace DCFApixels.DragonECS
} }
} }
foreach (var item in _pools) foreach (var item in _pools)
item.OnWorldResize(_gens.Length); item.InvokeOnWorldResize(_gens.Length);
} }
_gens[entityID] |= short.MinValue; _gens[entityID] |= short.MinValue;
EcsEntity entity = new EcsEntity(entityID, _gens[entityID]++, uniqueID); EcsEntity entity = new EcsEntity(entityID, _gens[entityID]++, uniqueID);

View File

@ -22,7 +22,8 @@ namespace DCFApixels.DragonECS
public readonly short world; public readonly short world;
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public ent ToEnt() => EcsWorld.Worlds[world].EntityIsAlive(id, gen) ? new ent(id) : default; //public ent ToEnt() => EcsWorld.Worlds[world].EntityIsAlive(id, gen) ? new ent(id) : default;
public ent ToEnt() => new ent(id);
#region Constructors #region Constructors
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -72,10 +73,6 @@ namespace DCFApixels.DragonECS
public readonly partial struct EcsEntity public readonly partial struct EcsEntity
{ {
private static EcsProfilerMarker _IsNullMarker = new EcsProfilerMarker("EcsEntity.IsNull"); private static EcsProfilerMarker _IsNullMarker = new EcsProfilerMarker("EcsEntity.IsNull");
private static EcsProfilerMarker _ReadMarker = new EcsProfilerMarker("EcsEntity.Read");
private static EcsProfilerMarker _WriteMarker = new EcsProfilerMarker("EcsEntity.Write");
private static EcsProfilerMarker _HasMarker = new EcsProfilerMarker("EcsEntity.Has");
private static EcsProfilerMarker _DelMarker = new EcsProfilerMarker("EcsEntity.Del");
public bool IsNull public bool IsNull
{ {
@ -86,43 +83,6 @@ namespace DCFApixels.DragonECS
return this == NULL; return this == NULL;
} }
} }
public ref readonly T Read<T>()
where T : struct
{
//using (_ReadMarker.Auto())
return ref EcsWorld.Worlds[world].GetOrCreatePool<T>().Read(id);
}
public ref T Add<T>()
where T : struct
{
return ref EcsWorld.Worlds[world].GetOrCreatePool<T>().Add(id);
}
public ref T Write<T>()
where T : struct
{
//using (_WriteMarker.Auto())
return ref EcsWorld.Worlds[world].GetOrCreatePool<T>().Write(id);
}
public bool Has<T>()
where T : struct
{
//using (_HasMarker.Auto())
return EcsWorld.Worlds[world].GetOrCreatePool<T>().Has(id);
}
public bool NotHas<T>()
where T : struct
{
//using (_HasMarker.Auto())
return EcsWorld.Worlds[world].GetOrCreatePool<T>().Has(id);
}
public void Del<T>()
where T : struct
{
//using (_DelMarker.Auto())
EcsWorld.Worlds[world].GetOrCreatePool<T>().Del(id);
}
} }
public static partial class entExtensions public static partial class entExtensions

View File

@ -15,8 +15,8 @@ namespace DCFApixels.DragonECS
#region Methods #region Methods
public int GetComponentID<T>(); public int GetComponentID<T>();
public IEcsPool<TComponent> GetOrCreatePool<TComponent>(Func<EcsWorld, IEcsPool> builder) where TComponent : struct; public TPool GetPool<TComponent, TPool>() where TComponent : struct where TPool : EcsPoolBase, new();
public ReadOnlySpan<IEcsPool> GetAllPools(); public ReadOnlySpan<EcsPoolBase> GetAllPools();
public TQuery Where<TQuery>(out TQuery query) where TQuery : EcsQueryBase; public TQuery Where<TQuery>(out TQuery query) where TQuery : EcsQueryBase;
public TQuery Select<TQuery>() where TQuery : EcsQueryBase; public TQuery Select<TQuery>() where TQuery : EcsQueryBase;

111
src/Pools/EcsNotNullPool.cs Normal file
View File

@ -0,0 +1,111 @@
using System;
using System.Runtime.CompilerServices;
using Unity.Profiling;
namespace DCFApixels.DragonECS
{
public sealed class EcsNotNullPool<T> : EcsPoolBase
where T : struct
{
private EcsWorld _source;
private bool[] _entityFlags;// index = entityID / value = entityFlag;/ value = 0 = no entityID
private T[] _items; //sparse
private int _count;
private IEcsComponentReset<T> _componentResetHandler;
private PoolRunners _poolRunners;
#region Properites
public int Count => _count;
public int Capacity => _items.Length;
public sealed override EcsWorld World => _source;
public sealed override Type ComponentType => typeof(T);
#endregion
#region Init
protected override void Init(EcsWorld world)
{
_source = world;
_entityFlags = new bool[world.Capacity];
_items = new T[world.Capacity];
_count = 0;
_componentResetHandler = EcsComponentResetHandler<T>.instance;
_poolRunners = new PoolRunners(world.Pipeline);
}
#endregion
#region Write/Read/Has/Del
private ProfilerMarker _addMark = new ProfilerMarker("EcsPoo.Add");
private ProfilerMarker _writeMark = new ProfilerMarker("EcsPoo.Write");
private ProfilerMarker _readMark = new ProfilerMarker("EcsPoo.Read");
private ProfilerMarker _hasMark = new ProfilerMarker("EcsPoo.Has");
private ProfilerMarker _delMark = new ProfilerMarker("EcsPoo.Del");
public ref T Add(int entityID)
{
// using (_addMark.Auto())
// {
ref bool entityFlag = ref _entityFlags[entityID];
if (entityFlag == false)
{
entityFlag = true;
_count++;
_poolRunners.add.OnComponentAdd<T>(entityID);
}
_poolRunners.write.OnComponentWrite<T>(entityID);
return ref _items[entityID];
// }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref T Write(int entityID)
{
// using (_writeMark.Auto())
_poolRunners.write.OnComponentWrite<T>(entityID);
return ref _items[entityID];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref readonly T Read(int entityID)
{
// using (_readMark.Auto())
return ref _items[entityID];
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public sealed override bool Has(int entityID)
{
// using (_hasMark.Auto())
return _entityFlags[entityID];
}
public void Del(int entityID)
{
// using (_delMark.Auto())
// {
_componentResetHandler.Reset(ref _items[entityID]);
_entityFlags[entityID] = false;
_count--;
_poolRunners.del.OnComponentDel<T>(entityID);
// }
}
#endregion
#region WorldCallbacks
protected override void OnWorldResize(int newSize)
{
Array.Resize(ref _entityFlags, newSize);
Array.Resize(ref _items, newSize);
}
protected override void OnDestroy() { }
#endregion
}
public interface INotNullComponent { }
public static class INotNullComponentExt
{
public static EcsNotNullPool<TComponent> GetPool<TComponent>(this EcsWorld self)
where TComponent : struct, INotNullComponent
{
return self.GetPool<TComponent, EcsNotNullPool<TComponent>>();
}
}
}

View File

@ -4,104 +4,55 @@ using Unity.Profiling;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
public interface IEcsPoolBase public abstract class EcsPoolBase
{
#region Properties
public Type ComponentType { get; }
public EcsWorld World { get; }
public int Count { get; }
public int Capacity { get; }
#endregion
#region Methods
public bool Has(int entityID);
#endregion
}
public interface IEcsReadonlyPool : IEcsPoolBase
{
#region Methods
public object Get(int entityID);
#endregion
}
public interface IEcsPool : IEcsReadonlyPool
{
#region Methods
public void AddOrWrite(int entityID, object data);
public void Del(int entityID);
#endregion
}
public interface IEcsReadonlyPool<T> : IEcsReadonlyPool where T : struct
{
public ref readonly T Read(int entityID);
}
public interface IEcsPool<T> : IEcsPool, IEcsReadonlyPool<T> where T : struct
{
public ref T Add(int entityID);
public ref T Write(int entityID);
}
public abstract class EcsPoolBase<T> : IEcsPoolBase
where T : struct
{ {
#region Properties #region Properties
public abstract Type ComponentType { get; } public abstract Type ComponentType { get; }
public abstract EcsWorld World { get; } public abstract EcsWorld World { get; }
public abstract int Count { get; }
public abstract int Capacity { get; }
#endregion #endregion
#region Methods #region Methods
public abstract bool Has(int entityID); public abstract bool Has(int entityID);
protected abstract void Init(EcsWorld world);
protected abstract void OnWorldResize(int newSize); protected abstract void OnWorldResize(int newSize);
protected abstract void OnDestroy(); protected abstract void OnDestroy();
#endregion #endregion
#region Internal #region Internal
internal void InvokeInit(EcsWorld world) => Init(world);
internal void InvokeOnWorldResize(int newSize) => OnWorldResize(newSize); internal void InvokeOnWorldResize(int newSize) => OnWorldResize(newSize);
internal void InvokeOnDestroy() => OnDestroy(); internal void InvokeOnDestroy() => OnDestroy();
#endregion #endregion
} }
public struct NullComponent { } public struct NullComponent { }
public sealed class EcsNullPool : EcsPoolBase<NullComponent> public sealed class EcsNullPool : EcsPoolBase
{ {
public static EcsNullPool instance => new EcsNullPool(null); public static EcsNullPool instance => new EcsNullPool(null);
private EcsWorld _source; private EcsWorld _source;
private NullComponent fakeComponent;
private EcsNullPool(EcsWorld source) => _source = source; private EcsNullPool(EcsWorld source) => _source = source;
#region Properties #region Properties
public sealed override Type ComponentType => typeof(NullComponent); public sealed override Type ComponentType => typeof(NullComponent);
public sealed override EcsWorld World => _source; public sealed override EcsWorld World => _source;
public sealed override int Count => 0;
public sealed override int Capacity => 1;
#endregion #endregion
#region Methods #region Methods
public sealed override ref NullComponent Add(int entity) => ref fakeComponent;
public sealed override bool Has(int index) => false; public sealed override bool Has(int index) => false;
public sealed override ref readonly NullComponent Read(int entity) => ref fakeComponent;
public sealed override ref NullComponent Write(int entity) => ref fakeComponent;
public sealed override void Del(int index) { }
#endregion #endregion
#region WorldCallbacks #region Callbacks
protected override void Init(EcsWorld world) { }
protected override void OnWorldResize(int newSize) { } protected override void OnWorldResize(int newSize) { }
protected override void OnDestroy() { } protected override void OnDestroy() { }
#endregion #endregion
} }
public sealed class EcsPool<T> : EcsPoolBase<T> public sealed class EcsPool<T> : EcsPoolBase
where T : struct where T : struct
{ {
public static EcsPool<T> Builder(EcsWorld source) private EcsWorld _source;
{
return new EcsPool<T>(source, 512, new PoolRunners(source.Pipeline));
}
private readonly EcsWorld _source;
private int[] _mapping;// index = entityID / value = itemIndex;/ value = 0 = no entityID private int[] _mapping;// index = entityID / value = itemIndex;/ value = 0 = no entityID
private T[] _items; //dense private T[] _items; //dense
@ -113,25 +64,26 @@ namespace DCFApixels.DragonECS
private PoolRunners _poolRunners; private PoolRunners _poolRunners;
#region Properites #region Properites
public sealed override int Count => _itemsCount; public int Count => _itemsCount;
public sealed override int Capacity => _items.Length; public int Capacity => _items.Length;
public sealed override EcsWorld World => _source; public sealed override EcsWorld World => _source;
public sealed override Type ComponentType => typeof(T); public sealed override Type ComponentType => typeof(T);
#endregion #endregion
#region Constructors #region Init
internal EcsPool(EcsWorld source, int capacity, PoolRunners poolRunners) protected override void Init(EcsWorld world)
{ {
_source = source; const int capacity = 512;
_source = world;
_mapping = new int[source.Capacity]; _mapping = new int[world.Capacity];
_recycledItems = new int[128]; _recycledItems = new int[128];
_recycledItemsCount = 0; _recycledItemsCount = 0;
_items = new T[capacity]; _items = new T[capacity];
_itemsCount = 0; _itemsCount = 0;
_componentResetHandler = EcsComponentResetHandler<T>.instance; _componentResetHandler = EcsComponentResetHandler<T>.instance;
_poolRunners = poolRunners; _poolRunners = new PoolRunners(world.Pipeline);
} }
#endregion #endregion
@ -141,7 +93,7 @@ namespace DCFApixels.DragonECS
private ProfilerMarker _readMark = new ProfilerMarker("EcsPoo.Read"); private ProfilerMarker _readMark = new ProfilerMarker("EcsPoo.Read");
private ProfilerMarker _hasMark = new ProfilerMarker("EcsPoo.Has"); private ProfilerMarker _hasMark = new ProfilerMarker("EcsPoo.Has");
private ProfilerMarker _delMark = new ProfilerMarker("EcsPoo.Del"); private ProfilerMarker _delMark = new ProfilerMarker("EcsPoo.Del");
public sealed override ref T Add(int entityID) public ref T Add(int entityID)
{ {
// using (_addMark.Auto()) // using (_addMark.Auto())
// { // {
@ -168,14 +120,14 @@ namespace DCFApixels.DragonECS
// } // }
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public sealed override ref T Write(int entityID) public ref T Write(int entityID)
{ {
// using (_writeMark.Auto()) // using (_writeMark.Auto())
_poolRunners.write.OnComponentWrite<T>(entityID); _poolRunners.write.OnComponentWrite<T>(entityID);
return ref _items[_mapping[entityID]]; return ref _items[_mapping[entityID]];
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public sealed override ref readonly T Read(int entityID) public ref readonly T Read(int entityID)
{ {
// using (_readMark.Auto()) // using (_readMark.Auto())
return ref _items[_mapping[entityID]]; return ref _items[_mapping[entityID]];
@ -186,7 +138,7 @@ namespace DCFApixels.DragonECS
// using (_hasMark.Auto()) // using (_hasMark.Auto())
return _mapping[entityID] > 0; return _mapping[entityID] > 0;
} }
public sealed override void Del(int entityID) public void Del(int entityID)
{ {
// using (_delMark.Auto()) // using (_delMark.Auto())
// { // {
@ -210,4 +162,14 @@ namespace DCFApixels.DragonECS
protected override void OnDestroy() { } protected override void OnDestroy() { }
#endregion #endregion
} }
public interface IComponent { }
public static class IComponentExt
{
public static EcsPool<TComponent> GetPool<TComponent>(this EcsWorld self)
where TComponent : struct, IComparable
{
return self.GetPool<TComponent, EcsPool<TComponent>>();
}
}
} }

105
src/Pools/EcsSinglePool.cs Normal file
View File

@ -0,0 +1,105 @@
using System;
using System.Runtime.CompilerServices;
using Unity.Profiling;
namespace DCFApixels.DragonECS
{
public sealed class EcsSinglePool<T> : EcsPoolBase
where T : struct
{
private EcsWorld _source;
private int[] _mapping;// index = entityID / value = itemIndex;/ value = 0 = no entityID
//private T[] _items; //dense
//private int _count;
//private int[] _recycledItems;
//private int _recycledItemsCount;
private int _count;
private T _component;
private PoolRunners _poolRunners;
#region Properites
public int Count => _count;
public sealed override EcsWorld World => _source;
public sealed override Type ComponentType => typeof(T);
#endregion
#region Init
protected override void Init(EcsWorld world)
{
_source = world;
_mapping = new int[world.Capacity];
_count = 0;
_poolRunners = new PoolRunners(world.Pipeline);
}
#endregion
#region Write/Read/Has/Del
private ProfilerMarker _addMark = new ProfilerMarker("EcsPoo.Add");
private ProfilerMarker _writeMark = new ProfilerMarker("EcsPoo.Write");
private ProfilerMarker _readMark = new ProfilerMarker("EcsPoo.Read");
private ProfilerMarker _hasMark = new ProfilerMarker("EcsPoo.Has");
private ProfilerMarker _delMark = new ProfilerMarker("EcsPoo.Del");
public ref T Add(int entityID)
{
// using (_addMark.Auto())
// {
if (_mapping[entityID] <= 0)
{
_mapping[entityID] = ++_count;
_poolRunners.add.OnComponentAdd<T>(entityID);
}
return ref _component;
// }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref T Write(int entityID)
{
// using (_writeMark.Auto())
_poolRunners.write.OnComponentWrite<T>(entityID);
return ref _component;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref readonly T Read(int entityID)
{
// using (_readMark.Auto())
return ref _component;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public sealed override bool Has(int entityID)
{
// using (_hasMark.Auto())
return _mapping[entityID] > 0;
}
public void Del(int entityID)
{
// using (_delMark.Auto())
// {
_mapping[entityID] = 0;
_count--;
_poolRunners.del.OnComponentDel<T>(entityID);
// }
}
#endregion
#region WorldCallbacks
protected override void OnWorldResize(int newSize)
{
Array.Resize(ref _mapping, newSize);
}
protected override void OnDestroy() { }
#endregion
}
public interface ISingleComponent { }
public static class ISingleComponentExt
{
public static EcsTagPool<TSingleComponent> GetPool<TSingleComponent>(this EcsWorld self)
where TSingleComponent : struct, ISingleComponent
{
return self.GetPool<TSingleComponent, EcsTagPool<TSingleComponent>>();
}
}
}

85
src/Pools/EcsTagPool.cs Normal file
View File

@ -0,0 +1,85 @@
using System;
using System.Runtime.CompilerServices;
using Unity.Profiling;
namespace DCFApixels.DragonECS
{
public sealed class EcsTagPool<T> : EcsPoolBase
where T : struct
{
private EcsWorld _source;
private int[] _mapping;// index = entityID / value = itemIndex;/ value = 0 = no entityID
private int _count;
private PoolRunners _poolRunners;
#region Properites
public int Count => _count;
public sealed override EcsWorld World => _source;
public sealed override Type ComponentType => typeof(T);
#endregion
#region Init
protected override void Init(EcsWorld world)
{
_source = world;
_mapping = new int[world.Capacity];
_count = 0;
_poolRunners = new PoolRunners(world.Pipeline);
}
#endregion
#region Add/Has/Del
private ProfilerMarker _addMark = new ProfilerMarker("EcsPoo.Add");
private ProfilerMarker _hasMark = new ProfilerMarker("EcsPoo.Has");
private ProfilerMarker _delMark = new ProfilerMarker("EcsPoo.Del");
public void Add(int entityID)
{
// using (_addMark.Auto())
// {
if (_mapping[entityID] <= 0)
{
_mapping[entityID] = ++_count;
_poolRunners.add.OnComponentAdd<T>(entityID);
}
// }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public sealed override bool Has(int entityID)
{
// using (_hasMark.Auto())
return _mapping[entityID] > 0;
}
public void Del(int entityID)
{
// using (_delMark.Auto())
// {
_mapping[entityID] = 0;
_count--;
_poolRunners.del.OnComponentDel<T>(entityID);
// }
}
#endregion
#region WorldCallbacks
protected override void OnWorldResize(int newSize)
{
Array.Resize(ref _mapping, newSize);
}
protected override void OnDestroy() { }
#endregion
}
public interface ITagComponent { }
public static class ITagComponentExt
{
public static EcsTagPool<TTagComponent> GetPool<TTagComponent>(this EcsWorld self)
where TTagComponent : struct, ITagComponent
{
return self.GetPool<TTagComponent, EcsTagPool<TTagComponent>>();
}
}
}

View File

@ -1,134 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DCFApixels.DragonECS.Test
{
public class TestWorld
{
public PoolToken RegisterPool<TComponent>()
{
return new PoolToken(1);
}
public IEcsPool GetPoolX()
{
return null;
}
}
public readonly struct PoolToken
{
internal readonly ushort id;
public PoolToken(ushort id)
{
this.id = id;
}
}
//реализовать query так чтоб на вход он получал какуюто коллекцию и заполнял ее. по итогу на выходе запроса юзер будет иметь просто список
//таким образом во первых он сам может решить как его прокрутить, через for или foreach или еще как. во вторых можно будет прикрутить поддержку nativearray от unity
public class TestPool<TComponent>
{
private PoolToken _token;
public TestPool(TestWorld world)
{
_token = world.RegisterPool<TComponent>();
}
}
public interface IPool { }
public class Pool1<TComponent> : EcsPoolBase<TComponent>
where TComponent : struct
{
public override Type ComponentType => throw new NotImplementedException();
public override EcsWorld World => throw new NotImplementedException();
public override int Count => throw new NotImplementedException();
public override int Capacity => throw new NotImplementedException();
public override ref TComponent Add(int entityID)
{
throw new NotImplementedException();
}
public override void Del(int entityID)
{
throw new NotImplementedException();
}
public override bool Has(int entityID)
{
throw new NotImplementedException();
}
public override ref readonly TComponent Read(int entityID)
{
throw new NotImplementedException();
}
public override ref TComponent Write(int entityID)
{
throw new NotImplementedException();
}
protected override void OnDestroy()
{
throw new NotImplementedException();
}
protected override void OnWorldResize(int newSize)
{
throw new NotImplementedException();
}
}
public interface IComponentPool<TPool, TComponent>
where TPool : IEcsPool<TComponent>
where TComponent : struct
{ }
public interface IComponent1<TComponent> : IComponentPool<Pool1<TComponent>, TComponent>
where TComponent : struct
{ }
public interface IComponent2<TComponent> : IComponentPool<EcsPool<TComponent>, TComponent>
where TComponent : struct
{ }
public struct ComponentX1 : IComponent1<ComponentX1> { }
public struct ComponentX2 : IComponent2<ComponentX2> { }
public static class Pool1Ext
{
public static Pool1<TComponent> GetPool<TComponent>(this TestWorld self)
where TComponent : struct, IComponent1<TComponent>
{
return (Pool1<TComponent>)self.GetPoolX();
}
}
public static class Pool2Ext
{
public static EcsPool<TComponent> GetPool<TComponent>(this TestWorld self)
where TComponent : struct, IComponent2<TComponent>
{
return (EcsPool<TComponent>)self.GetPoolX();
}
}
public class Foo
{
private TestWorld world;
public void Do()
{
var poola = world.GetPool<ComponentX1>();
}
}
}