mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 09:54:35 +08:00
reworkpool system/ add new pools
This commit is contained in:
parent
905cd3033a
commit
3a15b93da5
@ -53,16 +53,16 @@ namespace DCFApixels.DragonECS
|
||||
public override inc_<TComponent> Include<TComponent>() where TComponent : struct
|
||||
{
|
||||
_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
|
||||
{
|
||||
_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
|
||||
{
|
||||
return new opt_<TComponent>(_world.GetOrCreatePool<TComponent>());
|
||||
return new opt_<TComponent>(_world.GetPool<TComponent, EcsPool<TComponent>>());
|
||||
}
|
||||
|
||||
private void End(out EcsQueryMask mask)
|
||||
@ -93,7 +93,8 @@ namespace DCFApixels.DragonECS
|
||||
private ProfilerMarker _getEnumerator = new ProfilerMarker("EcsGraphQuery.Execute");
|
||||
protected sealed override void OnBuildAfter()
|
||||
{
|
||||
attachPool = World.GetOrCreatePool<Edge>();
|
||||
throw new NotImplementedException();
|
||||
// attachPool = World.GetPool<Edge>();
|
||||
}
|
||||
public sealed override void Execute()
|
||||
{
|
||||
|
@ -81,80 +81,4 @@ namespace DCFApixels.DragonECS
|
||||
public static implicit operator opt_<TComponent>(EcsQueryBuilderBase buider) => buider.Optional<TComponent>();
|
||||
}
|
||||
#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
|
||||
}
|
||||
|
@ -41,7 +41,7 @@ namespace DCFApixels.DragonECS
|
||||
private int[] _delEntBuffer;
|
||||
private int _delEntBufferCount;
|
||||
|
||||
private IEcsPool[] _pools;
|
||||
private EcsPoolBase[] _pools;
|
||||
private EcsNullPool _nullPool;
|
||||
|
||||
private EcsQueryBase[] _queries;
|
||||
@ -55,7 +55,7 @@ namespace DCFApixels.DragonECS
|
||||
private IEcsEntityDestroy _entityDestry;
|
||||
|
||||
#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;
|
||||
|
||||
#endregion
|
||||
@ -83,7 +83,7 @@ namespace DCFApixels.DragonECS
|
||||
if (!_pipeline.IsInit) pipline.Init();
|
||||
_entityDispenser = new IntDispenser(0);
|
||||
_nullPool = EcsNullPool.instance;
|
||||
_pools = new IEcsPool[512];
|
||||
_pools = new EcsPoolBase[512];
|
||||
ArrayUtility.Fill(_pools, _nullPool);
|
||||
|
||||
_gens = new short[512];
|
||||
@ -121,7 +121,7 @@ namespace DCFApixels.DragonECS
|
||||
#endregion
|
||||
|
||||
#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);
|
||||
|
||||
@ -133,9 +133,15 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@ -202,7 +208,7 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
}
|
||||
foreach (var item in _pools)
|
||||
item.OnWorldResize(_gens.Length);
|
||||
item.InvokeOnWorldResize(_gens.Length);
|
||||
}
|
||||
_gens[entityID] |= short.MinValue;
|
||||
EcsEntity entity = new EcsEntity(entityID, _gens[entityID]++, uniqueID);
|
||||
|
@ -22,7 +22,8 @@ namespace DCFApixels.DragonECS
|
||||
public readonly short world;
|
||||
|
||||
[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
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@ -72,10 +73,6 @@ namespace DCFApixels.DragonECS
|
||||
public readonly partial struct EcsEntity
|
||||
{
|
||||
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
|
||||
{
|
||||
@ -86,43 +83,6 @@ namespace DCFApixels.DragonECS
|
||||
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
|
||||
|
@ -15,8 +15,8 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
#region Methods
|
||||
public int GetComponentID<T>();
|
||||
public IEcsPool<TComponent> GetOrCreatePool<TComponent>(Func<EcsWorld, IEcsPool> builder) where TComponent : struct;
|
||||
public ReadOnlySpan<IEcsPool> GetAllPools();
|
||||
public TPool GetPool<TComponent, TPool>() where TComponent : struct where TPool : EcsPoolBase, new();
|
||||
public ReadOnlySpan<EcsPoolBase> GetAllPools();
|
||||
public TQuery Where<TQuery>(out TQuery query) where TQuery : EcsQueryBase;
|
||||
public TQuery Select<TQuery>() where TQuery : EcsQueryBase;
|
||||
|
||||
|
111
src/Pools/EcsNotNullPool.cs
Normal file
111
src/Pools/EcsNotNullPool.cs
Normal 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>>();
|
||||
}
|
||||
}
|
||||
}
|
@ -4,104 +4,55 @@ using Unity.Profiling;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public interface IEcsPoolBase
|
||||
{
|
||||
#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
|
||||
public abstract class EcsPoolBase
|
||||
{
|
||||
#region Properties
|
||||
public abstract Type ComponentType { get; }
|
||||
public abstract EcsWorld World { get; }
|
||||
public abstract int Count { get; }
|
||||
public abstract int Capacity { get; }
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
public abstract bool Has(int entityID);
|
||||
|
||||
protected abstract void Init(EcsWorld world);
|
||||
protected abstract void OnWorldResize(int newSize);
|
||||
protected abstract void OnDestroy();
|
||||
#endregion
|
||||
|
||||
#region Internal
|
||||
internal void InvokeInit(EcsWorld world) => Init(world);
|
||||
internal void InvokeOnWorldResize(int newSize) => OnWorldResize(newSize);
|
||||
internal void InvokeOnDestroy() => OnDestroy();
|
||||
#endregion
|
||||
}
|
||||
|
||||
public struct NullComponent { }
|
||||
public sealed class EcsNullPool : EcsPoolBase<NullComponent>
|
||||
public sealed class EcsNullPool : EcsPoolBase
|
||||
{
|
||||
public static EcsNullPool instance => new EcsNullPool(null);
|
||||
private EcsWorld _source;
|
||||
private NullComponent fakeComponent;
|
||||
private EcsNullPool(EcsWorld source) => _source = source;
|
||||
|
||||
#region Properties
|
||||
public sealed override Type ComponentType => typeof(NullComponent);
|
||||
public sealed override EcsWorld World => _source;
|
||||
public sealed override int Count => 0;
|
||||
public sealed override int Capacity => 1;
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
public sealed override ref NullComponent Add(int entity) => ref fakeComponent;
|
||||
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
|
||||
|
||||
#region WorldCallbacks
|
||||
#region Callbacks
|
||||
protected override void Init(EcsWorld world) { }
|
||||
protected override void OnWorldResize(int newSize) { }
|
||||
protected override void OnDestroy() { }
|
||||
#endregion
|
||||
}
|
||||
|
||||
public sealed class EcsPool<T> : EcsPoolBase<T>
|
||||
public sealed class EcsPool<T> : EcsPoolBase
|
||||
where T : struct
|
||||
{
|
||||
public static EcsPool<T> Builder(EcsWorld source)
|
||||
{
|
||||
return new EcsPool<T>(source, 512, new PoolRunners(source.Pipeline));
|
||||
}
|
||||
|
||||
private readonly EcsWorld _source;
|
||||
private EcsWorld _source;
|
||||
|
||||
private int[] _mapping;// index = entityID / value = itemIndex;/ value = 0 = no entityID
|
||||
private T[] _items; //dense
|
||||
@ -113,25 +64,26 @@ namespace DCFApixels.DragonECS
|
||||
private PoolRunners _poolRunners;
|
||||
|
||||
#region Properites
|
||||
public sealed override int Count => _itemsCount;
|
||||
public sealed override int Capacity => _items.Length;
|
||||
public int Count => _itemsCount;
|
||||
public int Capacity => _items.Length;
|
||||
public sealed override EcsWorld World => _source;
|
||||
public sealed override Type ComponentType => typeof(T);
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
internal EcsPool(EcsWorld source, int capacity, PoolRunners poolRunners)
|
||||
#region Init
|
||||
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];
|
||||
_recycledItemsCount = 0;
|
||||
_items = new T[capacity];
|
||||
_itemsCount = 0;
|
||||
|
||||
_componentResetHandler = EcsComponentResetHandler<T>.instance;
|
||||
_poolRunners = poolRunners;
|
||||
_poolRunners = new PoolRunners(world.Pipeline);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -141,7 +93,7 @@ namespace DCFApixels.DragonECS
|
||||
private ProfilerMarker _readMark = new ProfilerMarker("EcsPoo.Read");
|
||||
private ProfilerMarker _hasMark = new ProfilerMarker("EcsPoo.Has");
|
||||
private ProfilerMarker _delMark = new ProfilerMarker("EcsPoo.Del");
|
||||
public sealed override ref T Add(int entityID)
|
||||
public ref T Add(int entityID)
|
||||
{
|
||||
// using (_addMark.Auto())
|
||||
// {
|
||||
@ -168,14 +120,14 @@ namespace DCFApixels.DragonECS
|
||||
// }
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public sealed override ref T Write(int entityID)
|
||||
public ref T Write(int entityID)
|
||||
{
|
||||
// using (_writeMark.Auto())
|
||||
_poolRunners.write.OnComponentWrite<T>(entityID);
|
||||
return ref _items[_mapping[entityID]];
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public sealed override ref readonly T Read(int entityID)
|
||||
public ref readonly T Read(int entityID)
|
||||
{
|
||||
// using (_readMark.Auto())
|
||||
return ref _items[_mapping[entityID]];
|
||||
@ -186,7 +138,7 @@ namespace DCFApixels.DragonECS
|
||||
// using (_hasMark.Auto())
|
||||
return _mapping[entityID] > 0;
|
||||
}
|
||||
public sealed override void Del(int entityID)
|
||||
public void Del(int entityID)
|
||||
{
|
||||
// using (_delMark.Auto())
|
||||
// {
|
||||
@ -210,4 +162,14 @@ namespace DCFApixels.DragonECS
|
||||
protected override void OnDestroy() { }
|
||||
#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
105
src/Pools/EcsSinglePool.cs
Normal 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
85
src/Pools/EcsTagPool.cs
Normal 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>>();
|
||||
}
|
||||
}
|
||||
}
|
134
src/TestPool.cs
134
src/TestPool.cs
@ -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>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user