diff --git a/src/EcsGroup.cs b/src/EcsGroup.cs index e509987..a4fa31f 100644 --- a/src/EcsGroup.cs +++ b/src/EcsGroup.cs @@ -102,7 +102,7 @@ namespace DCFApixels.DragonECS _source = source; source.RegisterGroup(this); _dense = new int[denseCapacity]; - _sparse = new int[source.Entities.CapacitySparce]; + _sparse = new int[source.EntitesCapacity]; _delayedOps = new delayedOp[delayedOpsCapacity]; @@ -137,9 +137,10 @@ namespace DCFApixels.DragonECS public void Add(int entityID) { if (Contains(entityID)) return; - Add(entityID); + AddInternal(entityID); } - private void AddInternal(int entityID) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal void AddInternal(int entityID) { if (_lockCount > 0) { @@ -161,7 +162,7 @@ namespace DCFApixels.DragonECS RemoveInternal(entityID); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private void RemoveInternal(int entityID) + internal void RemoveInternal(int entityID) { if (_lockCount > 0) { diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index 5989a0d..99594e1 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -4,6 +4,7 @@ using System.Collections.ObjectModel; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Xml; +using static UnityEditor.Progress; namespace DCFApixels.DragonECS { @@ -17,7 +18,6 @@ namespace DCFApixels.DragonECS public EcsPipeline Pipeline { get; } public int EntitesCount { get; } public int EntitesCapacity { get; } - public EcsReadonlyGroup Entities { get; } #endregion #region GetterMethods @@ -74,9 +74,10 @@ namespace DCFApixels.DragonECS where TArchetype : EcsWorld { private IntDispenser _entityDispenser; - private EcsGroup _entities; + private int[] _denseEntities; + private int _entitiesCount; + private short[] _gens; //старший бит указывает на то жива ли сущьность. - private short[] _gens; //private short[] _componentCounts; //TODO private IEcsPool[] _pools; @@ -104,14 +105,13 @@ namespace DCFApixels.DragonECS #endregion #region Properties - public bool IsEmpty => _entities.Count < 0; + public bool IsEmpty => _entitiesCount < 0; public Type ArchetypeType => typeof(TArchetype); public int ID => id; public EcsPipeline Pipeline => _pipeline; - public int EntitesCount => _entities.Count; - public int EntitesCapacity => _entities.CapacityDense; - public EcsReadonlyGroup Entities => _entities.Readonly; + public int EntitesCount => _entitiesCount; + public int EntitesCapacity => _denseEntities.Length; #endregion #region Constructors @@ -128,7 +128,7 @@ namespace DCFApixels.DragonECS _filters = new EcsFilter[64]; _groups = new List(128); - _entities = new EcsGroup(this, 512, 512, 0); + _denseEntities = new int[512]; _filtersByIncludedComponents = new List[16]; _filtersByExcludedComponents = new List[16]; @@ -170,7 +170,7 @@ namespace DCFApixels.DragonECS } #endregion - #region GetFilter + #region GetFilter public EcsFilter Filter() where TInc : struct, IInc => Filter(); public EcsFilter Filter() where TInc : struct, IInc where TExc : struct, IExc { @@ -216,12 +216,11 @@ namespace DCFApixels.DragonECS list.Add(filter); } // scan exist entities for compatibility with new filter. - foreach (var item in _entities) + for (int i = 0; i < _entitiesCount && _entitiesCount <= _denseEntities.Length; i++) { - if (IsMaskCompatible(mask, item.id)) - { - filter.Add(item.id); - } + int entity = _denseEntities[i]; + if (IsMaskCompatible(mask, entity)) + filter.Add(entity); } return filter; @@ -271,34 +270,36 @@ namespace DCFApixels.DragonECS #endregion #region EntityChangedReact + void IEcsWorld.OnEntityComponentAdded(int entityID, int componentID) { var includeList = _filtersByIncludedComponents[componentID]; var excludeList = _filtersByExcludedComponents[componentID]; - //if (includeList != null) - //{ - // foreach (var filter in includeList) - // { - // if (IsMaskCompatible(filter.Mask, entityID)) - // { - // filter.Add(entityID); - // } - // } - //} - //if (excludeList != null) - //{ - // foreach (var filter in excludeList) - // { - // if (IsMaskCompatibleWithout(filter.Mask, entityID, componentID)) - // { - // filter.Remove(entityID); - // } - // } - //} + if (includeList != null) + { + foreach (var filter in includeList) + { + if (IsMaskCompatible(filter.Mask, entityID)) + { + filter.entities.UncheckedAdd(entityID); + } + } + } + if (excludeList != null) + { + foreach (var filter in excludeList) + { + if (IsMaskCompatibleWithout(filter.Mask, entityID, componentID)) + { + filter.entities.UncheckedRemove(entityID); + } + } + } + //TODO провести стресс тест для варианта выши и закоментированного ниже - if (includeList != null) foreach (var filter in includeList) filter.entities.Add(entityID); - if (excludeList != null) foreach (var filter in excludeList) filter.entities.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 componentID) @@ -306,29 +307,30 @@ namespace DCFApixels.DragonECS var includeList = _filtersByIncludedComponents[componentID]; var excludeList = _filtersByExcludedComponents[componentID]; - //if (includeList != null) - //{ - // foreach (var filter in includeList) - // { - // if (IsMaskCompatible(filter.Mask, entityID)) - // { - // filter.Remove(entityID); - // } - // } - //} - //if (excludeList != null) - //{ - // foreach (var filter in excludeList) - // { - // if (IsMaskCompatibleWithout(filter.Mask, entityID, componentID)) - // { - // filter.Add(entityID); - // } - // } - //} + if (includeList != null) + { + foreach (var filter in includeList) + { + if (IsMaskCompatible(filter.Mask, entityID)) + { + filter.entities.UncheckedRemove(entityID); + } + } + } + if (excludeList != null) + { + foreach (var filter in excludeList) + { + if (IsMaskCompatibleWithout(filter.Mask, entityID, componentID)) + { + filter.entities.UncheckedAdd(entityID); + } + } + } + //TODO провести стресс тест для варианта выши и закоментированного ниже - if (includeList != null) foreach (var filter in includeList) filter.entities.Remove(entityID); - if (excludeList != null) foreach (var filter in excludeList) filter.entities.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 @@ -336,21 +338,19 @@ namespace DCFApixels.DragonECS public ent NewEntity() { int entityID = _entityDispenser.GetFree(); - _entities.UncheckedAdd(entityID); + if (_entityDispenser.LastInt >= _denseEntities.Length) + Array.Resize(ref _denseEntities, _denseEntities.Length << 1); + _denseEntities[_entitiesCount++] = entityID; + if (_gens.Length <= entityID) { Array.Resize(ref _gens, _gens.Length << 1); - _entities.OnWorldResize(_gens.Length); foreach (var item in _groups) - { item.OnWorldResize(_gens.Length); - } foreach (var item in _pools) - { item.OnWorldResize(_gens.Length); - } } - + _gens[entityID] |= short.MinValue; ent entity = new ent(entityID, _gens[entityID]++, id); _entityCreate.OnEntityCreate(entity); return entity; @@ -358,7 +358,8 @@ namespace DCFApixels.DragonECS public void DelEntity(ent entity) { _entityDispenser.Release(entity.id); - _entities.UncheckedRemove(entity.id); + _gens[entity.id] |= short.MinValue; + _entitiesCount--; _entityDestry.OnEntityDestroy(entity); } @@ -370,7 +371,7 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool EntityIsAlive(int entityID, short gen) { - return _entities.Contains(entityID) && _gens[entityID] == gen; + return _gens[entityID] == gen; } #endregion @@ -378,7 +379,7 @@ namespace DCFApixels.DragonECS public void Destroy() { _entityDispenser = null; - _entities = null; + _denseEntities = null; _gens = null; _pools = null; _nullPool = null; diff --git a/src/Utils/IntDispenser.cs b/src/Utils/IntDispenser.cs index 4718ec3..113109f 100644 --- a/src/Utils/IntDispenser.cs +++ b/src/Utils/IntDispenser.cs @@ -10,6 +10,7 @@ namespace DCFApixels.DragonECS #region Properties public int LastInt => _increment; + public int FreeConut => _freeInts.Count; #endregion #region Constructor