diff --git a/src/EcsGroup.cs b/src/EcsGroup.cs index c6d0ffd..9a25f35 100644 --- a/src/EcsGroup.cs +++ b/src/EcsGroup.cs @@ -1,6 +1,7 @@ using System; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; +using Unity.Profiling; using static UnityEngine.Networking.UnityWebRequest; using delayedOp = System.Int32; @@ -75,7 +76,7 @@ namespace DCFApixels.DragonECS // _delayedOps это int[] для отложенных операций, хранятся отложенные операции в виде int значения, если старший бит = 0 то это опреация добавленияб если = 1 то это операция вычитания // this collection can only store numbers greater than 0 - public class EcsGroup + public unsafe class EcsGroup { private const int DEALAYED_ADD = 0; private const int DEALAYED_REMOVE = int.MinValue; @@ -155,10 +156,7 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Contains(int entityID) { - //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; + return _sparse[entityID] > 0; } #endregion @@ -180,11 +178,11 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void AddInternal(int entityID) { - if (_lockCount > 0) - { - AddDelayedOp(entityID, DEALAYED_ADD); - return; - } + //if (_lockCount > 0) + //{ + // AddDelayedOp(entityID, DEALAYED_ADD); + // return; + //} AggressiveAdd(entityID); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -205,11 +203,11 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void RemoveInternal(int entityID) { - if (_lockCount > 0) - { - AddDelayedOp(entityID, DEALAYED_REMOVE); - return; - } + //if (_lockCount > 0) + //{ + // AddDelayedOp(entityID, DEALAYED_REMOVE); + // return; + //} AggressiveRemove(entityID); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -298,8 +296,8 @@ namespace DCFApixels.DragonECS #if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS if (_source != group.World) throw new ArgumentException("World != groupFilter.World"); #endif - foreach (var item in group) - if (Contains(item.id)) + foreach (var item in this) + if (group.Contains(item.id)) AggressiveRemove(item.id); } /// as Except sets @@ -358,6 +356,35 @@ namespace DCFApixels.DragonECS } #endregion + #region Static Set operations + /// as Except sets + public static EcsReadonlyGroup Remove(EcsGroup a, EcsGroup b) + { +#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS + if (a._source != b._source) throw new ArgumentException("a.World != b.World"); +#endif + EcsGroup result = a._source.GetGroupFromPool(); + foreach (var item in a) + if (!b.Contains(item.id)) + result.AggressiveAdd(item.id); + a._source.ReleaseGroup(a); + return result.Readonly; + } + /// as Intersect sets + public static EcsReadonlyGroup And(EcsGroup a, EcsGroup b) + { +#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS + if (a._source != b._source) throw new ArgumentException("a.World != b.World"); +#endif + EcsGroup result = a._source.GetGroupFromPool(); + foreach (var item in a) + if (b.Contains(item.id)) + result.AggressiveAdd(item.id); + a._source.ReleaseGroup(a); + return result.Readonly; + } + #endregion + #region GetEnumerator [MethodImpl(MethodImplOptions.AggressiveInlining)] private void Unlock() @@ -380,27 +407,28 @@ namespace DCFApixels.DragonECS } } } + private ProfilerMarker _getEnumeratorReturn = new ProfilerMarker("EcsGroup.GetEnumerator"); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] public Enumerator GetEnumerator() { - Sort(); - _lockCount++; + // _lockCount++; return new Enumerator(this); } #endregion #region Enumerator - public struct Enumerator : IDisposable + public ref struct Enumerator// : IDisposable { - private readonly EcsGroup _source; + // private readonly EcsGroup _source; private readonly int[] _dense; private readonly int _count; private int _index; - [MethodImpl(MethodImplOptions.AggressiveInlining)] public Enumerator(EcsGroup group) { - _source = group; + // _source = group; _dense = group._dense; _count = group.Count; _index = 0; @@ -408,12 +436,12 @@ namespace DCFApixels.DragonECS public ent Current { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => new ent(_dense[_index]); + get => (ent)_dense[_index]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool MoveNext() => ++_index <= _count && _count<_dense.Length; // <= потму что отсчет начинается с индекса 1 //_count < _dense.Length дает среде понять что проверки на выход за границы не нужны - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Dispose() => _source.Unlock(); + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + //public void Dispose() => _source.Unlock(); } #endregion diff --git a/src/EcsMask.cs b/src/EcsMask.cs index 3dd8bea..543821a 100644 --- a/src/EcsMask.cs +++ b/src/EcsMask.cs @@ -23,7 +23,7 @@ namespace DCFApixels.DragonECS { return new int[] { - EcsWorld.ComponentType.uniqueID, + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), }; } } @@ -33,8 +33,8 @@ namespace DCFApixels.DragonECS { return new int[] { - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), }; } } @@ -44,9 +44,9 @@ namespace DCFApixels.DragonECS { return new int[] { - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), }; } } @@ -56,10 +56,10 @@ namespace DCFApixels.DragonECS { return new int[] { - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), }; } } @@ -69,11 +69,11 @@ namespace DCFApixels.DragonECS { return new int[] { - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), }; } } @@ -83,12 +83,12 @@ namespace DCFApixels.DragonECS { return new int[] { - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), }; } } @@ -98,13 +98,13 @@ namespace DCFApixels.DragonECS { return new int[] { - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), }; } } @@ -114,14 +114,14 @@ namespace DCFApixels.DragonECS { return new int[] { - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), }; } } @@ -131,15 +131,15 @@ namespace DCFApixels.DragonECS { return new int[] { - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), }; } } @@ -149,16 +149,16 @@ namespace DCFApixels.DragonECS { return new int[] { - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), }; } } @@ -168,17 +168,17 @@ namespace DCFApixels.DragonECS { return new int[] { - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), }; } } @@ -188,18 +188,18 @@ namespace DCFApixels.DragonECS { return new int[] { - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), }; } } @@ -217,7 +217,7 @@ namespace DCFApixels.DragonECS { return new int[] { - EcsWorld.ComponentType.uniqueID, + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), }; } } @@ -227,8 +227,8 @@ namespace DCFApixels.DragonECS { return new int[] { - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), }; } } @@ -238,9 +238,9 @@ namespace DCFApixels.DragonECS { return new int[] { - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), }; } } @@ -250,10 +250,10 @@ namespace DCFApixels.DragonECS { return new int[] { - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), }; } } @@ -263,11 +263,11 @@ namespace DCFApixels.DragonECS { return new int[] { - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), }; } } @@ -277,12 +277,12 @@ namespace DCFApixels.DragonECS { return new int[] { - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, - EcsWorld.ComponentType.uniqueID, + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), + ComponentIndexer.GetComponentId(ComponentIndexer.GetWorldId()), }; } } @@ -357,43 +357,43 @@ namespace DCFApixels.DragonECS { static Activator() { - var inc = new TInc().GetComponentsIDs(); - var exc = new TExc().GetComponentsIDs(); - Array.Sort(inc); - Array.Sort(exc); - - Type thisType = typeof(Activator); - - Type sortedIncType = typeof(TInc); - if (sortedIncType.IsGenericType) - { - Type[] sortedInc = new Type[inc.Length]; - for (int i = 0; i < sortedInc.Length; i++) - sortedInc[i] = EcsWorld.ComponentType.types[inc[i]]; - sortedIncType = sortedIncType.GetGenericTypeDefinition().MakeGenericType(sortedInc); - } - Type sortedExcType = typeof(TExc); - if (sortedExcType.IsGenericType) - { - Type[] sortedExc = new Type[exc.Length]; - for (int i = 0; i < sortedExc.Length; i++) - sortedExc[i] = EcsWorld.ComponentType.types[exc[i]]; - sortedExcType = sortedExcType.GetGenericTypeDefinition().MakeGenericType(sortedExc); - } - - Type targetType = typeof(Activator<,>).MakeGenericType(typeof(TWorldArchetype), sortedIncType, sortedExcType); - - if (targetType != thisType) - { - instance = (EcsMask)targetType.GetField(nameof(instance), BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).GetValue(null); - return; - } - - var id = _count++; - if (_count >= _capacity) - _capacity <<= 1; - - instance = new EcsMask(typeof(TWorldArchetype), id, inc, exc); + // var inc = new TInc().GetComponentsIDs(); + // var exc = new TExc().GetComponentsIDs(); + // Array.Sort(inc); + // Array.Sort(exc); + // + // Type thisType = typeof(Activator); + // + // Type sortedIncType = typeof(TInc); + // if (sortedIncType.IsGenericType) + // { + // Type[] sortedInc = new Type[inc.Length]; + // for (int i = 0; i < sortedInc.Length; i++) + // sortedInc[i] = EcsWorld.ComponentType.types[inc[i]]; + // sortedIncType = sortedIncType.GetGenericTypeDefinition().MakeGenericType(sortedInc); + // } + // Type sortedExcType = typeof(TExc); + // if (sortedExcType.IsGenericType) + // { + // Type[] sortedExc = new Type[exc.Length]; + // for (int i = 0; i < sortedExc.Length; i++) + // sortedExc[i] = EcsWorld.ComponentType.types[exc[i]]; + // sortedExcType = sortedExcType.GetGenericTypeDefinition().MakeGenericType(sortedExc); + // } + // + // Type targetType = typeof(Activator<,>).MakeGenericType(typeof(TWorldArchetype), sortedIncType, sortedExcType); + // + // if (targetType != thisType) + // { + // instance = (EcsMask)targetType.GetField(nameof(instance), BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).GetValue(null); + // return; + // } + // + // var id = _count++; + // if (_count >= _capacity) + // _capacity <<= 1; + // + // instance = new EcsMask(typeof(TWorldArchetype), id, inc, exc); } public readonly static EcsMask instance; diff --git a/src/EcsPool.cs b/src/EcsPool.cs index b180f60..8d7674d 100644 --- a/src/EcsPool.cs +++ b/src/EcsPool.cs @@ -20,7 +20,7 @@ namespace DCFApixels.DragonECS } public interface IEcsPool : IEcsPool where T : struct { - public ref readonly T Read(int entity); + public ref T Read(int entity); public new ref T Write(int entity); } @@ -28,7 +28,7 @@ namespace DCFApixels.DragonECS public sealed class EcsNullPool : EcsPool, IEcsPool { public static EcsNullPool instance => new EcsNullPool(null); - private readonly IEcsWorld _source; + private IEcsWorld _source; private EcsNullPool(IEcsWorld source) => _source = source; private NullComponent fakeComponent; public Type ComponentType => typeof(NullComponent); @@ -40,7 +40,7 @@ namespace DCFApixels.DragonECS public void Del(int index) { } public override bool Has(int index) => false; void IEcsPool.Write(int entityID) { } - public ref readonly NullComponent Read(int entity) => ref fakeComponent; + public ref NullComponent Read(int entity) => ref fakeComponent; public ref NullComponent Write(int entity) => ref fakeComponent; void IEcsPool.OnWorldResize(int newSize) { } internal override void OnWorldResize(int newSize) { } @@ -100,8 +100,8 @@ namespace DCFApixels.DragonECS private ProfilerMarker _delMark = new ProfilerMarker("EcsPoo.Del"); public ref T Add(int entityID) { - using (_addMark.Auto()) - { + // using (_addMark.Auto()) + // { ref int itemIndex = ref _mapping[entityID]; if (itemIndex <= 0) { @@ -124,29 +124,29 @@ namespace DCFApixels.DragonECS } _poolRunnres.write.OnComponentWrite(entityID); return ref _items[itemIndex]; - } + // } } public ref T Write(int entityID) { - using (_writeMark.Auto()) + // using (_writeMark.Auto()) return ref _items[_mapping[entityID]]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ref readonly T Read(int entityID) + public ref T Read(int entityID) { - using (_readMark.Auto()) + // using (_readMark.Auto()) return ref _items[_mapping[entityID]]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public sealed override bool Has(int entityID) { - using (_hasMark.Auto()) + // using (_hasMark.Auto()) return _mapping[entityID] > 0; } public void Del(int entityID) { - using (_delMark.Auto()) - { + // using (_delMark.Auto()) + // { entities.Remove(entityID); if (_recycledItemsCount >= _recycledItems.Length) @@ -155,7 +155,7 @@ namespace DCFApixels.DragonECS _mapping[entityID] = 0; _itemsCount--; _poolRunnres.del.OnComponentDel(entityID); - } + // } } #endregion diff --git a/src/EcsQuery.cs b/src/EcsQuery.cs index d472d3b..565466d 100644 --- a/src/EcsQuery.cs +++ b/src/EcsQuery.cs @@ -18,35 +18,48 @@ namespace DCFApixels.DragonECS public abstract class EcsQuery : EcsQueryBase where TWorldArchetype : EcsWorld { - private int _id; - public int ID => _id; private ProfilerMarker _getEnumerator = new ProfilerMarker("EcsQuery.GetEnumerator"); public EcsGroup.Enumerator GetEnumerator() { using (_getEnumerator.Auto()) { - groupFilter.Clear(); - var pools = World.GetAllPools(); - - if (mask.Inc.Length > 0) + // groupFilter.Clear(); + var pools = World.GetAllPools(); + // + // if (mask.Inc.Length > 0) + // { + // groupFilter.CopyFrom(pools[mask.Inc[0]].entities); + // for (int i = 1; i < mask.Inc.Length; i++) + // { + // groupFilter.AndWith(pools[mask.Inc[i]].entities); + // } + // } + // else + // { + // groupFilter.CopyFrom(World.Entities); + // } + // for (int i = 0; i < mask.Exc.Length; i++) + // { + // groupFilter.RemoveGroup(pools[mask.Exc[i]].entities); + // } + // + // groupFilter.Sort(); + // return groupFilter.GetEnumerator(); + // + EcsReadonlyGroup sum = World.Entities; + for (int i = 0; i < mask.Inc.Length; i++) { - groupFilter.CopyFrom(pools[mask.Inc[0]].entities); - for (int i = 1; i < mask.Inc.Length; i++) - { - groupFilter.AndWith(pools[mask.Inc[i]].entities); - } - } - else - { - groupFilter.CopyFrom(World.Entities); + sum = EcsGroup.And(sum.GetGroupInternal(), pools[mask.Inc[i]].entities); + // Debug.Log("inc " + sum.ToString()); } for (int i = 0; i < mask.Exc.Length; i++) { - groupFilter.RemoveGroup(pools[mask.Exc[i]].entities); + sum = EcsGroup.Remove(sum.GetGroupInternal(), pools[mask.Exc[i]].entities); + // Debug.Log("exc " + sum.ToString()); } - groupFilter.Sort(); - return groupFilter.GetEnumerator(); + //sum.GetGroupInternal().Sort(); + return sum.GetEnumerator(); } } protected virtual void Init(Builder b) { } diff --git a/src/EcsQueryMember.cs b/src/EcsQueryMember.cs index 8bd488b..9128cd1 100644 --- a/src/EcsQueryMember.cs +++ b/src/EcsQueryMember.cs @@ -10,7 +10,7 @@ namespace DCFApixels.DragonECS { public ref TComponent Add(ent entityID); public ref TComponent Write(ent entityID); - public ref readonly TComponent Read(ent entityID); + public ref TComponent Read(ent entityID); public bool Has(ent entityID); public void Del(ent entityID); } @@ -27,7 +27,7 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] public ref TComponent Write(ent entityID) => ref _pool.Write(entityID.id); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ref readonly TComponent Read(ent entityID) => ref _pool.Read(entityID.id); + public ref TComponent Read(ent entityID) => ref _pool.Read(entityID.id); [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Has(ent entityID) => _pool.Has(entityID.id); [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -51,7 +51,7 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] public ref TComponent Write(ent entityID) => ref _pool.Write(entityID.id); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ref readonly TComponent Read(ent entityID) => ref _pool.Read(entityID.id); + public ref TComponent Read(ent entityID) => ref _pool.Read(entityID.id); [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Has(ent entityID) => _pool.Has(entityID.id); [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -75,7 +75,7 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] public ref TComponent Write(ent entityID) => ref _pool.Write(entityID.id); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ref readonly TComponent Read(ent entityID) => ref _pool.Read(entityID.id); + public ref TComponent Read(ent entityID) => ref _pool.Read(entityID.id); [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Has(ent entityID) => _pool.Has(entityID.id); [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index c30af78..3b44931 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -82,6 +82,8 @@ namespace DCFApixels.DragonECS public IEcsRealationTable[] _relationTables; + private readonly int _worldArchetypeID = ComponentIndexer.GetWorldId(); + #region RelationTables public IEcsRealationTable GetRelationTalbe(TWorldArhetype targetWorld) where TWorldArhetype : EcsWorld @@ -110,7 +112,7 @@ namespace DCFApixels.DragonECS #region GetterMethods public ReadOnlySpan GetAllPools() => new ReadOnlySpan(_pools); - public int GetComponentID() => ComponentType.uniqueID; + public int GetComponentID() => ComponentIndexer.GetComponentId(_worldArchetypeID);////ComponentType.uniqueID; #endregion @@ -159,18 +161,19 @@ namespace DCFApixels.DragonECS #region GetPool public EcsPool GetPool() where T : struct { - int uniqueID = ComponentType.uniqueID; + //int uniqueID = ComponentType.uniqueID; + int uniqueID = ComponentIndexer.GetComponentId(_worldArchetypeID); if (uniqueID >= _pools.Length) { int oldCapacity = _pools.Length; - Array.Resize(ref _pools, ComponentType.Capacity); + Array.Resize(ref _pools, _pools.Length << 1); ArrayUtility.Fill(_pools, _nullPool, oldCapacity, oldCapacity - _pools.Length); } if (_pools[uniqueID] == _nullPool) { - _pools[uniqueID] = new EcsPool(this, ComponentType.uniqueID, 512, _poolRunnres); + _pools[uniqueID] = new EcsPool(this, uniqueID, 512, _poolRunnres); } return (EcsPool)_pools[uniqueID]; } @@ -330,7 +333,7 @@ namespace DCFApixels.DragonECS QueryType.capacity <<= 1; } } - internal static class ComponentType + /* internal static class ComponentType { internal static int increment = 1; internal static int Capacity @@ -358,7 +361,7 @@ namespace DCFApixels.DragonECS } ComponentType.types[uniqueID] = typeof(T); } - } + }*/ #endregion #region GroupsPool @@ -397,4 +400,56 @@ namespace DCFApixels.DragonECS del = pipeline.GetRunner(); } } + + + + public static class ComponentIndexer + { + private static List resizer = new List(); + private static int tokenCount = 0; + private static int[] componentCounts = new int[0]; + private static class World + { + public static int id = GetToken(); + } + private static int GetToken() + { + tokenCount++; + Array.Resize(ref componentCounts, tokenCount); + foreach (var item in resizer) + item.Resize(tokenCount); + return tokenCount - 1; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int GetWorldId() => World.id; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int GetComponentId(int worldID) => Component.Get(worldID); + private abstract class Resizer + { + public abstract void Resize(int size); + } + private sealed class Resizer : Resizer + { + public override void Resize(int size) => Array.Resize(ref Component.ids, size); + } + private static class Component + { + public static int[] ids; + static Component() + { + ids = new int[tokenCount]; + for (int i = 0; i < ids.Length; i++) + ids[i] = -1; + resizer.Add(new Resizer()); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int Get(int token) + { + ref int id = ref ids[token]; + if (id < 0) + id = componentCounts[token]++; + return id; + } + } + } } diff --git a/src/Utils/ArrayUtility.cs b/src/Utils/ArrayUtility.cs index 8f2a70f..3b26372 100644 --- a/src/Utils/ArrayUtility.cs +++ b/src/Utils/ArrayUtility.cs @@ -1,4 +1,7 @@ -namespace DCFApixels.DragonECS +using System.Runtime.InteropServices; +using System; + +namespace DCFApixels.DragonECS { internal static class ArrayUtility { @@ -18,4 +21,37 @@ } } } + + internal static unsafe class UnmanagedArray + { + public static void* New(int elementCount) + where T : struct + { + return Marshal.AllocHGlobal(Marshal.SizeOf(typeof(T)) * elementCount).ToPointer(); + } + + public static void* NewAndInit(int elementCount) + where T : struct + { + int newSizeInBytes = Marshal.SizeOf(typeof(T)) * elementCount; + byte* newArrayPointer = (byte*)Marshal.AllocHGlobal(newSizeInBytes).ToPointer(); + + for (int i = 0; i < newSizeInBytes; i++) + *(newArrayPointer + i) = 0; + + return (void*)newArrayPointer; + } + + public static void Free(void* pointerToUnmanagedMemory) + { + Marshal.FreeHGlobal(new IntPtr(pointerToUnmanagedMemory)); + } + + public static void* Resize(void* oldPointer, int newElementCount) + where T : struct + { + return (Marshal.ReAllocHGlobal(new IntPtr(oldPointer), + new IntPtr(Marshal.SizeOf(typeof(T)) * newElementCount))).ToPointer(); + } + } }