mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 01:44:35 +08:00
Optimization
This commit is contained in:
parent
a489f4cbae
commit
de7762861c
@ -22,12 +22,12 @@
|
|||||||
|
|
||||||
public sealed class EcsPreInitRunner : EcsRunner<IEcsPreInitSystem>, IEcsPreInitSystem
|
public sealed class EcsPreInitRunner : EcsRunner<IEcsPreInitSystem>, IEcsPreInitSystem
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG && !DISABLE_DRAGONECS_DEBUG
|
||||||
private EcsProfilerMarker[] _markers;
|
private EcsProfilerMarker[] _markers;
|
||||||
#endif
|
#endif
|
||||||
public void PreInit(EcsPipeline pipeline)
|
public void PreInit(EcsPipeline pipeline)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG && !DISABLE_DRAGONECS_DEBUG
|
||||||
for (int i = 0; i < targets.Length; i++)
|
for (int i = 0; i < targets.Length; i++)
|
||||||
{
|
{
|
||||||
using (_markers[i].Auto())
|
using (_markers[i].Auto())
|
||||||
@ -38,7 +38,7 @@
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG && !DISABLE_DRAGONECS_DEBUG
|
||||||
protected override void OnSetup()
|
protected override void OnSetup()
|
||||||
{
|
{
|
||||||
_markers = new EcsProfilerMarker[targets.Length];
|
_markers = new EcsProfilerMarker[targets.Length];
|
||||||
@ -51,12 +51,12 @@
|
|||||||
}
|
}
|
||||||
public sealed class EcsInitRunner : EcsRunner<IEcsInitSystem>, IEcsInitSystem
|
public sealed class EcsInitRunner : EcsRunner<IEcsInitSystem>, IEcsInitSystem
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG && !DISABLE_DRAGONECS_DEBUG
|
||||||
private EcsProfilerMarker[] _markers;
|
private EcsProfilerMarker[] _markers;
|
||||||
#endif
|
#endif
|
||||||
public void Init(EcsPipeline pipeline)
|
public void Init(EcsPipeline pipeline)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG && !DISABLE_DRAGONECS_DEBUG
|
||||||
for (int i = 0; i < targets.Length; i++)
|
for (int i = 0; i < targets.Length; i++)
|
||||||
{
|
{
|
||||||
using (_markers[i].Auto())
|
using (_markers[i].Auto())
|
||||||
@ -67,7 +67,7 @@
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG && !DISABLE_DRAGONECS_DEBUG
|
||||||
protected override void OnSetup()
|
protected override void OnSetup()
|
||||||
{
|
{
|
||||||
_markers = new EcsProfilerMarker[targets.Length];
|
_markers = new EcsProfilerMarker[targets.Length];
|
||||||
@ -80,12 +80,12 @@
|
|||||||
}
|
}
|
||||||
public sealed class EcsRunRunner : EcsRunner<IEcsRunSystem>, IEcsRunSystem
|
public sealed class EcsRunRunner : EcsRunner<IEcsRunSystem>, IEcsRunSystem
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG && !DISABLE_DRAGONECS_DEBUG
|
||||||
private EcsProfilerMarker[] _markers;
|
private EcsProfilerMarker[] _markers;
|
||||||
#endif
|
#endif
|
||||||
public void Run(EcsPipeline pipeline)
|
public void Run(EcsPipeline pipeline)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG && !DISABLE_DRAGONECS_DEBUG
|
||||||
for (int i = 0; i < targets.Length; i++)
|
for (int i = 0; i < targets.Length; i++)
|
||||||
{
|
{
|
||||||
using (_markers[i].Auto())
|
using (_markers[i].Auto())
|
||||||
@ -97,7 +97,7 @@
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG && !DISABLE_DRAGONECS_DEBUG
|
||||||
protected override void OnSetup()
|
protected override void OnSetup()
|
||||||
{
|
{
|
||||||
_markers = new EcsProfilerMarker[targets.Length];
|
_markers = new EcsProfilerMarker[targets.Length];
|
||||||
@ -110,12 +110,12 @@
|
|||||||
}
|
}
|
||||||
public sealed class EcsDestroyRunner : EcsRunner<IEcsDestroySystem>, IEcsDestroySystem
|
public sealed class EcsDestroyRunner : EcsRunner<IEcsDestroySystem>, IEcsDestroySystem
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG && !DISABLE_DRAGONECS_DEBUG
|
||||||
private EcsProfilerMarker[] _markers;
|
private EcsProfilerMarker[] _markers;
|
||||||
#endif
|
#endif
|
||||||
public void Destroy(EcsPipeline pipeline)
|
public void Destroy(EcsPipeline pipeline)
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG && !DISABLE_DRAGONECS_DEBUG
|
||||||
for (int i = 0; i < targets.Length; i++)
|
for (int i = 0; i < targets.Length; i++)
|
||||||
{
|
{
|
||||||
using (_markers[i].Auto())
|
using (_markers[i].Auto())
|
||||||
@ -126,7 +126,7 @@
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG && !DISABLE_DRAGONECS_DEBUG
|
||||||
protected override void OnSetup()
|
protected override void OnSetup()
|
||||||
{
|
{
|
||||||
_markers = new EcsProfilerMarker[targets.Length];
|
_markers = new EcsProfilerMarker[targets.Length];
|
87
src/Builtin/WorldRunners.cs
Normal file
87
src/Builtin/WorldRunners.cs
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
namespace DCFApixels.DragonECS
|
||||||
|
{
|
||||||
|
public interface IEcsComponentAdd : IEcsSystem
|
||||||
|
{
|
||||||
|
public void OnComponentAdd<T>(int entityID);
|
||||||
|
}
|
||||||
|
public interface IEcsComponentWrite : IEcsSystem
|
||||||
|
{
|
||||||
|
public void OnComponentWrite<T>(int entityID);
|
||||||
|
}
|
||||||
|
public interface IEcsComponentDel : IEcsSystem
|
||||||
|
{
|
||||||
|
public void OnComponentDel<T>(int entityID);
|
||||||
|
}
|
||||||
|
public interface IEcsComponentLifecycle : IEcsComponentAdd, IEcsComponentWrite, IEcsComponentDel { }
|
||||||
|
public sealed class EcsEntityAddComponentRunner : EcsRunner<IEcsComponentAdd>, IEcsComponentAdd
|
||||||
|
{
|
||||||
|
public void OnComponentAdd<T>(int entityID)
|
||||||
|
{
|
||||||
|
foreach (var item in targets) item.OnComponentAdd<T>(entityID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public sealed class EcsEntityChangeComponentRunner : EcsRunner<IEcsComponentWrite>, IEcsComponentWrite
|
||||||
|
{
|
||||||
|
public void OnComponentWrite<T>(int entityID)
|
||||||
|
{
|
||||||
|
foreach (var item in targets) item.OnComponentWrite<T>(entityID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public sealed class EcsEntityDelComponentRunner : EcsRunner<IEcsComponentDel>, IEcsComponentDel
|
||||||
|
{
|
||||||
|
public void OnComponentDel<T>(int entityID)
|
||||||
|
{
|
||||||
|
foreach (var item in targets) item.OnComponentDel<T>(entityID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public interface IEcsEntityCreate : IEcsSystem
|
||||||
|
{
|
||||||
|
public void OnEntityCreate(ent entity);
|
||||||
|
}
|
||||||
|
public interface IEcsEntityDestroy : IEcsSystem
|
||||||
|
{
|
||||||
|
public void OnEntityDestroy(ent entity);
|
||||||
|
}
|
||||||
|
public interface IEcsEntityLifecycle : IEcsEntityCreate, IEcsEntityDestroy { }
|
||||||
|
public sealed class EcsEntityCreateRunner : EcsRunner<IEcsEntityCreate>, IEcsEntityCreate
|
||||||
|
{
|
||||||
|
public void OnEntityCreate(ent entity)
|
||||||
|
{
|
||||||
|
foreach (var item in targets) item.OnEntityCreate(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public sealed class EcsEntityDestroyRunner : EcsRunner<IEcsEntityDestroy>, IEcsEntityDestroy
|
||||||
|
{
|
||||||
|
public void OnEntityDestroy(ent entity)
|
||||||
|
{
|
||||||
|
foreach (var item in targets) item.OnEntityDestroy(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public interface IEcsWorldCreate : IEcsSystem
|
||||||
|
{
|
||||||
|
public void OnWorldCreate(IEcsWorld world);
|
||||||
|
}
|
||||||
|
public interface IEcsWorldDestroy : IEcsSystem
|
||||||
|
{
|
||||||
|
public void OnWorldDestroy(IEcsWorld world);
|
||||||
|
}
|
||||||
|
public interface IEcsWorldLifecycle : IEcsWorldCreate, IEcsWorldDestroy { }
|
||||||
|
public sealed class EcsWorldCreateRunner : EcsRunner<IEcsWorldCreate>, IEcsWorldCreate
|
||||||
|
{
|
||||||
|
public void OnWorldCreate(IEcsWorld world)
|
||||||
|
{
|
||||||
|
foreach (var item in targets) item.OnWorldCreate(world);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public sealed class EcsWorldDestryRunner : EcsRunner<IEcsWorldDestroy>, IEcsWorldDestroy
|
||||||
|
{
|
||||||
|
public void OnWorldDestroy(IEcsWorld world)
|
||||||
|
{
|
||||||
|
foreach (var item in targets) item.OnWorldDestroy(world);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,11 @@
|
|||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
public sealed class EcsDefaultWrold : EcsWorld<EcsDefaultWrold> { }
|
public sealed class EcsDefaultWrold : EcsWorld<EcsDefaultWrold>
|
||||||
public sealed class EcsEventWrold : EcsWorld<EcsDefaultWrold> { }
|
{
|
||||||
|
public EcsDefaultWrold(EcsPipeline pipeline) : base(pipeline) { }
|
||||||
|
}
|
||||||
|
public sealed class EcsEventWrold : EcsWorld<EcsDefaultWrold>
|
||||||
|
{
|
||||||
|
public EcsEventWrold(EcsPipeline pipeline) : base(pipeline) { }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public AutoScope Auto() => new AutoScope(id);
|
public AutoScope Auto() => new AutoScope(id);
|
||||||
|
|
||||||
public readonly struct AutoScope : IDisposable
|
public readonly ref struct AutoScope
|
||||||
{
|
{
|
||||||
private readonly int id;
|
private readonly int id;
|
||||||
public AutoScope(int id)
|
public AutoScope(int id)
|
||||||
@ -43,14 +43,14 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void Print(string tag, object v)
|
public static void Print(string tag, object v)
|
||||||
{
|
{
|
||||||
#if !DISABLE_ECS_DEBUG
|
#if !DISABLE_DRAGONECS_DEBUG
|
||||||
DebugService.Instance.Print(tag, v);
|
DebugService.Instance.Print(tag, v);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static int RegisterMark(string name)
|
public static int RegisterMark(string name)
|
||||||
{
|
{
|
||||||
#if !DISABLE_ECS_DEBUG
|
#if !DISABLE_DRAGONECS_DEBUG
|
||||||
return DebugService.Instance.RegisterMark(name);
|
return DebugService.Instance.RegisterMark(name);
|
||||||
#else
|
#else
|
||||||
return 0;
|
return 0;
|
||||||
@ -59,21 +59,21 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void DeleteMark(string name)
|
public static void DeleteMark(string name)
|
||||||
{
|
{
|
||||||
#if !DISABLE_ECS_DEBUG
|
#if !DISABLE_DRAGONECS_DEBUG
|
||||||
DebugService.Instance.DeleteMark(name);
|
DebugService.Instance.DeleteMark(name);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void ProfileMarkBegin(int id)
|
public static void ProfileMarkBegin(int id)
|
||||||
{
|
{
|
||||||
#if !DISABLE_ECS_DEBUG
|
#if !DISABLE_DRAGONECS_DEBUG
|
||||||
DebugService.Instance.ProfileMarkBegin(id);
|
DebugService.Instance.ProfileMarkBegin(id);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void ProfileMarkEnd(int id)
|
public static void ProfileMarkEnd(int id)
|
||||||
{
|
{
|
||||||
#if !DISABLE_ECS_DEBUG
|
#if !DISABLE_DRAGONECS_DEBUG
|
||||||
DebugService.Instance.ProfileMarkEnd(id);
|
DebugService.Instance.ProfileMarkEnd(id);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -145,7 +145,7 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
public DefaultDebugService()
|
public DefaultDebugService()
|
||||||
{
|
{
|
||||||
#if !DISABLE_ECS_DEBUG
|
#if !DISABLE_DRAGONECS_DEBUG
|
||||||
_stopwatchs = new Stopwatch[64];
|
_stopwatchs = new Stopwatch[64];
|
||||||
_stopwatchsNames= new string[64];
|
_stopwatchsNames= new string[64];
|
||||||
#endif
|
#endif
|
||||||
|
@ -15,7 +15,7 @@ namespace DCFApixels.DragonECS
|
|||||||
public class EcsFilter : IEcsFilter
|
public class EcsFilter : IEcsFilter
|
||||||
{
|
{
|
||||||
private readonly IEcsWorld _source;
|
private readonly IEcsWorld _source;
|
||||||
private readonly EcsGroup _entities;
|
internal readonly EcsGroup entities;
|
||||||
private readonly EcsMask _mask;
|
private readonly EcsMask _mask;
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
@ -32,12 +32,12 @@ namespace DCFApixels.DragonECS
|
|||||||
public EcsReadonlyGroup Entities
|
public EcsReadonlyGroup Entities
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get => _entities.Readonly;
|
get => entities.Readonly;
|
||||||
}
|
}
|
||||||
public int EntitiesCount
|
public int EntitiesCount
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get => _entities.Count;
|
get => entities.Count;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
_source = source;
|
_source = source;
|
||||||
_mask = mask;
|
_mask = mask;
|
||||||
_entities = new EcsGroup(source, capasity);
|
entities = new EcsGroup(source, capasity);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -54,19 +54,19 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal void Add(int entityID)
|
internal void Add(int entityID)
|
||||||
{
|
{
|
||||||
_entities.Add(entityID);
|
entities.UncheckedAdd(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal void Remove(int entityID)
|
internal void Remove(int entityID)
|
||||||
{
|
{
|
||||||
_entities.Remove(entityID);
|
entities.UncheckedRemove(entityID);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region GetEnumerator
|
#region GetEnumerator
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public EcsGroup.Enumerator GetEnumerator() => _entities.GetEnumerator();
|
public EcsGroup.Enumerator GetEnumerator() => entities.GetEnumerator();
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
129
src/EcsGroup.cs
129
src/EcsGroup.cs
@ -17,6 +17,16 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get => _source.Count;
|
get => _source.Count;
|
||||||
}
|
}
|
||||||
|
public int CapacityDense
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get => _source.CapacityDense;
|
||||||
|
}
|
||||||
|
public int CapacitySparce
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get => _source.CapacitySparce;
|
||||||
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool Contains(int entityID) => _source.Contains(entityID);
|
public bool Contains(int entityID) => _source.Contains(entityID);
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@ -51,6 +61,16 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get => _count;
|
get => _count;
|
||||||
}
|
}
|
||||||
|
public int CapacityDense
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get => _dense.Length;
|
||||||
|
}
|
||||||
|
public int CapacitySparce
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get => _sparse.Length;
|
||||||
|
}
|
||||||
public EcsReadonlyGroup Readonly
|
public EcsReadonlyGroup Readonly
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@ -60,11 +80,29 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
#region Constrcutors
|
#region Constrcutors
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public EcsGroup(IEcsWorld source, int denseCapacity = 64, int sparseCapacity = 256, int delayedOpsCapacity = 128)
|
internal EcsGroup(IEcsWorld source, int denseCapacity, int sparceCapacity, int delayedOpsCapacity)
|
||||||
{
|
{
|
||||||
_source = source;
|
_source = source;
|
||||||
|
source.RegisterGroup(this);
|
||||||
_dense = new int[denseCapacity];
|
_dense = new int[denseCapacity];
|
||||||
_sparse = new int[sparseCapacity];
|
_sparse = new int[sparceCapacity];
|
||||||
|
|
||||||
|
_delayedOps = new delayedOp[delayedOpsCapacity];
|
||||||
|
|
||||||
|
_lockCount = 0;
|
||||||
|
_delayedOpsCount = 0;
|
||||||
|
|
||||||
|
_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public EcsGroup(IEcsWorld source, int denseCapacity = 64, int delayedOpsCapacity = 128)
|
||||||
|
{
|
||||||
|
_source = source;
|
||||||
|
source.RegisterGroup(this);
|
||||||
|
_dense = new int[denseCapacity];
|
||||||
|
_sparse = new int[source.Entities.CapacitySparce];
|
||||||
|
|
||||||
_delayedOps = new delayedOp[delayedOpsCapacity];
|
_delayedOps = new delayedOp[delayedOpsCapacity];
|
||||||
|
|
||||||
@ -79,53 +117,64 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool Contains(int entityID)
|
public bool Contains(int entityID)
|
||||||
{
|
{
|
||||||
return /*entityID > 0 && */ entityID < _sparse.Length && _sparse[entityID] > 0;
|
//TODO добавить проверку на больше 0 в #if (DEBUG && !DISABLE_DRAGONECS_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||||
|
#if (DEBUG && !DISABLE_DRAGONECS_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||||
|
#endif
|
||||||
|
return /*entityID > 0 && entityID < _sparse.Length && */ _sparse[entityID] > 0;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IndexOf
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public int IndexOf(int entityID)
|
||||||
|
{
|
||||||
|
return _sparse[entityID];
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region add/remove
|
#region add/remove
|
||||||
|
public void UncheckedAdd(int entityID) => AddInternal(entityID);
|
||||||
public void Add(int entityID)
|
public void Add(int entityID)
|
||||||
{
|
{
|
||||||
if (_lockCount > 0)
|
if (Contains(entityID)) return;
|
||||||
|
Add(entityID);
|
||||||
|
}
|
||||||
|
private void AddInternal(int entityID)
|
||||||
|
{
|
||||||
|
if (_lockCount > 0)
|
||||||
{
|
{
|
||||||
AddDelayedOp(entityID, DEALAYED_ADD);
|
AddDelayedOp(entityID, DEALAYED_ADD);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Contains(entityID))
|
if (++_count >= _dense.Length)
|
||||||
return;
|
|
||||||
|
|
||||||
if(++_count >= _dense.Length)
|
|
||||||
Array.Resize(ref _dense, _dense.Length << 1);
|
Array.Resize(ref _dense, _dense.Length << 1);
|
||||||
|
|
||||||
if (entityID >= _sparse.Length)
|
|
||||||
{
|
|
||||||
int neadedSpace = _sparse.Length;
|
|
||||||
while (entityID >= neadedSpace)
|
|
||||||
neadedSpace <<= 1;
|
|
||||||
Array.Resize(ref _sparse, neadedSpace);
|
|
||||||
}
|
|
||||||
|
|
||||||
_dense[_count] = entityID;
|
_dense[_count] = entityID;
|
||||||
_sparse[entityID] = _count;
|
_sparse[entityID] = _count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UncheckedRemove(int entityID) => RemoveInternal(entityID);
|
||||||
public void Remove(int entityID)
|
public void Remove(int entityID)
|
||||||
|
{
|
||||||
|
if (!Contains(entityID)) return;
|
||||||
|
RemoveInternal(entityID);
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
private void RemoveInternal(int entityID)
|
||||||
{
|
{
|
||||||
if (_lockCount > 0)
|
if (_lockCount > 0)
|
||||||
{
|
{
|
||||||
AddDelayedOp(entityID, DEALAYED_REMOVE);
|
AddDelayedOp(entityID, DEALAYED_REMOVE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Contains(entityID))
|
|
||||||
return;
|
|
||||||
|
|
||||||
_dense[_sparse[entityID]] = _dense[_count];
|
_dense[_sparse[entityID]] = _dense[_count];
|
||||||
_sparse[_dense[_count--]] = _sparse[entityID];
|
_sparse[_dense[_count--]] = _sparse[entityID];
|
||||||
_sparse[entityID] = 0;
|
_sparse[entityID] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private void AddDelayedOp(int entityID, int isAddBitFlag)
|
private void AddDelayedOp(int entityID, int isAddBitFlag)
|
||||||
{
|
{
|
||||||
@ -137,24 +186,32 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
//TODO добавить автосоритровку при каждом GetEnumerator
|
internal void OnWorldResize(int newSize)
|
||||||
|
{
|
||||||
|
Array.Resize(ref _sparse, newSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO добавить метод Sort
|
||||||
|
|
||||||
|
//TODO добавить автосоритровку при каждом GetEnumerator и проверить будет ли прирост производительности или ее падение.
|
||||||
|
//Суть в том что так возможно можно будет более плотно подавать данные в проц
|
||||||
|
|
||||||
#region AddGroup/RemoveGroup
|
#region AddGroup/RemoveGroup
|
||||||
public void AddGroup(EcsReadonlyGroup group)
|
public void AddGroup(EcsReadonlyGroup group)
|
||||||
{
|
{
|
||||||
foreach (var item in group) Add(item.id);
|
foreach (var item in group) UncheckedAdd(item.id);
|
||||||
}
|
}
|
||||||
public void RemoveGroup(EcsReadonlyGroup group)
|
public void RemoveGroup(EcsReadonlyGroup group)
|
||||||
{
|
{
|
||||||
foreach (var item in group) Remove(item.id);
|
foreach (var item in group) UncheckedRemove(item.id);
|
||||||
}
|
}
|
||||||
public void AddGroup(EcsGroup group)
|
public void AddGroup(EcsGroup group)
|
||||||
{
|
{
|
||||||
foreach (var item in group) Add(item.id);
|
foreach (var item in group) UncheckedAdd(item.id);
|
||||||
}
|
}
|
||||||
public void RemoveGroup(EcsGroup group)
|
public void RemoveGroup(EcsGroup group)
|
||||||
{
|
{
|
||||||
foreach (var item in group) Remove(item.id);
|
foreach (var item in group) UncheckedRemove(item.id);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -162,7 +219,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
private void Unlock()
|
private void Unlock()
|
||||||
{
|
{
|
||||||
#if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
|
#if (DEBUG && !DISABLE_DRAGONECS_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||||
if (_lockCount <= 0)
|
if (_lockCount <= 0)
|
||||||
{
|
{
|
||||||
throw new Exception($"Invalid lock-unlock balance for {nameof(EcsGroup)}.");
|
throw new Exception($"Invalid lock-unlock balance for {nameof(EcsGroup)}.");
|
||||||
@ -175,11 +232,11 @@ namespace DCFApixels.DragonECS
|
|||||||
delayedOp op = _delayedOps[i];
|
delayedOp op = _delayedOps[i];
|
||||||
if (op >= 0) //delayedOp.IsAdded
|
if (op >= 0) //delayedOp.IsAdded
|
||||||
{
|
{
|
||||||
Add(op & int.MaxValue); //delayedOp.Entity
|
UncheckedAdd(op & int.MaxValue); //delayedOp.Entity
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Remove(op & int.MaxValue); //delayedOp.Entity
|
UncheckedRemove(op & int.MaxValue); //delayedOp.Entity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -214,7 +271,6 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
using (_marker.Auto())
|
using (_marker.Auto())
|
||||||
return _source.World.GetEntity(_source._dense[_pointer]);
|
return _source.World.GetEntity(_source._dense[_pointer]);
|
||||||
// return _source._dense[_pointer];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,4 +294,19 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static class EcsGroupExtensions
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void Normalize<T>(this EcsGroup self, ref T[] array)
|
||||||
|
{
|
||||||
|
if (array.Length < self.CapacityDense) Array.Resize(ref array, self.CapacityDense);
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static void Normalize<T>(this EcsReadonlyGroup self, ref T[] array)
|
||||||
|
{
|
||||||
|
if (array.Length < self.CapacityDense) Array.Resize(ref array, self.CapacityDense);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,21 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
public sealed class EcsPipeline
|
public sealed class EcsPipeline
|
||||||
{
|
{
|
||||||
|
private static EcsPipeline _empty;
|
||||||
|
public static EcsPipeline Empty
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if(_empty == null)
|
||||||
|
{
|
||||||
|
_empty = new EcsPipeline(Array.Empty<IEcsSystem>());
|
||||||
|
_empty.Init();
|
||||||
|
_empty._isEmptyDummy = true;
|
||||||
|
}
|
||||||
|
return _empty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private IEcsSystem[] _allSystems;
|
private IEcsSystem[] _allSystems;
|
||||||
private Dictionary<Type, IEcsRunner> _runners;
|
private Dictionary<Type, IEcsRunner> _runners;
|
||||||
private IEcsRunSystem _runRunnerCache;
|
private IEcsRunSystem _runRunnerCache;
|
||||||
@ -16,10 +31,12 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
private bool _isInit;
|
private bool _isInit;
|
||||||
private bool _isDestoryed;
|
private bool _isDestoryed;
|
||||||
|
private bool _isEmptyDummy;
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
public ReadOnlyCollection<IEcsSystem> AllSystems => _allSystemsSealed;
|
public ReadOnlyCollection<IEcsSystem> AllSystems => _allSystemsSealed;
|
||||||
public ReadOnlyDictionary<Type, IEcsRunner> AllRunners => _allRunnersSealed;
|
public ReadOnlyDictionary<Type, IEcsRunner> AllRunners => _allRunnersSealed;
|
||||||
|
public bool IsInit => _isInit;
|
||||||
public bool IsDestoryed => _isDestoryed;
|
public bool IsDestoryed => _isDestoryed;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -33,6 +50,7 @@ namespace DCFApixels.DragonECS
|
|||||||
_allRunnersSealed = new ReadOnlyDictionary<Type, IEcsRunner>(_runners);
|
_allRunnersSealed = new ReadOnlyDictionary<Type, IEcsRunner>(_runners);
|
||||||
|
|
||||||
_isInit = false;
|
_isInit = false;
|
||||||
|
_isEmptyDummy = false;
|
||||||
_isDestoryed = false;
|
_isDestoryed = false;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@ -57,7 +75,10 @@ namespace DCFApixels.DragonECS
|
|||||||
#region LifeCycle
|
#region LifeCycle
|
||||||
public void Init()
|
public void Init()
|
||||||
{
|
{
|
||||||
if(_isInit == true)
|
if (_isEmptyDummy)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (_isInit == true)
|
||||||
{
|
{
|
||||||
EcsDebug.Print("[Warning]", $"This {nameof(EcsPipeline)} has already been initialized");
|
EcsDebug.Print("[Warning]", $"This {nameof(EcsPipeline)} has already been initialized");
|
||||||
return;
|
return;
|
||||||
@ -80,7 +101,7 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Run()
|
public void Run()
|
||||||
{
|
{
|
||||||
#if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
|
#if (DEBUG && !DISABLE_DRAGONECS_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||||
CheckBeforeInitForMethod(nameof(Run));
|
CheckBeforeInitForMethod(nameof(Run));
|
||||||
CheckAfterDestroyForMethod(nameof(Run));
|
CheckAfterDestroyForMethod(nameof(Run));
|
||||||
#endif
|
#endif
|
||||||
@ -88,7 +109,10 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
public void Destroy()
|
public void Destroy()
|
||||||
{
|
{
|
||||||
#if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
|
if (_isEmptyDummy)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#if (DEBUG && !DISABLE_DRAGONECS_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||||
CheckBeforeInitForMethod(nameof(Run));
|
CheckBeforeInitForMethod(nameof(Run));
|
||||||
#endif
|
#endif
|
||||||
if (_isDestoryed == true)
|
if (_isDestoryed == true)
|
||||||
@ -102,7 +126,7 @@ namespace DCFApixels.DragonECS
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region StateChecks
|
#region StateChecks
|
||||||
#if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
|
#if (DEBUG && !DISABLE_DRAGONECS_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||||
private void CheckBeforeInitForMethod(string methodName)
|
private void CheckBeforeInitForMethod(string methodName)
|
||||||
{
|
{
|
||||||
if (!_isInit)
|
if (!_isInit)
|
||||||
|
136
src/EcsPool.cs
136
src/EcsPool.cs
@ -1,6 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using Unity.Profiling;
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
@ -15,6 +17,8 @@ namespace DCFApixels.DragonECS
|
|||||||
public bool Has(int index);
|
public bool Has(int index);
|
||||||
public void Write(int index);
|
public void Write(int index);
|
||||||
public void Del(int index);
|
public void Del(int index);
|
||||||
|
|
||||||
|
internal void OnWorldResize(int newSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IEcsPool<T> : IEcsPool
|
public interface IEcsPool<T> : IEcsPool
|
||||||
@ -43,6 +47,8 @@ namespace DCFApixels.DragonECS
|
|||||||
public void Del(int index) { }
|
public void Del(int index) { }
|
||||||
public bool Has(int index) => false;
|
public bool Has(int index) => false;
|
||||||
public void Write(int index) { }
|
public void Write(int index) { }
|
||||||
|
|
||||||
|
void IEcsPool.OnWorldResize(int newSize) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
public class EcsPool<T> : IEcsPool<T>
|
public class EcsPool<T> : IEcsPool<T>
|
||||||
@ -50,14 +56,21 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
private readonly int _id;
|
private readonly int _id;
|
||||||
private readonly IEcsWorld _source;
|
private readonly IEcsWorld _source;
|
||||||
private readonly SparseSet _sparseSet;
|
// private readonly EcsGroup _entities;
|
||||||
private T[] _denseItems;
|
|
||||||
|
private int[] _mapping;// index = entity / value = itemIndex;/ value = 0 = no entity
|
||||||
|
private T[] _items; //dense
|
||||||
|
private int _itemsCount;
|
||||||
|
private int[] _recycledItems;
|
||||||
|
private int _recycledItemsCount;
|
||||||
|
|
||||||
private IEcsComponentReset<T> _componentResetHandler;
|
private IEcsComponentReset<T> _componentResetHandler;
|
||||||
|
|
||||||
|
private PoolRunnres _poolRunnres;
|
||||||
|
|
||||||
#region Properites
|
#region Properites
|
||||||
public int EntitiesCount => _sparseSet.Count;
|
public int EntitiesCount => _itemsCount;
|
||||||
public int Capacity => _sparseSet.CapacityDense;
|
public int Capacity => _items.Length;
|
||||||
|
|
||||||
public IEcsWorld World => _source;
|
public IEcsWorld World => _source;
|
||||||
public Type DataType => typeof(T);
|
public Type DataType => typeof(T);
|
||||||
@ -65,47 +78,81 @@ namespace DCFApixels.DragonECS
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
public EcsPool(IEcsWorld source, int id, int capacity)
|
internal EcsPool(IEcsWorld source, int id, int capacity, PoolRunnres poolRunnres)
|
||||||
{
|
{
|
||||||
_source = source;
|
_source = source;
|
||||||
_id = id;
|
_id = id;
|
||||||
_sparseSet = new SparseSet(capacity, capacity);
|
|
||||||
|
|
||||||
_denseItems =new T[capacity];
|
_mapping = new int[source.EntitesCapacity];
|
||||||
|
_recycledItems = new int[128];
|
||||||
|
_recycledItemsCount = 0;
|
||||||
|
_items =new T[capacity];
|
||||||
|
_itemsCount = 0;
|
||||||
|
|
||||||
_componentResetHandler = ComponentResetHandler.New<T>();
|
_componentResetHandler = ComponentResetHandler.New<T>();
|
||||||
|
_poolRunnres = poolRunnres;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Read/Write/Has/Del
|
#region Write/Read/Has/Del
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public ref readonly T Read(int entity)
|
|
||||||
{
|
|
||||||
return ref _denseItems[_sparseSet.IndexOf(entity)];
|
|
||||||
}
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public ref T Write(int entity)
|
|
||||||
{
|
|
||||||
if (!_sparseSet.Contains(entity))
|
|
||||||
{
|
|
||||||
_sparseSet.Add(entity);
|
|
||||||
_sparseSet.Normalize(ref _denseItems);
|
|
||||||
_source.OnEntityComponentAdded(entity, _id);
|
|
||||||
_componentResetHandler.Reset(ref _denseItems[_sparseSet.IndexOf(entity)]);
|
|
||||||
}
|
|
||||||
return ref _denseItems[_sparseSet.IndexOf(entity)];
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
private ProfilerMarker _writeMark = new ProfilerMarker("EcsPoo.Write");
|
||||||
public bool Has(int entity)
|
private ProfilerMarker _readMark = new ProfilerMarker("EcsPoo.Read");
|
||||||
|
private ProfilerMarker _hasMark = new ProfilerMarker("EcsPoo.Has");
|
||||||
|
private ProfilerMarker _delMark = new ProfilerMarker("EcsPoo.Del");
|
||||||
|
public ref T Write(int entityID)
|
||||||
{
|
{
|
||||||
return _sparseSet.IndexOf(entity) >= 0;
|
//using (_writeMark.Auto())
|
||||||
|
//{
|
||||||
|
ref int itemIndex = ref _mapping[entityID];
|
||||||
|
if (itemIndex <= 0) //åñëè 0 òî íàäî äîáàâèòü
|
||||||
|
{
|
||||||
|
if (_recycledItemsCount > 0)
|
||||||
|
{
|
||||||
|
itemIndex = _recycledItems[--_recycledItemsCount];
|
||||||
|
_itemsCount++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
itemIndex = _itemsCount++;
|
||||||
|
if (itemIndex >= _items.Length)
|
||||||
|
Array.Resize(ref _items, _items.Length << 1);
|
||||||
|
}
|
||||||
|
_mapping[entityID] = itemIndex;
|
||||||
|
_componentResetHandler.Reset(ref _items[itemIndex]);
|
||||||
|
_source.OnEntityComponentAdded(entityID, _id);
|
||||||
|
_poolRunnres.add.OnComponentAdd<T>(entityID);
|
||||||
|
}
|
||||||
|
|
||||||
|
_poolRunnres.write.OnComponentWrite<T>(entityID);
|
||||||
|
return ref _items[itemIndex];
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Del(int entity)
|
public ref readonly T Read(int entityID)
|
||||||
{
|
{
|
||||||
_sparseSet.RemoveAt(entity);
|
//using (_readMark.Auto())
|
||||||
_source.OnEntityComponentRemoved(entity, _id);
|
return ref _items[_mapping[entityID]];
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public bool Has(int entityID)
|
||||||
|
{
|
||||||
|
//using (_hasMark.Auto())
|
||||||
|
return _mapping[entityID] > 0;
|
||||||
|
}
|
||||||
|
public void Del(int entityID)
|
||||||
|
{
|
||||||
|
//using (_delMark.Auto())
|
||||||
|
//{
|
||||||
|
if(_recycledItemsCount >= _recycledItems.Length)
|
||||||
|
Array.Resize(ref _recycledItems, _recycledItems.Length << 1);
|
||||||
|
_recycledItems[_recycledItemsCount++] = _mapping[entityID];
|
||||||
|
_mapping[entityID] = 0;
|
||||||
|
_itemsCount--;
|
||||||
|
//_entities.UncheckedRemove(entityID);
|
||||||
|
_source.OnEntityComponentRemoved(entityID, _id);
|
||||||
|
_poolRunnres.del.OnComponentDel<T>(entityID);
|
||||||
|
//}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -123,33 +170,10 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
public override int GetHashCode() => _source.GetHashCode() + ID;
|
public override int GetHashCode() => _source.GetHashCode() + ID;
|
||||||
#endregion
|
#endregion
|
||||||
}
|
|
||||||
|
|
||||||
#region ComponentResetHandler
|
void IEcsPool.OnWorldResize(int newSize)
|
||||||
internal static class ComponentResetHandler
|
|
||||||
{
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static IEcsComponentReset<T> New<T>()
|
|
||||||
{
|
{
|
||||||
Type targetType = typeof(T);
|
Array.Resize(ref _mapping, newSize);
|
||||||
if (targetType.GetInterfaces().Contains(typeof(IEcsComponentReset<>).MakeGenericType(targetType)))
|
|
||||||
{
|
|
||||||
return (IEcsComponentReset<T>)Activator.CreateInstance(typeof(ComponentResetHandler<>).MakeGenericType(targetType));
|
|
||||||
}
|
|
||||||
return (IEcsComponentReset<T>)Activator.CreateInstance(typeof(ComponentResetDummy<>).MakeGenericType(targetType));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
internal sealed class ComponentResetDummy<T> : IEcsComponentReset<T>
|
|
||||||
{
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public void Reset(ref T component) => component = default;
|
|
||||||
}
|
|
||||||
internal sealed class ComponentResetHandler<T> : IEcsComponentReset<T>
|
|
||||||
where T : IEcsComponentReset<T>
|
|
||||||
{
|
|
||||||
private T _fakeInstnace = default;
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public void Reset(ref T component) => _fakeInstnace.Reset(ref component);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@ namespace DCFApixels.DragonECS
|
|||||||
.Where(type => type.BaseType != null && type.BaseType.IsGenericType && runnerBaseType == type.BaseType.GetGenericTypeDefinition()));
|
.Where(type => type.BaseType != null && type.BaseType.IsGenericType && runnerBaseType == type.BaseType.GetGenericTypeDefinition()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
|
#if (DEBUG && !DISABLE_DRAGONECS_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||||
for (int i = 0; i < runnerHandlerTypes.Count; i++)
|
for (int i = 0; i < runnerHandlerTypes.Count; i++)
|
||||||
{
|
{
|
||||||
var e = CheckRunnerValide(runnerHandlerTypes[i]);
|
var e = CheckRunnerValide(runnerHandlerTypes[i]);
|
||||||
@ -136,7 +136,7 @@ namespace DCFApixels.DragonECS
|
|||||||
private static Type _subclass;
|
private static Type _subclass;
|
||||||
internal static void Register(Type subclass)
|
internal static void Register(Type subclass)
|
||||||
{
|
{
|
||||||
#if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
|
#if (DEBUG && !DISABLE_DRAGONECS_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||||
if (_subclass != null)
|
if (_subclass != null)
|
||||||
{
|
{
|
||||||
throw new EcsRunnerImplementationException($"The Runner<{typeof(TInterface).FullName}> can have only one implementing subclass");
|
throw new EcsRunnerImplementationException($"The Runner<{typeof(TInterface).FullName}> can have only one implementing subclass");
|
||||||
|
229
src/EcsWorld.cs
229
src/EcsWorld.cs
@ -2,6 +2,8 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Xml;
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
@ -12,9 +14,12 @@ namespace DCFApixels.DragonECS
|
|||||||
public bool IsEmpty { get; }
|
public bool IsEmpty { get; }
|
||||||
public Type ArchetypeType { get; }
|
public Type ArchetypeType { get; }
|
||||||
public int ID { get; }
|
public int ID { get; }
|
||||||
|
public EcsPipeline Pipeline { get; }
|
||||||
|
public int EntitesCount { get; }
|
||||||
|
public int EntitesCapacity { get; }
|
||||||
|
public EcsReadonlyGroup Entities { get; }
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
#region GetterMethods
|
#region GetterMethods
|
||||||
public ReadOnlySpan<IEcsPool> GetAllPools();
|
public ReadOnlySpan<IEcsPool> GetAllPools();
|
||||||
|
|
||||||
@ -22,12 +27,13 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
public EcsPool<T> GetPool<T>() where T : struct;
|
public EcsPool<T> GetPool<T>() where T : struct;
|
||||||
|
public EcsPool<T> UncheckedGetPool<T>() where T : struct;
|
||||||
public EcsFilter Filter<TInc>() where TInc : struct, IInc;
|
public EcsFilter Filter<TInc>() where TInc : struct, IInc;
|
||||||
public EcsFilter Filter<TInc, TExc>() where TInc : struct, IInc where TExc : struct, IExc;
|
public EcsFilter Filter<TInc, TExc>() where TInc : struct, IInc where TExc : struct, IExc;
|
||||||
public ent NewEntity();
|
public ent NewEntity();
|
||||||
|
public void DelEntity(ent entity);
|
||||||
public bool EntityIsAlive(int entityID, short gen);
|
public bool EntityIsAlive(int entityID, short gen);
|
||||||
public ent GetEntity(int entityID);
|
public ent GetEntity(int entityID);
|
||||||
public void DelEntity(int entityID);
|
|
||||||
public void Destroy();
|
public void Destroy();
|
||||||
|
|
||||||
public bool IsMaskCompatible(EcsMask mask, int entity);
|
public bool IsMaskCompatible(EcsMask mask, int entity);
|
||||||
@ -35,6 +41,10 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
internal void OnEntityComponentAdded(int entityID, int changedPoolID);
|
internal void OnEntityComponentAdded(int entityID, int changedPoolID);
|
||||||
internal void OnEntityComponentRemoved(int entityID, int changedPoolID);
|
internal void OnEntityComponentRemoved(int entityID, int changedPoolID);
|
||||||
|
|
||||||
|
public int GetComponentID<T>();
|
||||||
|
|
||||||
|
internal void RegisterGroup(EcsGroup group);
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,6 +58,8 @@ namespace DCFApixels.DragonECS
|
|||||||
public EcsWorld()
|
public EcsWorld()
|
||||||
{
|
{
|
||||||
id = (short)_worldIdDispenser.GetFree();
|
id = (short)_worldIdDispenser.GetFree();
|
||||||
|
if(id >= Worlds.Length)
|
||||||
|
Array.Resize(ref Worlds, Worlds.Length << 1);
|
||||||
Worlds[id] = (IEcsWorld)this;
|
Worlds[id] = (IEcsWorld)this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,8 +87,19 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
private EcsFilter[] _filters;
|
private EcsFilter[] _filters;
|
||||||
|
|
||||||
|
private EcsPipeline _pipeline;
|
||||||
|
|
||||||
|
private List<EcsGroup> _groups;
|
||||||
|
|
||||||
|
#region RunnersCache
|
||||||
|
private PoolRunnres _poolRunnres;
|
||||||
|
private IEcsEntityCreate _entityCreate;
|
||||||
|
private IEcsEntityDestroy _entityDestry;
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region GetterMethods
|
#region GetterMethods
|
||||||
public ReadOnlySpan<IEcsPool> GetAllPools() => new ReadOnlySpan<IEcsPool>(_pools);
|
public ReadOnlySpan<IEcsPool> GetAllPools() => new ReadOnlySpan<IEcsPool>(_pools);
|
||||||
|
public int GetComponentID<T>() => ComponentType<T>.uniqueID;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -84,21 +107,38 @@ namespace DCFApixels.DragonECS
|
|||||||
public bool IsEmpty => _entities.Count < 0;
|
public bool IsEmpty => _entities.Count < 0;
|
||||||
public Type ArchetypeType => typeof(TArchetype);
|
public Type ArchetypeType => typeof(TArchetype);
|
||||||
public int ID => id;
|
public int ID => id;
|
||||||
|
public EcsPipeline Pipeline => _pipeline;
|
||||||
|
|
||||||
|
public int EntitesCount => _entities.Count;
|
||||||
|
public int EntitesCapacity => _entities.CapacityDense;
|
||||||
|
public EcsReadonlyGroup Entities => _entities.Readonly;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
public EcsWorld()
|
public EcsWorld(EcsPipeline pipline = null)
|
||||||
{
|
{
|
||||||
|
_pipeline = pipline ?? EcsPipeline.Empty;
|
||||||
|
if (!_pipeline.IsInit) pipline.Init();
|
||||||
_entityDispenser = new IntDispenser(1);
|
_entityDispenser = new IntDispenser(1);
|
||||||
_nullPool = new EcsNullPool(this);
|
_nullPool = new EcsNullPool(this);
|
||||||
_pools = new IEcsPool[512];
|
_pools = new IEcsPool[512];
|
||||||
FillArray(_pools, _nullPool);
|
FillArray(_pools, _nullPool);
|
||||||
//Array.Fill(_pools, _nullPool); //TODO Fix it
|
|
||||||
_gens = new short[512];
|
_gens = new short[512];
|
||||||
_filters = new EcsFilter[64];
|
_filters = new EcsFilter[64];
|
||||||
_entities = new EcsGroup(this, 512);
|
_groups = new List<EcsGroup>(128);
|
||||||
|
|
||||||
|
_entities = new EcsGroup(this, 512, 512, 0);
|
||||||
|
|
||||||
_filtersByIncludedComponents = new List<EcsFilter>[16];
|
_filtersByIncludedComponents = new List<EcsFilter>[16];
|
||||||
_filtersByExcludedComponents = new List<EcsFilter>[16];
|
_filtersByExcludedComponents = new List<EcsFilter>[16];
|
||||||
|
|
||||||
|
_poolRunnres = new PoolRunnres(_pipeline);
|
||||||
|
_entityCreate = _pipeline.GetRunner<IEcsEntityCreate>();
|
||||||
|
_entityDestry = _pipeline.GetRunner<IEcsEntityDestroy>();
|
||||||
|
_pipeline.GetRunner<IEcsInject<TArchetype>>().Inject((TArchetype)this);
|
||||||
|
_pipeline.GetRunner<IEcsInject<IEcsWorld>>().Inject(this);
|
||||||
|
_pipeline.GetRunner<IEcsWorldCreate>().OnWorldCreate(this);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -120,14 +160,17 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
if (_pools[uniqueID] == _nullPool)
|
if (_pools[uniqueID] == _nullPool)
|
||||||
{
|
{
|
||||||
_pools[uniqueID] = new EcsPool<T>(this, ComponentType<T>.uniqueID, 512);
|
_pools[uniqueID] = new EcsPool<T>(this, ComponentType<T>.uniqueID, 512, _poolRunnres);
|
||||||
}
|
}
|
||||||
return (EcsPool<T>)_pools[uniqueID];
|
return (EcsPool<T>)_pools[uniqueID];
|
||||||
}
|
}
|
||||||
|
public EcsPool<T> UncheckedGetPool<T>() where T : struct
|
||||||
|
{
|
||||||
|
return (EcsPool<T>)_pools[ComponentType<T>.uniqueID];
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region GetFilter
|
#region GetFilter
|
||||||
public EcsFilter Filter<TInc>() where TInc : struct, IInc => Filter<TInc, Exc>();
|
public EcsFilter Filter<TInc>() where TInc : struct, IInc => Filter<TInc, Exc>();
|
||||||
public EcsFilter Filter<TInc, TExc>() where TInc : struct, IInc where TExc : struct, IExc
|
public EcsFilter Filter<TInc, TExc>() where TInc : struct, IInc where TExc : struct, IExc
|
||||||
{
|
{
|
||||||
@ -181,7 +224,6 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@ -189,7 +231,7 @@ namespace DCFApixels.DragonECS
|
|||||||
#region IsMaskCompatible/IsMaskCompatibleWithout
|
#region IsMaskCompatible/IsMaskCompatibleWithout
|
||||||
public bool IsMaskCompatible(EcsMask mask, int entity)
|
public bool IsMaskCompatible(EcsMask mask, int entity)
|
||||||
{
|
{
|
||||||
#if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
|
#if (DEBUG && !DISABLE_DRAGONECS_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||||
if (mask.WorldArchetypeType != typeof(TArchetype))
|
if (mask.WorldArchetypeType != typeof(TArchetype))
|
||||||
throw new EcsFrameworkException("mask.WorldArchetypeType != typeof(TArchetype)");
|
throw new EcsFrameworkException("mask.WorldArchetypeType != typeof(TArchetype)");
|
||||||
#endif
|
#endif
|
||||||
@ -208,7 +250,7 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
public bool IsMaskCompatibleWithout(EcsMask mask, int entity, int otherComponentID)
|
public bool IsMaskCompatibleWithout(EcsMask mask, int entity, int otherComponentID)
|
||||||
{
|
{
|
||||||
#if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
|
#if (DEBUG && !DISABLE_DRAGONECS_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||||
if (mask.WorldArchetypeType != typeof(TArchetype))
|
if (mask.WorldArchetypeType != typeof(TArchetype))
|
||||||
throw new EcsFrameworkException("mask.WorldArchetypeType != typeof(TArchetype)");
|
throw new EcsFrameworkException("mask.WorldArchetypeType != typeof(TArchetype)");
|
||||||
#endif
|
#endif
|
||||||
@ -220,8 +262,8 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
for (int i = 0, iMax = mask.ExcCount; i < iMax; i++)
|
for (int i = 0, iMax = mask.ExcCount; i < iMax; i++)
|
||||||
{
|
{
|
||||||
int poolID = mask.Exc[i];
|
int componentID = mask.Exc[i];
|
||||||
if (poolID != otherComponentID && _pools[poolID].Has(entity))
|
if (componentID != otherComponentID && _pools[componentID].Has(entity))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -234,53 +276,59 @@ namespace DCFApixels.DragonECS
|
|||||||
var includeList = _filtersByIncludedComponents[componentID];
|
var includeList = _filtersByIncludedComponents[componentID];
|
||||||
var excludeList = _filtersByExcludedComponents[componentID];
|
var excludeList = _filtersByExcludedComponents[componentID];
|
||||||
|
|
||||||
if (includeList != null)
|
//if (includeList != null)
|
||||||
{
|
//{
|
||||||
foreach (var filter in includeList)
|
// foreach (var filter in includeList)
|
||||||
{
|
// {
|
||||||
if (IsMaskCompatible(filter.Mask, entityID))
|
// if (IsMaskCompatible(filter.Mask, entityID))
|
||||||
{
|
// {
|
||||||
filter.Add(entityID);
|
// filter.Add(entityID);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
if (excludeList != null)
|
//if (excludeList != null)
|
||||||
{
|
//{
|
||||||
foreach (var filter in excludeList)
|
// foreach (var filter in excludeList)
|
||||||
{
|
// {
|
||||||
if (IsMaskCompatibleWithout(filter.Mask, entityID, componentID))
|
// if (IsMaskCompatibleWithout(filter.Mask, entityID, componentID))
|
||||||
{
|
// {
|
||||||
filter.Remove(entityID);
|
// filter.Remove(entityID);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
if (includeList != null) foreach (var filter in includeList) filter.entities.Add(entityID);
|
||||||
|
if (excludeList != null) foreach (var filter in excludeList) filter.entities.Remove(entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
void IEcsWorld.OnEntityComponentRemoved(int entityID, int changedPoolID)
|
void IEcsWorld.OnEntityComponentRemoved(int entityID, int componentID)
|
||||||
{
|
{
|
||||||
var includeList = _filtersByIncludedComponents[changedPoolID];
|
var includeList = _filtersByIncludedComponents[componentID];
|
||||||
var excludeList = _filtersByExcludedComponents[changedPoolID];
|
var excludeList = _filtersByExcludedComponents[componentID];
|
||||||
|
|
||||||
if (includeList != null)
|
//if (includeList != null)
|
||||||
{
|
//{
|
||||||
foreach (var filter in includeList)
|
// foreach (var filter in includeList)
|
||||||
{
|
// {
|
||||||
if (IsMaskCompatible(filter.Mask, entityID))
|
// if (IsMaskCompatible(filter.Mask, entityID))
|
||||||
{
|
// {
|
||||||
filter.Remove(entityID);
|
// filter.Remove(entityID);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
if (excludeList != null)
|
//if (excludeList != null)
|
||||||
{
|
//{
|
||||||
foreach (var filter in excludeList)
|
// foreach (var filter in excludeList)
|
||||||
{
|
// {
|
||||||
if (IsMaskCompatibleWithout(filter.Mask, entityID, changedPoolID))
|
// if (IsMaskCompatibleWithout(filter.Mask, entityID, componentID))
|
||||||
{
|
// {
|
||||||
filter.Add(entityID);
|
// filter.Add(entityID);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
|
||||||
|
if (includeList != null) foreach (var filter in includeList) filter.entities.Remove(entityID);
|
||||||
|
if (excludeList != null) foreach (var filter in excludeList) filter.entities.Add(entityID);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -288,23 +336,37 @@ namespace DCFApixels.DragonECS
|
|||||||
public ent NewEntity()
|
public ent NewEntity()
|
||||||
{
|
{
|
||||||
int entityID = _entityDispenser.GetFree();
|
int entityID = _entityDispenser.GetFree();
|
||||||
_entities.Add(entityID);
|
_entities.UncheckedAdd(entityID);
|
||||||
if (_gens.Length <= entityID)
|
if (_gens.Length <= entityID)
|
||||||
|
{
|
||||||
Array.Resize(ref _gens, _gens.Length << 1);
|
Array.Resize(ref _gens, _gens.Length << 1);
|
||||||
return new ent(entityID, _gens[entityID]++, id);
|
_entities.OnWorldResize(_gens.Length);
|
||||||
|
foreach (var item in _groups)
|
||||||
|
{
|
||||||
|
item.OnWorldResize(_gens.Length);
|
||||||
|
}
|
||||||
|
foreach (var item in _pools)
|
||||||
|
{
|
||||||
|
item.OnWorldResize(_gens.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ent entity = new ent(entityID, _gens[entityID]++, id);
|
||||||
|
_entityCreate.OnEntityCreate(entity);
|
||||||
|
return entity;
|
||||||
}
|
}
|
||||||
|
public void DelEntity(ent entity)
|
||||||
|
{
|
||||||
|
_entityDispenser.Release(entity.id);
|
||||||
|
_entities.UncheckedRemove(entity.id);
|
||||||
|
_entityDestry.OnEntityDestroy(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public ent GetEntity(int entityID)
|
public ent GetEntity(int entityID)
|
||||||
{
|
{
|
||||||
if (_entities.Contains(entityID) == false)
|
|
||||||
return ent.NULL;
|
|
||||||
|
|
||||||
return new ent(entityID, _gens[entityID], id);
|
return new ent(entityID, _gens[entityID], id);
|
||||||
}
|
}
|
||||||
public void DelEntity(int entityID)
|
|
||||||
{
|
|
||||||
_entityDispenser.Release(entityID);
|
|
||||||
_entities.Remove(entityID);
|
|
||||||
}
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool EntityIsAlive(int entityID, short gen)
|
public bool EntityIsAlive(int entityID, short gen)
|
||||||
{
|
{
|
||||||
@ -325,6 +387,11 @@ namespace DCFApixels.DragonECS
|
|||||||
_filters = null;
|
_filters = null;
|
||||||
Realeze();
|
Realeze();
|
||||||
}
|
}
|
||||||
|
public void DestryWithPipeline()
|
||||||
|
{
|
||||||
|
Destroy();
|
||||||
|
_pipeline.Destroy();
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Utils
|
#region Utils
|
||||||
@ -344,7 +411,7 @@ namespace DCFApixels.DragonECS
|
|||||||
static ComponentType()
|
static ComponentType()
|
||||||
{
|
{
|
||||||
uniqueID = ComponentType.increment++;
|
uniqueID = ComponentType.increment++;
|
||||||
#if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
|
#if (DEBUG && !DISABLE_DRAGONECS_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||||
if (ComponentType.increment + 1 > ushort.MaxValue)
|
if (ComponentType.increment + 1 > ushort.MaxValue)
|
||||||
{
|
{
|
||||||
throw new EcsFrameworkException($"No more room for new component for this {typeof(TArchetype).FullName} IWorldArchetype");
|
throw new EcsFrameworkException($"No more room for new component for this {typeof(TArchetype).FullName} IWorldArchetype");
|
||||||
@ -374,15 +441,27 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
|
||||||
|
|
||||||
#region Extensions
|
#region Other
|
||||||
public static class IEcsWorldExtensions
|
void IEcsWorld.RegisterGroup(EcsGroup group)
|
||||||
{
|
|
||||||
public static void DelEntity(this IEcsWorld self, ent entity)
|
|
||||||
{
|
{
|
||||||
self.DelEntity(entity.id);
|
_groups.Add(group);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 8, Size = 24)]
|
||||||
|
internal readonly struct PoolRunnres
|
||||||
|
{
|
||||||
|
public readonly IEcsComponentAdd add;
|
||||||
|
public readonly IEcsComponentWrite write;
|
||||||
|
public readonly IEcsComponentDel del;
|
||||||
|
|
||||||
|
public PoolRunnres(EcsPipeline pipeline)
|
||||||
|
{
|
||||||
|
add = pipeline.GetRunner<IEcsComponentAdd>();
|
||||||
|
write = pipeline.GetRunner<IEcsComponentWrite>();
|
||||||
|
del = pipeline.GetRunner<IEcsComponentDel>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
}
|
}
|
||||||
|
32
src/Utils/ComponentResetHandler.cs
Normal file
32
src/Utils/ComponentResetHandler.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS
|
||||||
|
{
|
||||||
|
internal static class ComponentResetHandler
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static IEcsComponentReset<T> New<T>()
|
||||||
|
{
|
||||||
|
Type targetType = typeof(T);
|
||||||
|
if (targetType.GetInterfaces().Contains(typeof(IEcsComponentReset<>).MakeGenericType(targetType)))
|
||||||
|
{
|
||||||
|
return (IEcsComponentReset<T>)Activator.CreateInstance(typeof(ComponentResetHandler<>).MakeGenericType(targetType));
|
||||||
|
}
|
||||||
|
return (IEcsComponentReset<T>)Activator.CreateInstance(typeof(ComponentResetDummy<>).MakeGenericType(targetType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
internal sealed class ComponentResetDummy<T> : IEcsComponentReset<T>
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void Reset(ref T component) => component = default;
|
||||||
|
}
|
||||||
|
internal sealed class ComponentResetHandler<T> : IEcsComponentReset<T>
|
||||||
|
where T : IEcsComponentReset<T>
|
||||||
|
{
|
||||||
|
private T _fakeInstnace = default;
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void Reset(ref T component) => _fakeInstnace.Reset(ref component);
|
||||||
|
}
|
||||||
|
}
|
16
src/ent.cs
16
src/ent.cs
@ -97,18 +97,18 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool IsAlive(this ref ent self)
|
public static bool IsAlive(this ref ent self)
|
||||||
{
|
{
|
||||||
using (_IsAliveMarker.Auto())
|
//using (_IsAliveMarker.Auto())
|
||||||
{
|
//{
|
||||||
bool result = EcsWorld.Worlds[self.world].EntityIsAlive(self.id, self.gen);
|
bool result = EcsWorld.Worlds[self.world].EntityIsAlive(self.id, self.gen);
|
||||||
if (!result) self = ent.NULL;
|
if (!result) self = ent.NULL;
|
||||||
return result;
|
return result;
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool IsNull(this in ent self)
|
public static bool IsNull(this in ent self)
|
||||||
{
|
{
|
||||||
using (_IsNullMarker.Auto())
|
//using (_IsNullMarker.Auto())
|
||||||
return self == ent.NULL;
|
return self == ent.NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,28 +116,28 @@ namespace DCFApixels.DragonECS
|
|||||||
public static ref readonly T Read<T>(this in ent self)
|
public static ref readonly T Read<T>(this in ent self)
|
||||||
where T : struct
|
where T : struct
|
||||||
{
|
{
|
||||||
using (_ReadMarker.Auto())
|
//using (_ReadMarker.Auto())
|
||||||
return ref EcsWorld.Worlds[self.world].GetPool<T>().Read(self.id);
|
return ref EcsWorld.Worlds[self.world].GetPool<T>().Read(self.id);
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static ref T Write<T>(this in ent self)
|
public static ref T Write<T>(this in ent self)
|
||||||
where T : struct
|
where T : struct
|
||||||
{
|
{
|
||||||
using (_WriteMarker.Auto())
|
//using (_WriteMarker.Auto())
|
||||||
return ref EcsWorld.Worlds[self.world].GetPool<T>().Write(self.id);
|
return ref EcsWorld.Worlds[self.world].GetPool<T>().Write(self.id);
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool Has<T>(this in ent self)
|
public static bool Has<T>(this in ent self)
|
||||||
where T : struct
|
where T : struct
|
||||||
{
|
{
|
||||||
using (_HasMarker.Auto())
|
//using (_HasMarker.Auto())
|
||||||
return EcsWorld.Worlds[self.world].GetPool<T>().Has(self.id);
|
return EcsWorld.Worlds[self.world].GetPool<T>().Has(self.id);
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static void Del<T>(this in ent self)
|
public static void Del<T>(this in ent self)
|
||||||
where T : struct
|
where T : struct
|
||||||
{
|
{
|
||||||
using (_DelMarker.Auto())
|
//using (_DelMarker.Auto())
|
||||||
EcsWorld.Worlds[self.world].GetPool<T>().Del(self.id);
|
EcsWorld.Worlds[self.world].GetPool<T>().Del(self.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user