mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-11-14 01:35:54 +08:00
moving part of the API into a separate module
This commit is contained in:
parent
32429e5af8
commit
7cc02d00ba
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using DCFApixels.DragonECS.Utils;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
using System;
|
using DCFApixels.DragonECS.Internal;
|
||||||
|
using DCFApixels.DragonECS.Utils;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using DCFApixels.DragonECS.Internal;
|
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
@ -144,7 +145,7 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Queries
|
#region Subjects
|
||||||
public TSubject GetSubject<TSubject>() where TSubject : EcsSubject
|
public TSubject GetSubject<TSubject>() where TSubject : EcsSubject
|
||||||
{
|
{
|
||||||
int uniqueID = WorldMetaStorage.GetSubjectId<TSubject>(_worldTypeID);
|
int uniqueID = WorldMetaStorage.GetSubjectId<TSubject>(_worldTypeID);
|
||||||
@ -154,104 +155,45 @@ namespace DCFApixels.DragonECS
|
|||||||
_subjects[uniqueID] = EcsSubject.Builder.Build<TSubject>(this);
|
_subjects[uniqueID] = EcsSubject.Builder.Build<TSubject>(this);
|
||||||
return (TSubject)_subjects[uniqueID];
|
return (TSubject)_subjects[uniqueID];
|
||||||
}
|
}
|
||||||
#region Iterate
|
|
||||||
public EcsSubjectIterator<TSubject> IterateFor<TSubject>(EcsReadonlyGroup sourceGroup, out TSubject subject) where TSubject : EcsSubject
|
|
||||||
{
|
|
||||||
|
|
||||||
subject = GetSubject<TSubject>();
|
|
||||||
return subject.GetIteratorFor(sourceGroup);
|
|
||||||
}
|
|
||||||
public EcsSubjectIterator<TSubject> IterateFor<TSubject>(EcsReadonlyGroup sourceGroup) where TSubject : EcsSubject
|
|
||||||
{
|
|
||||||
return GetSubject<TSubject>().GetIteratorFor(sourceGroup);
|
|
||||||
}
|
|
||||||
public EcsSubjectIterator<TSubject> Iterate<TSubject>(out TSubject subject) where TSubject : EcsSubject
|
|
||||||
{
|
|
||||||
subject = GetSubject<TSubject>();
|
|
||||||
return subject.GetIterator();
|
|
||||||
}
|
|
||||||
public EcsSubjectIterator<TSubject> Iterate<TSubject>() where TSubject : EcsSubject
|
|
||||||
{
|
|
||||||
return GetSubject<TSubject>().GetIterator();
|
|
||||||
}
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Where
|
#region Queries
|
||||||
private EcsWhereExecutor<TSubject> GetWhereExecutor<TSubject>() where TSubject : EcsSubject
|
public TExecutor GetExecutor<TExecutor>(Func<EcsWorld, TExecutor> builder) where TExecutor: EcsQueryExecutor
|
||||||
{
|
{
|
||||||
int id = WorldMetaStorage.GetExecutorId<EcsWhereExecutor<TSubject>>(_worldTypeID);
|
int id = WorldMetaStorage.GetExecutorId<TExecutor>(_worldTypeID);
|
||||||
if (id >= _executors.Length)
|
if (id >= _executors.Length)
|
||||||
Array.Resize(ref _executors, _executors.Length << 1);
|
Array.Resize(ref _executors, _executors.Length << 1);
|
||||||
if (_executors[id] == null)
|
if (_executors[id] == null)
|
||||||
_executors[id] = new EcsWhereExecutor<TSubject>(GetSubject<TSubject>());
|
_executors[id] = builder(this);
|
||||||
return (EcsWhereExecutor<TSubject>)_executors[id];
|
return (TExecutor)_executors[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
private EcsWhereExecutor<TSubject> EcsWhereExecutorBuilder<TSubject>(EcsWorld world) where TSubject : EcsSubject
|
||||||
|
{
|
||||||
|
return new EcsWhereExecutor<TSubject>(world.GetSubject<TSubject>());
|
||||||
}
|
}
|
||||||
public EcsWhereResult<TSubject> WhereFor<TSubject>(EcsReadonlyGroup sourceGroup, out TSubject subject) where TSubject : EcsSubject
|
public EcsWhereResult<TSubject> WhereFor<TSubject>(EcsReadonlyGroup sourceGroup, out TSubject subject) where TSubject : EcsSubject
|
||||||
{
|
{
|
||||||
var executor = GetWhereExecutor<TSubject>();
|
var executor = GetExecutor(EcsWhereExecutorBuilder<TSubject>);
|
||||||
subject = executor.Subject;
|
subject = executor.Subject;
|
||||||
return executor.ExecuteFor(sourceGroup);
|
return executor.ExecuteFor(sourceGroup);
|
||||||
}
|
}
|
||||||
public EcsWhereResult<TSubject> WhereFor<TSubject>(EcsReadonlyGroup sourceGroup) where TSubject : EcsSubject
|
public EcsWhereResult<TSubject> WhereFor<TSubject>(EcsReadonlyGroup sourceGroup) where TSubject : EcsSubject
|
||||||
{
|
{
|
||||||
return GetWhereExecutor<TSubject>().ExecuteFor(sourceGroup);
|
return GetExecutor(EcsWhereExecutorBuilder<TSubject>).ExecuteFor(sourceGroup);
|
||||||
}
|
}
|
||||||
public EcsWhereResult<TSubject> Where<TSubject>(out TSubject subject) where TSubject : EcsSubject
|
public EcsWhereResult<TSubject> Where<TSubject>(out TSubject subject) where TSubject : EcsSubject
|
||||||
{
|
{
|
||||||
var executor = GetWhereExecutor<TSubject>();
|
var executor = GetExecutor(EcsWhereExecutorBuilder<TSubject>);
|
||||||
subject = executor.Subject;
|
subject = executor.Subject;
|
||||||
return executor.Execute();
|
return executor.Execute();
|
||||||
}
|
}
|
||||||
public EcsWhereResult<TSubject> Where<TSubject>() where TSubject : EcsSubject
|
public EcsWhereResult<TSubject> Where<TSubject>() where TSubject : EcsSubject
|
||||||
{
|
{
|
||||||
return GetWhereExecutor<TSubject>().Execute();
|
return GetExecutor(EcsWhereExecutorBuilder<TSubject>).Execute();
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Join
|
|
||||||
private EcsJoinAttachExecutor<TSubject, TAttachComponent> GetJoinAttachExecutor<TSubject, TAttachComponent>()
|
|
||||||
where TSubject : EcsSubject
|
|
||||||
where TAttachComponent : struct, IEcsAttachComponent
|
|
||||||
{
|
|
||||||
int id = WorldMetaStorage.GetExecutorId<EcsJoinAttachExecutor<TSubject, TAttachComponent>>(_worldTypeID);
|
|
||||||
if (id >= _executors.Length)
|
|
||||||
Array.Resize(ref _executors, _executors.Length << 1);
|
|
||||||
if (_executors[id] == null)
|
|
||||||
_executors[id] = new EcsJoinAttachExecutor<TSubject, TAttachComponent>(GetSubject<TSubject>());
|
|
||||||
return (EcsJoinAttachExecutor<TSubject, TAttachComponent>)_executors[id];
|
|
||||||
}
|
|
||||||
public EcsJoinAttachResult<TSubject, TAttachComponent> JoinFor<TSubject, TAttachComponent>(EcsReadonlyGroup sourceGroup, out TSubject subject)
|
|
||||||
where TSubject : EcsSubject
|
|
||||||
where TAttachComponent : struct, IEcsAttachComponent
|
|
||||||
{
|
|
||||||
var executor = GetJoinAttachExecutor<TSubject, TAttachComponent>();
|
|
||||||
subject = executor.Subject;
|
|
||||||
return executor.ExecuteFor(sourceGroup);
|
|
||||||
}
|
|
||||||
public EcsJoinAttachResult<TSubject, TAttachComponent> JoinFor<TSubject, TAttachComponent>(EcsReadonlyGroup sourceGroup)
|
|
||||||
where TSubject : EcsSubject
|
|
||||||
where TAttachComponent : struct, IEcsAttachComponent
|
|
||||||
{
|
|
||||||
return GetJoinAttachExecutor<TSubject, TAttachComponent>().ExecuteFor(sourceGroup);
|
|
||||||
}
|
|
||||||
public EcsJoinAttachResult<TSubject, TAttachComponent> Join<TSubject, TAttachComponent>(out TSubject subject)
|
|
||||||
where TSubject : EcsSubject
|
|
||||||
where TAttachComponent : struct, IEcsAttachComponent
|
|
||||||
{
|
|
||||||
var executor = GetJoinAttachExecutor<TSubject, TAttachComponent>();
|
|
||||||
subject = executor.Subject;
|
|
||||||
return executor.Execute();
|
|
||||||
}
|
|
||||||
public EcsJoinAttachResult<TSubject, TAttachComponent> Join<TSubject, TAttachComponent>()
|
|
||||||
where TSubject : EcsSubject
|
|
||||||
where TAttachComponent : struct, IEcsAttachComponent
|
|
||||||
{
|
|
||||||
return GetJoinAttachExecutor<TSubject, TAttachComponent>().Execute();
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region IsMatchesMask
|
#region IsMatchesMask
|
||||||
public bool IsMatchesMask(EcsMask mask, int entityID)
|
public bool IsMatchesMask(EcsMask mask, int entityID)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,189 +0,0 @@
|
|||||||
using Unity.Profiling;
|
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
|
||||||
{
|
|
||||||
public sealed class EcsJoinAttachExecutor<TSubject, TAttachComponent> : EcsQueryExecutor
|
|
||||||
where TSubject : EcsSubject
|
|
||||||
where TAttachComponent : struct, IEcsAttachComponent
|
|
||||||
{
|
|
||||||
private readonly TSubject _subject;
|
|
||||||
internal readonly EcsGroup _filteredGroup;
|
|
||||||
private EcsWorld _targetWorld;
|
|
||||||
|
|
||||||
private EcsAttachPool<TAttachComponent> _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<TAttachComponent>();
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Methods
|
|
||||||
public EcsJoinAttachResult<TSubject, TAttachComponent> Execute() => ExecuteFor(_targetPool.Entities);
|
|
||||||
public EcsJoinAttachResult<TSubject, TAttachComponent> 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<TSubject>(_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<TSubject, TAttachComponent>(_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<TSubject, TAttachComponent>
|
|
||||||
where TSubject : EcsSubject
|
|
||||||
where TAttachComponent : struct, IEcsAttachComponent
|
|
||||||
{
|
|
||||||
public readonly TSubject s;
|
|
||||||
private readonly EcsJoinAttachExecutor<TSubject, TAttachComponent> _executer;
|
|
||||||
private readonly long _verison;
|
|
||||||
|
|
||||||
public bool IsRelevant => _verison == _executer.ExecuteVersion;
|
|
||||||
|
|
||||||
public EcsJoinAttachResult(TSubject s, EcsJoinAttachExecutor<TSubject, TAttachComponent> 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
|
|
||||||
}
|
|
||||||
@ -1,198 +0,0 @@
|
|||||||
using System;
|
|
||||||
using Unity.Profiling;
|
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
|
||||||
{
|
|
||||||
public sealed class EcsJoinHierarchyExecutor<TSubject, TAttachComponent> : EcsQueryExecutor
|
|
||||||
where TSubject : EcsSubject
|
|
||||||
where TAttachComponent : struct, IEcsAttachComponent
|
|
||||||
{
|
|
||||||
private readonly TSubject _subject;
|
|
||||||
internal readonly EcsGroup _filteredGroup;
|
|
||||||
private EcsWorld _targetWorld;
|
|
||||||
|
|
||||||
private EcsAttachPool<TAttachComponent> _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<TAttachComponent>();
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Methods
|
|
||||||
public EcsJoinHierarchyResult<TSubject, TAttachComponent> Execute() => ExecuteFor(_targetPool.Entities);
|
|
||||||
public EcsJoinHierarchyResult<TSubject, TAttachComponent> 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<TSubject>(_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<TSubject, TAttachComponent>(_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<TSubject, TAttachComponent>
|
|
||||||
where TSubject : EcsSubject
|
|
||||||
where TAttachComponent : struct, IEcsAttachComponent
|
|
||||||
{
|
|
||||||
public readonly TSubject s;
|
|
||||||
private readonly EcsJoinHierarchyExecutor<TSubject, TAttachComponent> _executer;
|
|
||||||
private readonly long _verison;
|
|
||||||
|
|
||||||
public bool IsRelevant => _verison == _executer.ExecuteVersion;
|
|
||||||
|
|
||||||
public EcsJoinHierarchyResult(TSubject s, EcsJoinHierarchyExecutor<TSubject, TAttachComponent> 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
|
|
||||||
}
|
|
||||||
@ -2,6 +2,7 @@
|
|||||||
{
|
{
|
||||||
public abstract class EcsQueryExecutor
|
public abstract class EcsQueryExecutor
|
||||||
{
|
{
|
||||||
internal abstract void Destroy();
|
internal void Destroy() => OnDestroy();
|
||||||
|
protected abstract void OnDestroy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,7 +37,7 @@ namespace DCFApixels.DragonECS
|
|||||||
return new EcsWhereResult<TSubject>(this, _filteredGroup.Readonly);
|
return new EcsWhereResult<TSubject>(this, _filteredGroup.Readonly);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
internal sealed override void Destroy()
|
protected sealed override void OnDestroy()
|
||||||
{
|
{
|
||||||
_filteredGroup.Release();
|
_filteredGroup.Release();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,140 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
|
||||||
{
|
|
||||||
//íå âëèÿåò íà ñ÷åò÷èê êîìïîíåíòîâ íà ñóùíîñòè
|
|
||||||
/// <summary>Pool for IEcsNotNullComponent components</summary>
|
|
||||||
public sealed class EcsNotNullPool<T> : IEcsPoolImplementation<T>, IEnumerable<T> //IntelliSense hack
|
|
||||||
where T : struct, IEcsNotNullComponent
|
|
||||||
{
|
|
||||||
private EcsWorld _source;
|
|
||||||
private int _id;
|
|
||||||
|
|
||||||
private T[] _items; //sparse
|
|
||||||
private int _count;
|
|
||||||
|
|
||||||
private IEcsComponentReset<T> _componentResetHandler;
|
|
||||||
private IEcsComponentCopy<T> _componentCopyHandler;
|
|
||||||
|
|
||||||
private List<IEcsPoolEventListener> _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<IEcsPoolEventListener>();
|
|
||||||
|
|
||||||
_componentResetHandler = EcsComponentResetHandler<T>.instance;
|
|
||||||
_componentCopyHandler = EcsComponentCopyHandler<T>.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<T>().Write(toEntityID));
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Callbacks
|
|
||||||
void IEcsPoolImplementation.OnWorldResize(int newSize)
|
|
||||||
{
|
|
||||||
Array.Resize(ref _items, newSize);
|
|
||||||
}
|
|
||||||
void IEcsPoolImplementation.OnWorldDestroy() { }
|
|
||||||
void IEcsPoolImplementation.OnReleaseDelEntityBuffer(ReadOnlySpan<int> buffer)
|
|
||||||
{
|
|
||||||
foreach (var entityID in buffer)
|
|
||||||
_componentResetHandler.Reset(ref _items[entityID]);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Other
|
|
||||||
ref T IEcsPool<T>.Add(int entityID) => ref Write(entityID);
|
|
||||||
ref readonly T IEcsPool<T>.Read(int entityID) => ref Read(entityID);
|
|
||||||
ref T IEcsPool<T>.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<T> IEnumerable<T>.GetEnumerator() => throw new NotImplementedException();
|
|
||||||
IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException();
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// Not null component. Is present on all entities, without explicit addition and cannot be deleted
|
|
||||||
/// </summary>
|
|
||||||
public interface IEcsNotNullComponent { }
|
|
||||||
public static class EcsNotNullPoolExt
|
|
||||||
{
|
|
||||||
public static EcsNotNullPool<TNotNullComponent> GetPool<TNotNullComponent>(this EcsWorld self) where TNotNullComponent : struct, IEcsNotNullComponent
|
|
||||||
{
|
|
||||||
return self.GetPool<TNotNullComponent, EcsNotNullPool<TNotNullComponent>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EcsNotNullPool<TNotNullComponent> Include<TNotNullComponent>(this EcsSubjectBuilderBase self) where TNotNullComponent : struct, IEcsNotNullComponent
|
|
||||||
{
|
|
||||||
return self.Include<TNotNullComponent, EcsNotNullPool<TNotNullComponent>>();
|
|
||||||
}
|
|
||||||
public static EcsNotNullPool<TNotNullComponent> Exclude<TNotNullComponent>(this EcsSubjectBuilderBase self) where TNotNullComponent : struct, IEcsNotNullComponent
|
|
||||||
{
|
|
||||||
return self.Exclude<TNotNullComponent, EcsNotNullPool<TNotNullComponent>>();
|
|
||||||
}
|
|
||||||
public static EcsNotNullPool<TNotNullComponent> Optional<TNotNullComponent>(this EcsSubjectBuilderBase self) where TNotNullComponent : struct, IEcsNotNullComponent
|
|
||||||
{
|
|
||||||
return self.Optional<TNotNullComponent, EcsNotNullPool<TNotNullComponent>>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -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<T> : IEcsPoolImplementation<T>, IEnumerable<T> //IntelliSense hack
|
|
||||||
where T : struct, IEcsSingleComponent
|
|
||||||
{
|
|
||||||
private EcsWorld _source;
|
|
||||||
private int _id;
|
|
||||||
|
|
||||||
private int[] _mapping;
|
|
||||||
|
|
||||||
private int _count;
|
|
||||||
private T _component;
|
|
||||||
|
|
||||||
private List<IEcsPoolEventListener> _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<IEcsPoolEventListener>();
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Methods
|
|
||||||
public ref T Add(int entityID)
|
|
||||||
{
|
|
||||||
#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS
|
|
||||||
if (Has(entityID)) ThrowAlreadyHasComponent<T>(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<T>(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<T>(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<T>(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<T>(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<T>(fromEntityID);
|
|
||||||
#endif
|
|
||||||
toWorld.GetPool<T>().TryAddOrWrite(toEntityID);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Callbacks
|
|
||||||
void IEcsPoolImplementation.OnWorldResize(int newSize)
|
|
||||||
{
|
|
||||||
Array.Resize(ref _mapping, newSize);
|
|
||||||
}
|
|
||||||
void IEcsPoolImplementation.OnWorldDestroy() { }
|
|
||||||
void IEcsPoolImplementation.OnReleaseDelEntityBuffer(ReadOnlySpan<int> 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<T> IEnumerable<T>.GetEnumerator() => throw new NotImplementedException();
|
|
||||||
IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException();
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
/// <summary>Singleton component</summary>
|
|
||||||
public interface IEcsSingleComponent { }
|
|
||||||
public static class EcsSinglePoolExt
|
|
||||||
{
|
|
||||||
public static EcsSinglePool<TSingleComponent> GetPool<TSingleComponent>(this EcsWorld self)
|
|
||||||
where TSingleComponent : struct, IEcsSingleComponent
|
|
||||||
{
|
|
||||||
return self.GetPool<TSingleComponent, EcsSinglePool<TSingleComponent>>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EcsSinglePool<TSingleComponent> Include<TSingleComponent>(this EcsSubjectBuilderBase self) where TSingleComponent : struct, IEcsSingleComponent
|
|
||||||
{
|
|
||||||
return self.Include<TSingleComponent, EcsSinglePool<TSingleComponent>>();
|
|
||||||
}
|
|
||||||
public static EcsSinglePool<TSingleComponent> Exclude<TSingleComponent>(this EcsSubjectBuilderBase self) where TSingleComponent : struct, IEcsSingleComponent
|
|
||||||
{
|
|
||||||
return self.Exclude<TSingleComponent, EcsSinglePool<TSingleComponent>>();
|
|
||||||
}
|
|
||||||
public static EcsSinglePool<TSingleComponent> Optional<TSingleComponent>(this EcsSubjectBuilderBase self) where TSingleComponent : struct, IEcsSingleComponent
|
|
||||||
{
|
|
||||||
return self.Optional<TSingleComponent, EcsSinglePool<TSingleComponent>>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS.Utils
|
||||||
{
|
{
|
||||||
internal static class ArrayUtility
|
internal static class ArrayUtility
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS.Utils
|
||||||
{
|
{
|
||||||
internal sealed class IntDispenser
|
internal sealed class IntDispenser
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
public static class Extensions
|
public static class IntExtensions
|
||||||
{
|
{
|
||||||
public static entlong ToEntityLong(this int self, EcsWorld world)
|
public static entlong ToEntityLong(this int self, EcsWorld world)
|
||||||
{
|
{
|
||||||
@ -6,7 +6,7 @@ using System.Diagnostics.Contracts;
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS.Utils
|
||||||
{
|
{
|
||||||
public class SparseArray<TValue>
|
public class SparseArray<TValue>
|
||||||
{
|
{
|
||||||
|
|||||||
@ -4,7 +4,7 @@ using System.Collections.Generic;
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS.Utils
|
||||||
{
|
{
|
||||||
public class SparseSet : IEnumerable<int>, ICollection<int>, IReadOnlyCollection<int>
|
public class SparseSet : IEnumerable<int>, ICollection<int>, IReadOnlyCollection<int>
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user