diff --git a/src/Builtin/BaseRunners.cs b/src/Builtin/BaseRunners.cs index a618cb7..b8e5b5e 100644 --- a/src/Builtin/BaseRunners.cs +++ b/src/Builtin/BaseRunners.cs @@ -22,12 +22,12 @@ public sealed class EcsPreInitRunner : EcsRunner, IEcsPreInitSystem { -#if DEBUG && !DISABLE_DRAGONECS_DEBUG +#if DEBUG && !DISABLE_DEBUG private EcsProfilerMarker[] _markers; #endif public void PreInit(EcsPipeline pipeline) { -#if DEBUG && !DISABLE_DRAGONECS_DEBUG +#if DEBUG && !DISABLE_DEBUG for (int i = 0; i < targets.Length; i++) { using (_markers[i].Auto()) @@ -38,7 +38,7 @@ #endif } -#if DEBUG && !DISABLE_DRAGONECS_DEBUG +#if DEBUG && !DISABLE_DEBUG protected override void OnSetup() { _markers = new EcsProfilerMarker[targets.Length]; @@ -51,12 +51,12 @@ } public sealed class EcsInitRunner : EcsRunner, IEcsInitSystem { -#if DEBUG && !DISABLE_DRAGONECS_DEBUG +#if DEBUG && !DISABLE_DEBUG private EcsProfilerMarker[] _markers; #endif public void Init(EcsPipeline pipeline) { -#if DEBUG && !DISABLE_DRAGONECS_DEBUG +#if DEBUG && !DISABLE_DEBUG for (int i = 0; i < targets.Length; i++) { using (_markers[i].Auto()) @@ -67,7 +67,7 @@ #endif } -#if DEBUG && !DISABLE_DRAGONECS_DEBUG +#if DEBUG && !DISABLE_DEBUG protected override void OnSetup() { _markers = new EcsProfilerMarker[targets.Length]; @@ -80,12 +80,12 @@ } public sealed class EcsRunRunner : EcsRunner, IEcsRunSystem { -#if DEBUG && !DISABLE_DRAGONECS_DEBUG +#if DEBUG && !DISABLE_DEBUG private EcsProfilerMarker[] _markers; #endif public void Run(EcsPipeline pipeline) { -#if DEBUG && !DISABLE_DRAGONECS_DEBUG +#if DEBUG && !DISABLE_DEBUG for (int i = 0; i < targets.Length; i++) { using (_markers[i].Auto()) @@ -97,7 +97,7 @@ #endif } -#if DEBUG && !DISABLE_DRAGONECS_DEBUG +#if DEBUG && !DISABLE_DEBUG protected override void OnSetup() { _markers = new EcsProfilerMarker[targets.Length]; @@ -110,12 +110,12 @@ } public sealed class EcsDestroyRunner : EcsRunner, IEcsDestroySystem { -#if DEBUG && !DISABLE_DRAGONECS_DEBUG +#if DEBUG && !DISABLE_DEBUG private EcsProfilerMarker[] _markers; #endif public void Destroy(EcsPipeline pipeline) { -#if DEBUG && !DISABLE_DRAGONECS_DEBUG +#if DEBUG && !DISABLE_DEBUG for (int i = 0; i < targets.Length; i++) { using (_markers[i].Auto()) @@ -126,7 +126,7 @@ #endif } -#if DEBUG && !DISABLE_DRAGONECS_DEBUG +#if DEBUG && !DISABLE_DEBUG protected override void OnSetup() { _markers = new EcsProfilerMarker[targets.Length]; diff --git a/src/EcsGroup.cs b/src/EcsGroup.cs index b046358..a9d7c34 100644 --- a/src/EcsGroup.cs +++ b/src/EcsGroup.cs @@ -1,4 +1,5 @@ using System; +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using delayedOp = System.Int32; @@ -188,6 +189,20 @@ namespace DCFApixels.DragonECS //TODO добавить автосоритровку при каждом GetEnumerator и проверить будет ли прирост производительности или ее падение. //Суть в том что так возможно можно будет более плотно подавать данные в проц + public void Sort() + { + int increment = 1; + for (int i = 0; i < _dense.Length; i++) + { + if (_sparse[i] > 0) + { + _sparse[i] = increment; + _dense[increment++] = i; + } + } + } + + #region AddGroup/RemoveGroup public void AddGroup(EcsReadonlyGroup group) { foreach (var item in group) Add(item.id); } @@ -233,6 +248,7 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] public Enumerator GetEnumerator() { + Sort(); _lockCount++; return new Enumerator(this); } diff --git a/src/EcsRelationTable.cs b/src/EcsRelationTable.cs index 069b817..8f2e430 100644 --- a/src/EcsRelationTable.cs +++ b/src/EcsRelationTable.cs @@ -8,7 +8,7 @@ namespace DCFApixels.DragonECS /* public interface IEcsRealationTable : IEcsReadonlyTable { public EcsFilter Relations() where TComponent : struct; - + rr } public sealed class EcsRelationTable : IEcsRealationTable where TArchetype : EcsRelationTableArchetypeBase diff --git a/src/EcsTable.cs b/src/EcsTable.cs new file mode 100644 index 0000000..69bb40a --- /dev/null +++ b/src/EcsTable.cs @@ -0,0 +1,265 @@ +using DCFApixels.DragonECS; +/*using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http.Headers; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Text; +using System.Threading.Tasks; +using UnityEngine.WSA; +using static UnityEditor.Experimental.GraphView.Port; + +namespace DCFApixels.Assets.DragonECS.src +{ + public struct Pose { } + public struct Health { } + public struct Mana { } + public struct EnemyTag { } + + public class TestArhetype : EcsEntityArhetype + { + public inc pose; + public inc health; + public opt mana; + public exc enemyTag; + + public TestArhetype(Builder b) : base(b) + { + pose = b.Include(); + health = b.Include(); + mana = b.Optional(); + enemyTag = b.Exclude(); + } + } + public class TestSystem : IEcsRunSystem + { + private TestArhetype test; + public void Run(EcsPipeline pipeline) + { + foreach (var e in test) + { + test.health.Read(e.id); + test.pose.Write(e.id) = new Pose(); + } + } + } + + + + + + + + + + + public abstract class EcsWorldArhetype + { + public EcsWorldArhetype(IEcsWorld world) { } + } + + public interface IFakeWorld { } + public class FakeWorld : IFakeWorld + where TWorldArhetype : EcsWorldArhetype + { + public readonly TWorldArhetype data; + + private EcsEntityArhetype[] _arhetypes; + + + public FakeWorld() + { + _arhetypes = new EcsEntityArhetype[ArhetypeID.capacity]; + } + + public TArhetype Arhetype() where TArhetype : EcsEntityArhetype + { + int id = ArhetypeID.id; + if (_arhetypes.Length < ArhetypeID.capacity) + Array.Resize(ref _arhetypes, ArhetypeID.capacity); + + if (_arhetypes[id] == null) + { + EcsEntityArhetype.Builder builder = new EcsEntityArhetype.Builder(this); + _arhetypes[id] = (TArhetype)Activator.CreateInstance(typeof(TArhetype), builder); + builder.End(); + } + + return (TArhetype)_arhetypes[id]; + } + + + #region ArhetypeID + private static class ArhetypeID + { + public static int count = 0; + public static int capacity = 128; + } + private static class ArhetypeID + { + public static int id; + static ArhetypeID() + { + id = ArhetypeID.count++; + if (ArhetypeID.count > ArhetypeID.capacity) + ArhetypeID.capacity <<= 1; + } + } + #endregion + } + + public interface IEcsEntityArhetype + { + internal void AddEntity(int entityID); + internal void RemoveEntity(int entityID); + } + public class EcsEntityArhetype : IEcsEntityArhetype + where TWorldArhetype : EcsWorldArhetype + { + private int _id; + private EcsGroup _group; + + public int ID => _id; + public EcsReadonlyGroup entities + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => _group.Readonly; + } + + public EcsEntityArhetype(Builder b) { } + + public EcsGroup.Enumerator GetEnumerator() => _group.GetEnumerator(); + + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void IEcsEntityArhetype.AddEntity(int entityID) => _group.Add(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + void IEcsEntityArhetype.RemoveEntity(int entityID) => _group.Remove(entityID); + + #region Builder + public class Builder + { + private IFakeWorld _world; + private List _inc; + private List _exc; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal Builder(IFakeWorld world) + { + _world = world; + } + + public inc Include() where TComponent : struct + { + _inc.Add(_world.GetComponentID()); + return new inc(_world.GetPool()); + } + public exc Exclude() where TComponent : struct + { + _exc.Add(_world.GetComponentID()); + return new exc(_world.GetPool()); + } + public opt Optional() where TComponent : struct + { + return new opt(_world.GetPool()); + } + + internal void End(out EcsEntityArhetypeMask mask) + { + _inc.Sort(); + _exc.Sort(); + mask = new EcsEntityArhetypeMask(_world.ArchetypeType, _inc.ToArray(), _exc.ToArray()); + + _world = null; + _inc.Clear(); + _inc = null; + _exc.Clear(); + _exc = null; + } + } + #endregion + } + + + public interface IEcsFiled + where TComponent : struct + { + public ref TComponent Write(int entityID); + public ref readonly TComponent Read(int entityID); + public bool Has(int entityID); + public void Del(int entityID); + } + + [StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)] + public readonly struct inc : IEcsFiled + where TComponent : struct + { + private readonly EcsPool _pool; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal inc(EcsPool pool) => _pool = pool; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ref TComponent Write(int entityID) => ref _pool.Write(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ref readonly TComponent Read(int entityID) => ref _pool.Read(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Has(int entityID) => _pool.Has(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Del(int entityID) => _pool.Del(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override string ToString() => $"{(_pool == null ? "NULL" : _pool.World.ArchetypeType.Name)}inc<{typeof(TComponent).Name}>"; + } + + [StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)] + public readonly struct exc : IEcsFiled + where TComponent : struct + { + private readonly EcsPool _pool; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal exc(EcsPool pool) => _pool = pool; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ref TComponent Write(int entityID) => ref _pool.Write(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ref readonly TComponent Read(int entityID) => ref _pool.Read(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Has(int entityID) => _pool.Has(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Del(int entityID) => _pool.Del(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override string ToString() => $"{(_pool == null ? "NULL" : _pool.World.ArchetypeType.Name)}exc<{typeof(TComponent).Name}>"; + } + + [StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)] + public readonly struct opt : IEcsFiled + where TComponent : struct + { + private readonly EcsPool _pool; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal opt(EcsPool pool) => _pool = pool; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ref TComponent Write(int entityID) => ref _pool.Write(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ref readonly TComponent Read(int entityID) => ref _pool.Read(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool Has(int entityID) => _pool.Has(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Del(int entityID) => _pool.Del(entityID); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public override string ToString() => $"{(_pool == null ? "NULL" : _pool.World.ArchetypeType.Name)}opt<{typeof(TComponent).Name}>"; + } + + public class EcsEntityArhetypeMask + { + internal readonly Type WorldArchetypeType; + internal readonly int[] Inc; + internal readonly int[] Exc; + public EcsEntityArhetypeMask(Type worldArchetypeType, int[] inc, int[] exc) + { + WorldArchetypeType = worldArchetypeType; + Inc = inc; + Exc = exc; + } + } + +} +*/ \ No newline at end of file