diff --git a/src/Debug/EcsDebug.cs b/src/Debug/EcsDebug.cs index 798f56f..1e29074 100644 --- a/src/Debug/EcsDebug.cs +++ b/src/Debug/EcsDebug.cs @@ -1,4 +1,5 @@ -using System; +using DCFApixels.DragonECS.Utils; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.CompilerServices; diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index 7c88a0a..690a5d9 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -1,7 +1,8 @@ -using System; +using DCFApixels.DragonECS.Internal; +using DCFApixels.DragonECS.Utils; +using System; using System.Collections.Generic; using System.Runtime.CompilerServices; -using DCFApixels.DragonECS.Internal; namespace DCFApixels.DragonECS { @@ -144,7 +145,7 @@ namespace DCFApixels.DragonECS } #endregion - #region Queries + #region Subjects public TSubject GetSubject() where TSubject : EcsSubject { int uniqueID = WorldMetaStorage.GetSubjectId(_worldTypeID); @@ -154,104 +155,45 @@ namespace DCFApixels.DragonECS _subjects[uniqueID] = EcsSubject.Builder.Build(this); return (TSubject)_subjects[uniqueID]; } - #region Iterate - public EcsSubjectIterator IterateFor(EcsReadonlyGroup sourceGroup, out TSubject subject) where TSubject : EcsSubject - { - - subject = GetSubject(); - return subject.GetIteratorFor(sourceGroup); - } - public EcsSubjectIterator IterateFor(EcsReadonlyGroup sourceGroup) where TSubject : EcsSubject - { - return GetSubject().GetIteratorFor(sourceGroup); - } - public EcsSubjectIterator Iterate(out TSubject subject) where TSubject : EcsSubject - { - subject = GetSubject(); - return subject.GetIterator(); - } - public EcsSubjectIterator Iterate() where TSubject : EcsSubject - { - return GetSubject().GetIterator(); - } #endregion - #region Where - private EcsWhereExecutor GetWhereExecutor() where TSubject : EcsSubject + #region Queries + public TExecutor GetExecutor(Func builder) where TExecutor: EcsQueryExecutor { - int id = WorldMetaStorage.GetExecutorId>(_worldTypeID); + int id = WorldMetaStorage.GetExecutorId(_worldTypeID); if (id >= _executors.Length) Array.Resize(ref _executors, _executors.Length << 1); if (_executors[id] == null) - _executors[id] = new EcsWhereExecutor(GetSubject()); - return (EcsWhereExecutor)_executors[id]; + _executors[id] = builder(this); + return (TExecutor)_executors[id]; + } + + private EcsWhereExecutor EcsWhereExecutorBuilder(EcsWorld world) where TSubject : EcsSubject + { + return new EcsWhereExecutor(world.GetSubject()); } public EcsWhereResult WhereFor(EcsReadonlyGroup sourceGroup, out TSubject subject) where TSubject : EcsSubject { - var executor = GetWhereExecutor(); + var executor = GetExecutor(EcsWhereExecutorBuilder); subject = executor.Subject; return executor.ExecuteFor(sourceGroup); } public EcsWhereResult WhereFor(EcsReadonlyGroup sourceGroup) where TSubject : EcsSubject { - return GetWhereExecutor().ExecuteFor(sourceGroup); + return GetExecutor(EcsWhereExecutorBuilder).ExecuteFor(sourceGroup); } public EcsWhereResult Where(out TSubject subject) where TSubject : EcsSubject { - var executor = GetWhereExecutor(); + var executor = GetExecutor(EcsWhereExecutorBuilder); subject = executor.Subject; return executor.Execute(); } public EcsWhereResult Where() where TSubject : EcsSubject { - return GetWhereExecutor().Execute(); + return GetExecutor(EcsWhereExecutorBuilder).Execute(); } #endregion - #region Join - private EcsJoinAttachExecutor GetJoinAttachExecutor() - where TSubject : EcsSubject - where TAttachComponent : struct, IEcsAttachComponent - { - int id = WorldMetaStorage.GetExecutorId>(_worldTypeID); - if (id >= _executors.Length) - Array.Resize(ref _executors, _executors.Length << 1); - if (_executors[id] == null) - _executors[id] = new EcsJoinAttachExecutor(GetSubject()); - return (EcsJoinAttachExecutor)_executors[id]; - } - public EcsJoinAttachResult JoinFor(EcsReadonlyGroup sourceGroup, out TSubject subject) - where TSubject : EcsSubject - where TAttachComponent : struct, IEcsAttachComponent - { - var executor = GetJoinAttachExecutor(); - subject = executor.Subject; - return executor.ExecuteFor(sourceGroup); - } - public EcsJoinAttachResult JoinFor(EcsReadonlyGroup sourceGroup) - where TSubject : EcsSubject - where TAttachComponent : struct, IEcsAttachComponent - { - return GetJoinAttachExecutor().ExecuteFor(sourceGroup); - } - public EcsJoinAttachResult Join(out TSubject subject) - where TSubject : EcsSubject - where TAttachComponent : struct, IEcsAttachComponent - { - var executor = GetJoinAttachExecutor(); - subject = executor.Subject; - return executor.Execute(); - } - public EcsJoinAttachResult Join() - where TSubject : EcsSubject - where TAttachComponent : struct, IEcsAttachComponent - { - return GetJoinAttachExecutor().Execute(); - } - #endregion - - #endregion - #region IsMatchesMask public bool IsMatchesMask(EcsMask mask, int entityID) { diff --git a/src/Executors/EcsJoinAttachExecutor.cs b/src/Executors/EcsJoinAttachExecutor.cs deleted file mode 100644 index a307e1f..0000000 --- a/src/Executors/EcsJoinAttachExecutor.cs +++ /dev/null @@ -1,189 +0,0 @@ -using Unity.Profiling; - -namespace DCFApixels.DragonECS -{ - public sealed class EcsJoinAttachExecutor : EcsQueryExecutor - where TSubject : EcsSubject - where TAttachComponent : struct, IEcsAttachComponent - { - private readonly TSubject _subject; - internal readonly EcsGroup _filteredGroup; - private EcsWorld _targetWorld; - - private EcsAttachPool _targetPool; - - private int _targetWorldCapacity = -1; - private int _targetPoolCapacity = -1; - - private int[] _mapping; - private int[] _counts; - private EntityLinkedList _linkedBasket; - - private bool _isInitTargetWorld = false; - - private ProfilerMarker _executeJoin = new ProfilerMarker("JoinAttachQuery.Join"); - - private long _executeVersion; - - #region Properties - public TSubject Subject => _subject; - internal long ExecuteVersion => _executeVersion; - #endregion - - #region Constructors - public EcsJoinAttachExecutor(TSubject subject) - { - _subject = subject; - _filteredGroup = EcsGroup.New(subject.World); - _targetPool = subject.World.GetPool(); - } - #endregion - - #region Methods - public EcsJoinAttachResult Execute() => ExecuteFor(_targetPool.Entities); - public EcsJoinAttachResult ExecuteFor(EcsReadonlyGroup sourceGroup) - { - _executeJoin.Begin(); - var world = _subject.World; -#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS - if (sourceGroup.IsNull) throw new System.ArgumentNullException();//TODO составить текст исключения. -#endif - if (!_isInitTargetWorld) - InitTargetWorlds(sourceGroup.World); -#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS - else - if (_targetWorld != sourceGroup.World) throw new System.ArgumentException();//TODO составить текст исключения. это проверка на то что пользователь использует правильный мир -#endif - - //Подготовка массивов - if (_targetWorldCapacity < _targetWorld.Capacity) - { - _targetWorldCapacity = _targetWorld.Capacity; - _mapping = new int[_targetWorldCapacity]; - _counts = new int[_targetWorldCapacity]; - } - else - { - ArrayUtility.Fill(_counts, 0); - ArrayUtility.Fill(_mapping, 0); - } - if (_targetPoolCapacity < _targetPool.Capacity) - { - _targetPoolCapacity = _targetPool.Capacity; - _linkedBasket.Resize(_targetPoolCapacity); - } - _linkedBasket.Clear(); - //Конец подготовки массивов - - var iterator = new EcsSubjectIterator(_subject, sourceGroup); - foreach (var attachID in iterator) - { - entlong attachTarget = _targetPool.Read(attachID).Target; - if (!attachTarget.IsAlive) - { - //_targetPool.Del(attachID); - continue; - } - int attachTargetID = attachTarget.id; - //if (!CheckMaskInternal(targetWorldWhereQuery.query.mask, attachTargetID)) continue; //TODO проверить что все работает //исчключить все аттачи, цели которых не входят в targetWorldWhereQuery - - ref int nodeIndex = ref _mapping[attachTargetID]; - if (nodeIndex <= 0) - nodeIndex = _linkedBasket.Add(attachID); - else - _linkedBasket.Insert(nodeIndex, attachID); - _counts[attachTargetID]++; - } - - _executeVersion++; - _executeJoin.End(); - - return new EcsJoinAttachResult(_subject, this , _executeVersion); - } - private void InitTargetWorlds(EcsWorld targetWorld) - { - _targetWorld = targetWorld; - - _targetWorldCapacity = _targetWorld.Capacity; - _mapping = new int[_targetWorldCapacity]; - _counts = new int[_targetWorldCapacity]; - - _targetPoolCapacity = _targetPool.Capacity; - _linkedBasket = new EntityLinkedList(_targetPoolCapacity); - _isInitTargetWorld = true; - } - internal sealed override void Destroy() - { - _filteredGroup.Release(); - _targetWorld = null; - _mapping = null; - _counts = null; - _linkedBasket = null; - } - #endregion - - #region Internal result methods - internal bool Has(int attachedEnttiyID) => _filteredGroup.Has(attachedEnttiyID); - internal EntityLinkedList.EnumerableSpan GetNodes(int entityID) => _linkedBasket.Span(_mapping[entityID], _counts[entityID]); - internal int GetNode(int entityID) => _counts[entityID] > 0 ? _linkedBasket.Get(_mapping[entityID]) : 0; - internal int GetNodesCount(int entityID) => _counts[entityID]; - internal bool HasNode(int entityID, int attachedEntityID) => _filteredGroup.Has(attachedEntityID) && _targetPool.Read(attachedEntityID).Target.id == entityID; - #endregion - } - - #region JoinAttachExecuter Results - public readonly ref struct EcsJoinAttachResult - where TSubject : EcsSubject - where TAttachComponent : struct, IEcsAttachComponent - { - public readonly TSubject s; - private readonly EcsJoinAttachExecutor _executer; - private readonly long _verison; - - public bool IsRelevant => _verison == _executer.ExecuteVersion; - - public EcsJoinAttachResult(TSubject s, EcsJoinAttachExecutor executer, long version) - { - this.s = s; - _executer = executer; - _verison = version; - } - - public bool Has(int attachedEnttiyID) - { -#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS - if (!IsRelevant) throw new System.InvalidOperationException();//TODO составить текст исключения. -#endif - return _executer.Has(attachedEnttiyID); - } - public EntityLinkedList.EnumerableSpan GetNodes(int entityID) - { -#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS - if (!IsRelevant) throw new System.InvalidOperationException();//TODO составить текст исключения. -#endif - return _executer.GetNodes(entityID); - } - public int GetNode(int entityID) - { -#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS - if (!IsRelevant) throw new System.InvalidOperationException();//TODO составить текст исключения. -#endif - return _executer.GetNode(entityID); - } - public int GetNodesCount(int entityID) - { -#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS - if (!IsRelevant) throw new System.InvalidOperationException();//TODO составить текст исключения. -#endif - return _executer.GetNodesCount(entityID); - } - public bool HasNode(int entityID, int attachedEntityID) - { -#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS - if (!IsRelevant) throw new System.InvalidOperationException();//TODO составить текст исключения. -#endif - return _executer.HasNode(entityID, attachedEntityID); - } - } - #endregion -} diff --git a/src/Executors/EcsJoinHierarchyExecutor.cs b/src/Executors/EcsJoinHierarchyExecutor.cs deleted file mode 100644 index 9e989b6..0000000 --- a/src/Executors/EcsJoinHierarchyExecutor.cs +++ /dev/null @@ -1,198 +0,0 @@ -using System; -using Unity.Profiling; - -namespace DCFApixels.DragonECS -{ - public sealed class EcsJoinHierarchyExecutor : EcsQueryExecutor - where TSubject : EcsSubject - where TAttachComponent : struct, IEcsAttachComponent - { - private readonly TSubject _subject; - internal readonly EcsGroup _filteredGroup; - private EcsWorld _targetWorld; - - private EcsAttachPool _targetPool; - - private int _targetWorldCapacity = -1; - private int _targetPoolCapacity = -1; - - private int[] _mapping; - private int[] _counts; - private EntityLinkedList _linkedBasket; - - private bool _isInitTargetWorld = false; - - private ProfilerMarker _executeWhere = new ProfilerMarker("JoinAttachQuery.Where"); - private ProfilerMarker _executeJoin = new ProfilerMarker("JoinAttachQuery.Join"); - - private long _executeVersion; - - #region Properties - public TSubject Subject => _subject; - internal long ExecuteVersion => _executeVersion; - #endregion - - #region Constructors - public EcsJoinHierarchyExecutor(TSubject subject) - { - _subject = subject; - _filteredGroup = EcsGroup.New(subject.World); - _targetPool = subject.World.GetPool(); - } - #endregion - - #region Methods - public EcsJoinHierarchyResult Execute() => ExecuteFor(_targetPool.Entities); - public EcsJoinHierarchyResult ExecuteFor(EcsReadonlyGroup sourceGroup) - { - var world = _subject.World; - _executeJoin.Begin(); -#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS - if (sourceGroup.IsNull) throw new ArgumentNullException();//TODO составить текст исключения. -#endif - if (!_isInitTargetWorld) - InitTargetWorlds(sourceGroup.World); -#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS - else - if (_targetWorld != sourceGroup.World) throw new ArgumentException();//TODO составить текст исключения. это проверка на то что пользователь использует правильный мир -#endif - - //Подготовка массивов - if (_targetWorldCapacity < _targetWorld.Capacity) - { - _targetWorldCapacity = _targetWorld.Capacity; - _mapping = new int[_targetWorldCapacity]; - _counts = new int[_targetWorldCapacity]; - } - else - { - ArrayUtility.Fill(_counts, 0); - ArrayUtility.Fill(_mapping, 0); - } - if (_targetPoolCapacity < _targetPool.Capacity) - { - _targetPoolCapacity = _targetPool.Capacity; - _linkedBasket.Resize(_targetPoolCapacity); - } - _linkedBasket.Clear(); - //Конец подготовки массивов - - var iterator = new EcsSubjectIterator(_subject, sourceGroup); - foreach (var attachID in iterator) - { - entlong attachTarget = _targetPool.Read(attachID).Target; - if (!attachTarget.IsAlive) - { - //_targetPool.Del(attachID); - continue; - } - int attachTargetID = attachTarget.id; - //if (!CheckMaskInternal(targetWorldWhereQuery.query.mask, attachTargetID)) continue; //TODO проверить что все работает //исчключить все аттачи, цели которых не входят в targetWorldWhereQuery - - ref int nodeIndex = ref _mapping[attachTargetID]; - if (nodeIndex <= 0) - nodeIndex = _linkedBasket.Add(attachID); - else - _linkedBasket.Insert(nodeIndex, attachID); - _counts[attachTargetID]++; - } - - _executeVersion++; - _executeJoin.End(); - - return new EcsJoinHierarchyResult(_subject, this , _executeVersion); - } - private void InitTargetWorlds(EcsWorld targetWorld) - { - _targetWorld = targetWorld; - - _targetWorldCapacity = _targetWorld.Capacity; - _mapping = new int[_targetWorldCapacity]; - _counts = new int[_targetWorldCapacity]; - - _targetPoolCapacity = _targetPool.Capacity; - _linkedBasket = new EntityLinkedList(_targetPoolCapacity); - _isInitTargetWorld = true; - } - internal sealed override void Destroy() - { - _filteredGroup.Release(); - _targetWorld = null; - _mapping = null; - _counts = null; - _linkedBasket = null; - } - #endregion - - #region Internal result methods - internal bool Has(int attachedEnttiyID) => _filteredGroup.Has(attachedEnttiyID); - - internal EntityLinkedList.EnumerableSpan GetNodes(int entityID) => _linkedBasket.Span(_mapping[entityID], _counts[entityID]); - internal int GetNode(int entityID) => _counts[entityID] > 0 ? _linkedBasket.Get(_mapping[entityID]) : 0; - internal int GetNodesCount(int entityID) => _counts[entityID]; - internal bool HasNode(int entityID, int attachedEntityID) => _filteredGroup.Has(attachedEntityID) && _targetPool.Read(attachedEntityID).Target.id == entityID; - - - internal EntityLinkedList.EnumerableSpan GetSubNodes(int entityID) => throw new NotImplementedException(); - internal int GetSubNode(int entityID) => throw new NotImplementedException(); - internal bool GetSubNodesCount(int entityID, int attachedEntityID) => throw new NotImplementedException(); - internal bool HasSubNode(int entityID, int attachedEntityID) => throw new NotImplementedException(); - #endregion - } - - #region JoinAttachExecuter Results - public readonly ref struct EcsJoinHierarchyResult - where TSubject : EcsSubject - where TAttachComponent : struct, IEcsAttachComponent - { - public readonly TSubject s; - private readonly EcsJoinHierarchyExecutor _executer; - private readonly long _verison; - - public bool IsRelevant => _verison == _executer.ExecuteVersion; - - public EcsJoinHierarchyResult(TSubject s, EcsJoinHierarchyExecutor executer, long version) - { - this.s = s; - _executer = executer; - _verison = version; - } - - public bool Has(int attachedEnttiyID) - { -#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS - if (!IsRelevant) throw new InvalidOperationException();//TODO составить текст исключения. -#endif - return _executer.Has(attachedEnttiyID); - } - public EntityLinkedList.EnumerableSpan GetNodes(int entityID) - { -#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS - if (!IsRelevant) throw new InvalidOperationException();//TODO составить текст исключения. -#endif - return _executer.GetNodes(entityID); - } - public int GetNode(int entityID) - { -#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS - if (!IsRelevant) throw new InvalidOperationException();//TODO составить текст исключения. -#endif - return _executer.GetNode(entityID); - } - public int GetNodesCount(int entityID) - { -#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS - if (!IsRelevant) throw new InvalidOperationException();//TODO составить текст исключения. -#endif - return _executer.GetNodesCount(entityID); - } - public bool HasNode(int entityID, int attachedEntityID) - { -#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS - if (!IsRelevant) throw new InvalidOperationException();//TODO составить текст исключения. -#endif - return _executer.HasNode(entityID, attachedEntityID); - } - } - #endregion -} diff --git a/src/Executors/EcsQueryExecutor.cs b/src/Executors/EcsQueryExecutor.cs index 1a15dc1..8b8534e 100644 --- a/src/Executors/EcsQueryExecutor.cs +++ b/src/Executors/EcsQueryExecutor.cs @@ -2,6 +2,7 @@ { public abstract class EcsQueryExecutor { - internal abstract void Destroy(); + internal void Destroy() => OnDestroy(); + protected abstract void OnDestroy(); } } diff --git a/src/Executors/EcsWhereExecutor.cs b/src/Executors/EcsWhereExecutor.cs index b15bfff..c7ccc97 100644 --- a/src/Executors/EcsWhereExecutor.cs +++ b/src/Executors/EcsWhereExecutor.cs @@ -37,7 +37,7 @@ namespace DCFApixels.DragonECS return new EcsWhereResult(this, _filteredGroup.Readonly); } } - internal sealed override void Destroy() + protected sealed override void OnDestroy() { _filteredGroup.Release(); } diff --git a/src/Pools/EcsNotNullPool.cs b/src/Pools/EcsNotNullPool.cs deleted file mode 100644 index 7e482d9..0000000 --- a/src/Pools/EcsNotNullPool.cs +++ /dev/null @@ -1,140 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Runtime.CompilerServices; - -namespace DCFApixels.DragonECS -{ - // - /// Pool for IEcsNotNullComponent components - public sealed class EcsNotNullPool : IEcsPoolImplementation, IEnumerable //IntelliSense hack - where T : struct, IEcsNotNullComponent - { - private EcsWorld _source; - private int _id; - - private T[] _items; //sparse - private int _count; - - private IEcsComponentReset _componentResetHandler; - private IEcsComponentCopy _componentCopyHandler; - - private List _listeners; - - #region Properites - public int Count => _count; - public int Capacity => _items.Length; - public int ComponentID => _id; - public Type ComponentType => typeof(T); - public EcsWorld World => _source; - #endregion - - #region Init - void IEcsPoolImplementation.OnInit(EcsWorld world, int componentID) - { - _source = world; - _id = componentID; - - _items = new T[world.Capacity]; - _count = 0; - - _listeners = new List(); - - _componentResetHandler = EcsComponentResetHandler.instance; - _componentCopyHandler = EcsComponentCopyHandler.instance; - } - #endregion - - #region Methods - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ref T Write(int entityID) - { - _listeners.InvokeOnWrite(entityID); - return ref _items[entityID]; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ref readonly T Read(int entityID) - { - return ref _items[entityID]; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Has(int entityID) - { - return true; - } - public void Copy(int fromEntityID, int toEntityID) - { - _componentCopyHandler.Copy(ref Write(fromEntityID), ref Write(toEntityID)); - } - public void Copy(int fromEntityID, EcsWorld toWorld, int toEntityID) - { - _componentCopyHandler.Copy(ref Write(fromEntityID), ref toWorld.GetPool().Write(toEntityID)); - } - #endregion - - #region Callbacks - void IEcsPoolImplementation.OnWorldResize(int newSize) - { - Array.Resize(ref _items, newSize); - } - void IEcsPoolImplementation.OnWorldDestroy() { } - void IEcsPoolImplementation.OnReleaseDelEntityBuffer(ReadOnlySpan buffer) - { - foreach (var entityID in buffer) - _componentResetHandler.Reset(ref _items[entityID]); - } - #endregion - - #region Other - ref T IEcsPool.Add(int entityID) => ref Write(entityID); - ref readonly T IEcsPool.Read(int entityID) => ref Read(entityID); - ref T IEcsPool.Write(int entityID) => ref Write(entityID); - void IEcsPool.Del(int entityID) { } - void IEcsPool.AddRaw(int entityID, object dataRaw) => Write(entityID) = (T)dataRaw; - object IEcsPool.GetRaw(int entityID) => Write(entityID); - void IEcsPool.SetRaw(int entityID, object dataRaw) => Write(entityID) = (T)dataRaw; - #endregion - - #region Listeners - public void AddListener(IEcsPoolEventListener listener) - { - if (listener == null) { throw new ArgumentNullException("listener is null"); } - _listeners.Add(listener); - } - public void RemoveListener(IEcsPoolEventListener listener) - { - if (listener == null) { throw new ArgumentNullException("listener is null"); } - _listeners.Remove(listener); - } - #endregion - - #region IEnumerator - IntelliSense hack - IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); - IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); - #endregion - } - /// - /// Not null component. Is present on all entities, without explicit addition and cannot be deleted - /// - public interface IEcsNotNullComponent { } - public static class EcsNotNullPoolExt - { - public static EcsNotNullPool GetPool(this EcsWorld self) where TNotNullComponent : struct, IEcsNotNullComponent - { - return self.GetPool>(); - } - - public static EcsNotNullPool Include(this EcsSubjectBuilderBase self) where TNotNullComponent : struct, IEcsNotNullComponent - { - return self.Include>(); - } - public static EcsNotNullPool Exclude(this EcsSubjectBuilderBase self) where TNotNullComponent : struct, IEcsNotNullComponent - { - return self.Exclude>(); - } - public static EcsNotNullPool Optional(this EcsSubjectBuilderBase self) where TNotNullComponent : struct, IEcsNotNullComponent - { - return self.Optional>(); - } - } -} diff --git a/src/Pools/EcsSinglePool.cs b/src/Pools/EcsSinglePool.cs deleted file mode 100644 index 8359d66..0000000 --- a/src/Pools/EcsSinglePool.cs +++ /dev/null @@ -1,177 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Runtime.CompilerServices; - -namespace DCFApixels.DragonECS -{ - using static EcsPoolThrowHalper; - public sealed class EcsSinglePool : IEcsPoolImplementation, IEnumerable //IntelliSense hack - where T : struct, IEcsSingleComponent - { - private EcsWorld _source; - private int _id; - - private int[] _mapping; - - private int _count; - private T _component; - - private List _listeners; - - #region Properites - public ref T Instance - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => ref _component; - } - public int Count => _count; - int IEcsPool.Capacity => -1; - public int ComponentID => _id; - public Type ComponentType => typeof(T); - public EcsWorld World => _source; - #endregion - - #region Init - void IEcsPoolImplementation.OnInit(EcsWorld world, int componentID) - { - _source = world; - _id = componentID; - - _mapping = new int[world.Capacity]; - _count = 0; - _listeners = new List(); - } - #endregion - - #region Methods - public ref T Add(int entityID) - { -#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS - if (Has(entityID)) ThrowAlreadyHasComponent(entityID); -#endif - _mapping[entityID] = ++_count; - this.IncrementEntityComponentCount(entityID); - _listeners.InvokeOnAddAndWrite(entityID); - return ref _component; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ref T Write(int entityID) - { -#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS - if (!Has(entityID)) ThrowNotHaveComponent(entityID); -#endif - _listeners.InvokeOnWrite(entityID); - return ref _component; - } - public ref T TryAddOrWrite(int entityID) - { - if (!Has(entityID)) - return ref Add(entityID); - return ref Write(entityID); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public ref readonly T Read(int entityID) - { -#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS - if (!Has(entityID)) ThrowNotHaveComponent(entityID); -#endif - return ref _component; - } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public bool Has(int entityID) - { - return _mapping[entityID] > 0; - } - public void Del(int entityID) - { -#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS - if (!Has(entityID)) ThrowNotHaveComponent(entityID); -#endif - _mapping[entityID] = 0; - _count--; - this.DecrementEntityComponentCount(entityID); - _listeners.InvokeOnDel(entityID); - } - public void TryDel(int entityID) - { - if (Has(entityID)) Del(entityID); - } - public void Copy(int fromEntityID, int toEntityID) - { -#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS - if (!Has(fromEntityID)) ThrowNotHaveComponent(fromEntityID); -#endif - TryAddOrWrite(toEntityID); - } - public void Copy(int fromEntityID, EcsWorld toWorld, int toEntityID) - { -#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS - if (!Has(fromEntityID)) ThrowNotHaveComponent(fromEntityID); -#endif - toWorld.GetPool().TryAddOrWrite(toEntityID); - } - #endregion - - #region Callbacks - void IEcsPoolImplementation.OnWorldResize(int newSize) - { - Array.Resize(ref _mapping, newSize); - } - void IEcsPoolImplementation.OnWorldDestroy() { } - void IEcsPoolImplementation.OnReleaseDelEntityBuffer(ReadOnlySpan buffer) - { - foreach (var entityID in buffer) - TryDel(entityID); - } - #endregion - - #region Other - void IEcsPool.AddRaw(int entityID, object dataRaw) => Instance = (T)dataRaw; - object IEcsPool.GetRaw(int entityID) => Instance; - void IEcsPool.SetRaw(int entityID, object dataRaw) => Instance = (T)dataRaw; - #endregion - - #region Listeners - public void AddListener(IEcsPoolEventListener listener) - { - if (listener == null) { throw new ArgumentNullException("listener is null"); } - _listeners.Add(listener); - } - public void RemoveListener(IEcsPoolEventListener listener) - { - if (listener == null) { throw new ArgumentNullException("listener is null"); } - _listeners.Remove(listener); - } - #endregion - - #region IEnumerator - IntelliSense hack - IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); - IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException(); - #endregion - } - /// Singleton component - public interface IEcsSingleComponent { } - public static class EcsSinglePoolExt - { - public static EcsSinglePool GetPool(this EcsWorld self) - where TSingleComponent : struct, IEcsSingleComponent - { - return self.GetPool>(); - } - - public static EcsSinglePool Include(this EcsSubjectBuilderBase self) where TSingleComponent : struct, IEcsSingleComponent - { - return self.Include>(); - } - public static EcsSinglePool Exclude(this EcsSubjectBuilderBase self) where TSingleComponent : struct, IEcsSingleComponent - { - return self.Exclude>(); - } - public static EcsSinglePool Optional(this EcsSubjectBuilderBase self) where TSingleComponent : struct, IEcsSingleComponent - { - return self.Optional>(); - } - } -} diff --git a/src/Utils/ArrayUtility.cs b/src/Utils/ArrayUtility.cs index e5e72b6..fe8b188 100644 --- a/src/Utils/ArrayUtility.cs +++ b/src/Utils/ArrayUtility.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.InteropServices; -namespace DCFApixels.DragonECS +namespace DCFApixels.DragonECS.Utils { internal static class ArrayUtility { diff --git a/src/Utils/IntDispenser.cs b/src/Utils/IntDispenser.cs index c0b0b25..96fb120 100644 --- a/src/Utils/IntDispenser.cs +++ b/src/Utils/IntDispenser.cs @@ -1,7 +1,7 @@ using System.Collections.Concurrent; using System.Threading; -namespace DCFApixels.DragonECS +namespace DCFApixels.DragonECS.Utils { internal sealed class IntDispenser { diff --git a/src/Utils/Extensions.cs b/src/Utils/IntExtensions.cs similarity index 83% rename from src/Utils/Extensions.cs rename to src/Utils/IntExtensions.cs index 2e1fd6e..2c42f57 100644 --- a/src/Utils/Extensions.cs +++ b/src/Utils/IntExtensions.cs @@ -1,6 +1,6 @@ namespace DCFApixels.DragonECS { - public static class Extensions + public static class IntExtensions { public static entlong ToEntityLong(this int self, EcsWorld world) { diff --git a/src/Utils/SparseArray.cs b/src/Utils/SparseArray.cs index 493eac7..8d9dccb 100644 --- a/src/Utils/SparseArray.cs +++ b/src/Utils/SparseArray.cs @@ -6,7 +6,7 @@ using System.Diagnostics.Contracts; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -namespace DCFApixels.DragonECS +namespace DCFApixels.DragonECS.Utils { public class SparseArray { diff --git a/src/Utils/SparseSet.cs b/src/Utils/SparseSet.cs index 79f0636..9bc7b4d 100644 --- a/src/Utils/SparseSet.cs +++ b/src/Utils/SparseSet.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Text; -namespace DCFApixels.DragonECS +namespace DCFApixels.DragonECS.Utils { public class SparseSet : IEnumerable, ICollection, IReadOnlyCollection {