mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 18:14:37 +08:00
fix changes
This commit is contained in:
parent
df54e7bac7
commit
c0b1d8ba5b
242
src/EcsGroup.cs
242
src/EcsGroup.cs
@ -2,7 +2,6 @@
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Unity.Profiling;
|
using Unity.Profiling;
|
||||||
using static UnityEngine.Networking.UnityWebRequest;
|
|
||||||
using delayedOp = System.Int32;
|
using delayedOp = System.Int32;
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
@ -38,6 +37,11 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get => _source.CapacitySparce;
|
get => _source.CapacitySparce;
|
||||||
}
|
}
|
||||||
|
public bool IsReleazed
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get => _source.IsReleazed;
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
@ -46,10 +50,10 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public EcsGroup.Enumerator GetEnumerator() => _source.GetEnumerator();
|
public EcsGroup.Enumerator GetEnumerator() => _source.GetEnumerator();
|
||||||
|
|
||||||
public EcsGroup Extract()
|
/// <summary>Equivalent of the EcsGroup.Clone() method</summary>
|
||||||
{
|
/// <returns>An editable clone of this EcsReadnolyGroup</returns>
|
||||||
return new EcsGroup(_source);
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
}
|
public EcsGroup Extract() => _source.Clone();
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Object
|
#region Object
|
||||||
@ -59,24 +63,41 @@ namespace DCFApixels.DragonECS
|
|||||||
return _source.ToString();
|
return _source.ToString();
|
||||||
return "NULL";
|
return "NULL";
|
||||||
}
|
}
|
||||||
|
public override int GetHashCode() => _source.GetHashCode();
|
||||||
|
public override bool Equals(object obj) => obj is EcsGroup group && group == this;
|
||||||
|
public bool Equals(EcsReadonlyGroup other) => _source == other._source;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Internal
|
#region Internal
|
||||||
internal void Release()
|
|
||||||
{
|
|
||||||
_source.World.ReleaseGroup(_source);
|
|
||||||
}
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal EcsGroup GetGroupInternal() => _source;
|
internal EcsGroup GetGroupInternal() => _source;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region operators
|
||||||
|
public static bool operator ==(EcsReadonlyGroup a, EcsReadonlyGroup b) => a.Equals(b);
|
||||||
|
public static bool operator ==(EcsReadonlyGroup a, EcsGroup b) => a.Equals(b);
|
||||||
|
public static bool operator !=(EcsReadonlyGroup a, EcsReadonlyGroup b) => !a.Equals(b);
|
||||||
|
public static bool operator !=(EcsReadonlyGroup a, EcsGroup b) => !a.Equals(b);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Dispose/Release
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
_source.Dispose();
|
||||||
|
}
|
||||||
|
public void Release()
|
||||||
|
{
|
||||||
|
_source.World.ReleaseGroup(_source);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
// не может содержать значение 0
|
// не может содержать значение 0
|
||||||
// _delayedOps это int[] для отложенных операций, хранятся отложенные операции в виде int значения, если старший бит = 0 то это опреация добавленияб если = 1 то это операция вычитания
|
// _delayedOps это int[] для отложенных операций, хранятся отложенные операции в виде int значения, если старший бит = 0 то это опреация добавленияб если = 1 то это операция вычитания
|
||||||
|
|
||||||
// this collection can only store numbers greater than 0
|
// this collection can only store numbers greater than 0
|
||||||
public unsafe class EcsGroup
|
public unsafe class EcsGroup : IDisposable, IEquatable<EcsGroup>
|
||||||
{
|
{
|
||||||
private const int DEALAYED_ADD = 0;
|
private const int DEALAYED_ADD = 0;
|
||||||
private const int DEALAYED_REMOVE = int.MinValue;
|
private const int DEALAYED_REMOVE = int.MinValue;
|
||||||
@ -93,6 +114,8 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
private int _lockCount;
|
private int _lockCount;
|
||||||
|
|
||||||
|
private bool _isReleazed = true;
|
||||||
|
|
||||||
#region Properties
|
#region Properties
|
||||||
public IEcsWorld World => _source;
|
public IEcsWorld World => _source;
|
||||||
public int Count
|
public int Count
|
||||||
@ -115,16 +138,25 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get => new EcsReadonlyGroup(this);
|
get => new EcsReadonlyGroup(this);
|
||||||
}
|
}
|
||||||
|
public bool IsReleazed
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get => _isReleazed;
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constrcutors
|
#region Constrcutors
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
public static EcsGroup New(IEcsWorld world)
|
||||||
public EcsGroup(IEcsWorld source, int denseCapacity = 64, int delayedOpsCapacity = 128)
|
|
||||||
{
|
{
|
||||||
_source = source;
|
return world.GetGroupFromPool();
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
internal EcsGroup(IEcsWorld world, int denseCapacity = 64, int delayedOpsCapacity = 128)
|
||||||
|
{
|
||||||
|
_source = world;
|
||||||
_source.RegisterGroup(this);
|
_source.RegisterGroup(this);
|
||||||
_dense = new int[denseCapacity];
|
_dense = new int[denseCapacity];
|
||||||
_sparse = new int[source.EntitesCapacity];
|
_sparse = new int[world.EntitesCapacity];
|
||||||
|
|
||||||
_delayedOps = new delayedOp[delayedOpsCapacity];
|
_delayedOps = new delayedOp[delayedOpsCapacity];
|
||||||
|
|
||||||
@ -132,31 +164,13 @@ namespace DCFApixels.DragonECS
|
|||||||
_delayedOpsCount = 0;
|
_delayedOpsCount = 0;
|
||||||
_count = 0;
|
_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public EcsGroup(EcsGroup copyFrom, int delayedOpsCapacity = 128)
|
|
||||||
{
|
|
||||||
_source = copyFrom._source;
|
|
||||||
_source.RegisterGroup(this);
|
|
||||||
_dense = new int[copyFrom._dense.Length];
|
|
||||||
_sparse = new int[copyFrom._sparse.Length];
|
|
||||||
|
|
||||||
_delayedOps = new delayedOp[delayedOpsCapacity];
|
|
||||||
|
|
||||||
_lockCount = 0;
|
|
||||||
_delayedOpsCount = 0;
|
|
||||||
_count = 0;
|
|
||||||
|
|
||||||
foreach (var item in copyFrom)
|
|
||||||
AggressiveAdd(item.id);
|
|
||||||
}
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Contains
|
#region Contains
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool Contains(int entityID)
|
public bool Contains(int entityID)
|
||||||
{
|
{
|
||||||
return _sparse[entityID] > 0;
|
return _sparse[entityID] > 0;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -229,12 +243,7 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
#region Sort/Clear
|
||||||
internal void OnWorldResize(int newSize)
|
|
||||||
{
|
|
||||||
Array.Resize(ref _sparse, newSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Sort()
|
public void Sort()
|
||||||
{
|
{
|
||||||
int increment = 1;
|
int increment = 1;
|
||||||
@ -247,9 +256,20 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public void Clear() => _count = 0;
|
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
_count = 0;
|
||||||
|
for (int i = 0; i < _dense.Length; i++)
|
||||||
|
_dense[i] = 0;
|
||||||
|
for (int i = 0; i < _sparse.Length; i++)
|
||||||
|
_sparse[i] = 0;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region CopyFrom/Clone
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void CopyFrom(EcsReadonlyGroup group) => CopyFrom(group.GetGroupInternal());
|
||||||
public void CopyFrom(EcsGroup group)
|
public void CopyFrom(EcsGroup group)
|
||||||
{
|
{
|
||||||
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||||
@ -259,29 +279,20 @@ namespace DCFApixels.DragonECS
|
|||||||
foreach (var item in group)
|
foreach (var item in group)
|
||||||
AggressiveAdd(item.id);
|
AggressiveAdd(item.id);
|
||||||
}
|
}
|
||||||
public void CopyFrom(EcsReadonlyGroup group)
|
public EcsGroup Clone()
|
||||||
{
|
{
|
||||||
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
EcsGroup result = _source.GetGroupFromPool();
|
||||||
if (group.World != _source) throw new ArgumentException("groupFilter.World != World");
|
result.CopyFrom(this);
|
||||||
#endif
|
return result;
|
||||||
Clear();
|
|
||||||
foreach (var item in group)
|
|
||||||
AggressiveAdd(item.id);
|
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region Set operations
|
#region Set operations
|
||||||
/// <summary>as Union sets</summary>
|
/// <summary>as Union sets</summary>
|
||||||
public void AddGroup(EcsGroup group)
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
{
|
public void UnionWith(EcsReadonlyGroup group) => UnionWith(group.GetGroupInternal());
|
||||||
#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))
|
|
||||||
AggressiveAdd(item.id);
|
|
||||||
}
|
|
||||||
/// <summary>as Union sets</summary>
|
/// <summary>as Union sets</summary>
|
||||||
public void AddGroup(EcsReadonlyGroup group)
|
public void UnionWith(EcsGroup group)
|
||||||
{
|
{
|
||||||
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||||
if (_source != group.World) throw new ArgumentException("World != groupFilter.World");
|
if (_source != group.World) throw new ArgumentException("World != groupFilter.World");
|
||||||
@ -290,8 +301,12 @@ namespace DCFApixels.DragonECS
|
|||||||
if (!Contains(item.id))
|
if (!Contains(item.id))
|
||||||
AggressiveAdd(item.id);
|
AggressiveAdd(item.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>as Except sets</summary>
|
/// <summary>as Except sets</summary>
|
||||||
public void RemoveGroup(EcsGroup group)
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void ExceptWith(EcsReadonlyGroup group) => ExceptWith(group.GetGroupInternal());
|
||||||
|
/// <summary>as Except sets</summary>
|
||||||
|
public void ExceptWith(EcsGroup group)
|
||||||
{
|
{
|
||||||
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||||
if (_source != group.World) throw new ArgumentException("World != groupFilter.World");
|
if (_source != group.World) throw new ArgumentException("World != groupFilter.World");
|
||||||
@ -300,16 +315,10 @@ namespace DCFApixels.DragonECS
|
|||||||
if (group.Contains(item.id))
|
if (group.Contains(item.id))
|
||||||
AggressiveRemove(item.id);
|
AggressiveRemove(item.id);
|
||||||
}
|
}
|
||||||
/// <summary>as Except sets</summary>
|
|
||||||
public void RemoveGroup(EcsReadonlyGroup group)
|
/// <summary>as Intersect sets</summary>
|
||||||
{
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
public void AndWith(EcsReadonlyGroup group) => AndWith(group.GetGroupInternal());
|
||||||
if (_source != group.World) throw new ArgumentException("World != groupFilter.World");
|
|
||||||
#endif
|
|
||||||
foreach (var item in group)
|
|
||||||
if (Contains(item.id))
|
|
||||||
AggressiveRemove(item.id);
|
|
||||||
}
|
|
||||||
/// <summary>as Intersect sets</summary>
|
/// <summary>as Intersect sets</summary>
|
||||||
public void AndWith(EcsGroup group)
|
public void AndWith(EcsGroup group)
|
||||||
{
|
{
|
||||||
@ -320,33 +329,15 @@ namespace DCFApixels.DragonECS
|
|||||||
if (!group.Contains(item.id))
|
if (!group.Contains(item.id))
|
||||||
AggressiveRemove(item.id);
|
AggressiveRemove(item.id);
|
||||||
}
|
}
|
||||||
/// <summary>as Intersect sets</summary>
|
|
||||||
public void AndWith(EcsReadonlyGroup group)
|
/// <summary>as Symmetric Except sets</summary>
|
||||||
{
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
public void XorWith(EcsReadonlyGroup group) => XorWith(group.GetGroupInternal());
|
||||||
if (World != group.World) throw new ArgumentException("World != groupFilter.World");
|
|
||||||
#endif
|
|
||||||
foreach (var item in this)
|
|
||||||
if (!group.Contains(item.id))
|
|
||||||
AggressiveRemove(item.id);
|
|
||||||
}
|
|
||||||
/// <summary>as Symmetric Except sets</summary>
|
/// <summary>as Symmetric Except sets</summary>
|
||||||
public void XorWith(EcsGroup group)
|
public void XorWith(EcsGroup group)
|
||||||
{
|
{
|
||||||
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||||
if (_source != group.World) throw new ArgumentException("World != groupFilter.World");
|
if (_source != group.World) throw new ArgumentException("World != groupFilter.World");
|
||||||
#endif
|
|
||||||
foreach (var item in group)
|
|
||||||
if (Contains(item.id))
|
|
||||||
AggressiveRemove(item.id);
|
|
||||||
else
|
|
||||||
AggressiveAdd(item.id);
|
|
||||||
}
|
|
||||||
/// <summary>as Symmetric Except sets</summary>
|
|
||||||
public void XorWith(EcsReadonlyGroup group)
|
|
||||||
{
|
|
||||||
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
|
||||||
if (_source != group.World) throw new ArgumentException("World != groupFilter.World");
|
|
||||||
#endif
|
#endif
|
||||||
foreach (var item in group)
|
foreach (var item in group)
|
||||||
if (Contains(item.id))
|
if (Contains(item.id))
|
||||||
@ -358,7 +349,8 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
#region Static Set operations
|
#region Static Set operations
|
||||||
/// <summary>as Except sets</summary>
|
/// <summary>as Except sets</summary>
|
||||||
public static EcsReadonlyGroup Remove(EcsGroup a, EcsGroup b)
|
/// <returns>new group from pool</returns>
|
||||||
|
public static EcsGroup Except(EcsGroup a, EcsGroup b)
|
||||||
{
|
{
|
||||||
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||||
if (a._source != b._source) throw new ArgumentException("a.World != b.World");
|
if (a._source != b._source) throw new ArgumentException("a.World != b.World");
|
||||||
@ -368,10 +360,11 @@ namespace DCFApixels.DragonECS
|
|||||||
if (!b.Contains(item.id))
|
if (!b.Contains(item.id))
|
||||||
result.AggressiveAdd(item.id);
|
result.AggressiveAdd(item.id);
|
||||||
a._source.ReleaseGroup(a);
|
a._source.ReleaseGroup(a);
|
||||||
return result.Readonly;
|
return result;
|
||||||
}
|
}
|
||||||
/// <summary>as Intersect sets</summary>
|
/// <summary>as Intersect sets</summary>
|
||||||
public static EcsReadonlyGroup And(EcsGroup a, EcsGroup b)
|
/// <returns>new group from pool</returns>
|
||||||
|
public static EcsGroup And(EcsGroup a, EcsGroup b)
|
||||||
{
|
{
|
||||||
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||||
if (a._source != b._source) throw new ArgumentException("a.World != b.World");
|
if (a._source != b._source) throw new ArgumentException("a.World != b.World");
|
||||||
@ -381,7 +374,21 @@ namespace DCFApixels.DragonECS
|
|||||||
if (b.Contains(item.id))
|
if (b.Contains(item.id))
|
||||||
result.AggressiveAdd(item.id);
|
result.AggressiveAdd(item.id);
|
||||||
a._source.ReleaseGroup(a);
|
a._source.ReleaseGroup(a);
|
||||||
return result.Readonly;
|
return result;
|
||||||
|
}
|
||||||
|
/// <summary>as Intersect sets</summary>
|
||||||
|
/// <returns>new group from pool</returns>
|
||||||
|
public static EcsGroup Union(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)
|
||||||
|
result.AggressiveAdd(item.id);
|
||||||
|
foreach (var item in a)
|
||||||
|
result.Add(item.id);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -450,6 +457,51 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
return string.Join(", ", _dense.AsSpan(1, _count).ToArray());
|
return string.Join(", ", _dense.AsSpan(1, _count).ToArray());
|
||||||
}
|
}
|
||||||
|
public override bool Equals(object obj) => obj is EcsGroup group && Equals(group);
|
||||||
|
public bool Equals(EcsReadonlyGroup other) => Equals(other.GetGroupInternal());
|
||||||
|
public bool Equals(EcsGroup other)
|
||||||
|
{
|
||||||
|
if (other.Count != Count)
|
||||||
|
return false;
|
||||||
|
foreach (var item in other)
|
||||||
|
if (!Contains(item.id))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
int hash = 0;
|
||||||
|
foreach (var item in this)
|
||||||
|
hash ^= 1 << (item.id % 32); //реализация от балды, так как не нужен, но фишка в том что хеш не учитывает порядок сущьностей, что явлется правильным поведением.
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region operators
|
||||||
|
public static bool operator ==(EcsGroup a, EcsGroup b) => a.Equals(b);
|
||||||
|
public static bool operator ==(EcsGroup a, EcsReadonlyGroup b) => a.Equals(b);
|
||||||
|
public static bool operator !=(EcsGroup a, EcsGroup b) => !a.Equals(b);
|
||||||
|
public static bool operator !=(EcsGroup a, EcsReadonlyGroup b) => !a.Equals(b);
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region OnWorldResize
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
internal void OnWorldResize(int newSize)
|
||||||
|
{
|
||||||
|
Array.Resize(ref _sparse, newSize);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region IDisposable/Release
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Release();
|
||||||
|
}
|
||||||
|
public void Release()
|
||||||
|
{
|
||||||
|
_isReleazed = true;
|
||||||
|
_source.ReleaseGroup(this);
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,6 @@ namespace DCFApixels.DragonECS
|
|||||||
public Type ComponentType { get; }
|
public Type ComponentType { get; }
|
||||||
public int ComponentID { get; }
|
public int ComponentID { get; }
|
||||||
public IEcsWorld World { get; }
|
public IEcsWorld World { get; }
|
||||||
public EcsReadonlyGroup Entities { get; }
|
|
||||||
public int Count { get; }
|
public int Count { get; }
|
||||||
public int Capacity { get; }
|
public int Capacity { get; }
|
||||||
public bool Has(int entityID);
|
public bool Has(int entityID);
|
||||||
@ -34,7 +33,6 @@ namespace DCFApixels.DragonECS
|
|||||||
public Type ComponentType => typeof(NullComponent);
|
public Type ComponentType => typeof(NullComponent);
|
||||||
public int ComponentID => -1;
|
public int ComponentID => -1;
|
||||||
public IEcsWorld World => _source;
|
public IEcsWorld World => _source;
|
||||||
public EcsReadonlyGroup Entities => default;
|
|
||||||
public int Count => 0;
|
public int Count => 0;
|
||||||
public int Capacity => 1;
|
public int Capacity => 1;
|
||||||
public void Del(int index) { }
|
public void Del(int index) { }
|
||||||
@ -47,7 +45,6 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
public abstract class EcsPool
|
public abstract class EcsPool
|
||||||
{
|
{
|
||||||
internal EcsGroup entities;
|
|
||||||
public abstract bool Has(int entityID);
|
public abstract bool Has(int entityID);
|
||||||
internal abstract void OnWorldResize(int newSize);
|
internal abstract void OnWorldResize(int newSize);
|
||||||
}
|
}
|
||||||
@ -66,7 +63,6 @@ namespace DCFApixels.DragonECS
|
|||||||
private IEcsComponentReset<T> _componentResetHandler;
|
private IEcsComponentReset<T> _componentResetHandler;
|
||||||
private PoolRunnres _poolRunnres;
|
private PoolRunnres _poolRunnres;
|
||||||
#region Properites
|
#region Properites
|
||||||
public EcsReadonlyGroup Entities => entities.Readonly;
|
|
||||||
public int Count => _itemsCount;
|
public int Count => _itemsCount;
|
||||||
public int Capacity => _items.Length;
|
public int Capacity => _items.Length;
|
||||||
public IEcsWorld World => _source;
|
public IEcsWorld World => _source;
|
||||||
@ -77,7 +73,6 @@ namespace DCFApixels.DragonECS
|
|||||||
#region Constructors
|
#region Constructors
|
||||||
internal EcsPool(IEcsWorld source, int id, int capacity, PoolRunnres poolRunnres)
|
internal EcsPool(IEcsWorld source, int id, int capacity, PoolRunnres poolRunnres)
|
||||||
{
|
{
|
||||||
entities = new EcsGroup(source);
|
|
||||||
_source = source;
|
_source = source;
|
||||||
_componentID = id;
|
_componentID = id;
|
||||||
|
|
||||||
@ -105,7 +100,6 @@ namespace DCFApixels.DragonECS
|
|||||||
ref int itemIndex = ref _mapping[entityID];
|
ref int itemIndex = ref _mapping[entityID];
|
||||||
if (itemIndex <= 0)
|
if (itemIndex <= 0)
|
||||||
{
|
{
|
||||||
entities.Add(entityID);
|
|
||||||
if (_recycledItemsCount > 0)
|
if (_recycledItemsCount > 0)
|
||||||
{
|
{
|
||||||
itemIndex = _recycledItems[--_recycledItemsCount];
|
itemIndex = _recycledItems[--_recycledItemsCount];
|
||||||
@ -147,8 +141,6 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
// using (_delMark.Auto())
|
// using (_delMark.Auto())
|
||||||
// {
|
// {
|
||||||
entities.Remove(entityID);
|
|
||||||
|
|
||||||
if (_recycledItemsCount >= _recycledItems.Length)
|
if (_recycledItemsCount >= _recycledItems.Length)
|
||||||
Array.Resize(ref _recycledItems, _recycledItems.Length << 1);
|
Array.Resize(ref _recycledItems, _recycledItems.Length << 1);
|
||||||
_recycledItems[_recycledItemsCount++] = _mapping[entityID];
|
_recycledItems[_recycledItemsCount++] = _mapping[entityID];
|
||||||
@ -168,7 +160,7 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
#region Object
|
#region Object
|
||||||
public override bool Equals(object obj) => base.Equals(obj);
|
public override bool Equals(object obj) => base.Equals(obj);
|
||||||
public override int GetHashCode() => _source.GetHashCode() + ~ComponentID;
|
public override int GetHashCode() => _source.GetHashCode() ^ ~ComponentID;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Internal
|
#region Internal
|
||||||
|
@ -16,46 +16,37 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
private ProfilerMarker _getEnumerator = new ProfilerMarker("EcsQuery.GetEnumerator");
|
private ProfilerMarker _getEnumerator = new ProfilerMarker("EcsQuery.GetEnumerator");
|
||||||
|
|
||||||
|
|
||||||
public EcsGroup.Enumerator GetEnumerator()
|
public EcsGroup.Enumerator GetEnumerator()
|
||||||
{
|
{
|
||||||
using (_getEnumerator.Auto())
|
using (_getEnumerator.Auto())
|
||||||
{
|
{
|
||||||
// groupFilter.Clear();
|
var pools = World.GetAllPools();
|
||||||
var pools = World.GetAllPools();
|
|
||||||
//
|
EcsReadonlyGroup all = World.Entities;
|
||||||
// if (mask.Inc.Length > 0)
|
groupFilter.Clear();
|
||||||
// {
|
foreach (var e in all)
|
||||||
// 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++)
|
|
||||||
{
|
{
|
||||||
sum = EcsGroup.And(sum.GetGroupInternal(), pools[mask.Inc[i]].entities);
|
int entityID = e.id;
|
||||||
// Debug.Log("inc " + sum.ToString());
|
|
||||||
|
for (int i = 0, iMax = mask.Inc.Length; i < iMax; i++)
|
||||||
|
{
|
||||||
|
if (!pools[mask.Inc[i]].Has(entityID))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0, iMax = mask.Exc.Length; i < iMax; i++)
|
||||||
|
{
|
||||||
|
if (pools[mask.Exc[i]].Has(entityID))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
groupFilter.AggressiveAdd(entityID);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < mask.Exc.Length; i++)
|
groupFilter.Sort();
|
||||||
{
|
return groupFilter.GetEnumerator();
|
||||||
sum = EcsGroup.Remove(sum.GetGroupInternal(), pools[mask.Exc[i]].entities);
|
|
||||||
// Debug.Log("exc " + sum.ToString());
|
|
||||||
}
|
|
||||||
//sum.GetGroupInternal().Sort();
|
|
||||||
return sum.GetEnumerator();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
protected virtual void Init(Builder b) { }
|
protected virtual void Init(Builder b) { }
|
||||||
@ -85,7 +76,8 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
|
|
||||||
builder.End(out newQuery.mask);
|
builder.End(out newQuery.mask);
|
||||||
newQuery.groupFilter = new EcsGroup(world);
|
// newQuery.groupFilter = new EcsGroup(world);
|
||||||
|
newQuery.groupFilter = EcsGroup.New(world);
|
||||||
return (TQuery)(object)newQuery;
|
return (TQuery)(object)newQuery;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,7 +88,6 @@ namespace DCFApixels.DragonECS
|
|||||||
_exc = new List<int>(4);
|
_exc = new List<int>(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Init query member methods
|
|
||||||
public override inc<TComponent> Include<TComponent>() where TComponent : struct
|
public override inc<TComponent> Include<TComponent>() where TComponent : struct
|
||||||
{
|
{
|
||||||
_inc.Add(_world.GetComponentID<TComponent>());
|
_inc.Add(_world.GetComponentID<TComponent>());
|
||||||
@ -111,18 +102,14 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
return new opt<TComponent>(_world.GetPool<TComponent>());
|
return new opt<TComponent>(_world.GetPool<TComponent>());
|
||||||
}
|
}
|
||||||
#endregion
|
|
||||||
|
|
||||||
private void End(out EcsQueryMask mask)
|
private void End(out EcsQueryMask mask)
|
||||||
{
|
{
|
||||||
_inc.Sort();
|
_inc.Sort();
|
||||||
_exc.Sort();
|
_exc.Sort();
|
||||||
mask = new EcsQueryMask(_world.ArchetypeType, _inc.ToArray(), _exc.ToArray());
|
mask = new EcsQueryMask(_world.ArchetypeType, _inc.ToArray(), _exc.ToArray());
|
||||||
|
|
||||||
_world = null;
|
_world = null;
|
||||||
_inc.Clear();
|
|
||||||
_inc = null;
|
_inc = null;
|
||||||
_exc.Clear();
|
|
||||||
_exc = null;
|
_exc = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
|
||||||
{
|
|
||||||
public class EcsTable
|
|
||||||
{
|
|
||||||
private IEcsPool[] _pools;
|
|
||||||
private EcsNullPool _nullPool;
|
|
||||||
|
|
||||||
private short[] _gens;
|
|
||||||
private short[] _componentCounts;
|
|
||||||
|
|
||||||
private int _entitiesCount;
|
|
||||||
|
|
||||||
private List<EcsQuery>[] _filtersByIncludedComponents;
|
|
||||||
private List<EcsQuery>[] _filtersByExcludedComponents;
|
|
||||||
|
|
||||||
private EcsQuery[] _queries;
|
|
||||||
|
|
||||||
private List<EcsGroup> _groups;
|
|
||||||
|
|
||||||
|
|
||||||
#region Properties
|
|
||||||
public int Count => _entitiesCount;
|
|
||||||
public int Capacity => _gens.Length;
|
|
||||||
public ReadOnlySpan<IEcsPool> GetAllPools() => new ReadOnlySpan<IEcsPool>(_pools);
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region internal Add/Has/Remove
|
|
||||||
internal void Add(int entityID)
|
|
||||||
{
|
|
||||||
int entity;
|
|
||||||
if (_entitiesCount >= _gens.Length)
|
|
||||||
{
|
|
||||||
Array.Resize(ref _gens, _gens.Length << 1);
|
|
||||||
Array.Resize(ref _componentCounts, _componentCounts.Length << 1);
|
|
||||||
}
|
|
||||||
_gens[_entitiesCount++]++;
|
|
||||||
_componentCounts[_entitiesCount++] = 0;
|
|
||||||
|
|
||||||
// if (_gens.Length <= entityID)
|
|
||||||
// {
|
|
||||||
// //TODO есть проблема что если передать слишком большой id такой алогоритм не сработает
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
internal void Has(int entityID)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
internal void Remove(int entityID)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
//public int GetComponentID<T>() => ;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -33,7 +33,7 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
public abstract class EcsWorld
|
public abstract class EcsWorld
|
||||||
{
|
{
|
||||||
internal static IEcsWorld[] Worlds = new IEcsWorld[8];
|
public static IEcsWorld[] Worlds = new IEcsWorld[8];
|
||||||
private static IntDispenser _worldIdDispenser = new IntDispenser(0);
|
private static IntDispenser _worldIdDispenser = new IntDispenser(0);
|
||||||
|
|
||||||
public readonly short id;
|
public readonly short id;
|
||||||
@ -196,18 +196,12 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region IsMaskCompatible/IsMaskCompatibleWithout
|
#region IsMaskCompatible
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public bool IsMaskCompatible<TInc>(int entityID) where TInc : struct, IInc
|
|
||||||
{
|
|
||||||
return IsMaskCompatible(EcsMaskMap<TWorldArchetype>.GetMask<TInc, Exc>(), entityID);
|
|
||||||
}
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool IsMaskCompatible<TInc, TExc>(int entityID) where TInc : struct, IInc where TExc : struct, IExc
|
public bool IsMaskCompatible<TInc, TExc>(int entityID) where TInc : struct, IInc where TExc : struct, IExc
|
||||||
{
|
{
|
||||||
return IsMaskCompatible(EcsMaskMap<TWorldArchetype>.GetMask<TInc, TExc>(), entityID);
|
return IsMaskCompatible(EcsMaskMap<TWorldArchetype>.GetMask<TInc, TExc>(), entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsMaskCompatible(EcsComponentMask mask, int entityID)
|
public bool IsMaskCompatible(EcsComponentMask mask, int entityID)
|
||||||
{
|
{
|
||||||
#if (DEBUG && !DISABLE_DRAGONECS_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
#if (DEBUG && !DISABLE_DRAGONECS_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||||
@ -348,9 +342,7 @@ namespace DCFApixels.DragonECS
|
|||||||
EcsGroup IEcsWorld.GetGroupFromPool()
|
EcsGroup IEcsWorld.GetGroupFromPool()
|
||||||
{
|
{
|
||||||
if (_pool.Count <= 0)
|
if (_pool.Count <= 0)
|
||||||
{
|
|
||||||
return new EcsGroup(this);
|
return new EcsGroup(this);
|
||||||
}
|
|
||||||
return _pool.Pop();
|
return _pool.Pop();
|
||||||
}
|
}
|
||||||
void IEcsWorld.ReleaseGroup(EcsGroup group)
|
void IEcsWorld.ReleaseGroup(EcsGroup group)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using UnityEngine.Rendering;
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
|
36
src/TestPool.cs
Normal file
36
src/TestPool.cs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS.Test
|
||||||
|
{
|
||||||
|
public class TestWorld
|
||||||
|
{
|
||||||
|
public PoolToken RegisterPool<TComponent>()
|
||||||
|
{
|
||||||
|
return new PoolToken(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public readonly struct PoolToken
|
||||||
|
{
|
||||||
|
internal readonly ushort id;
|
||||||
|
public PoolToken(ushort id)
|
||||||
|
{
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//реализовать query так чтоб на вход он получал какуюто коллекцию и заполнял ее. по итогу на выходе запроса юзер будет иметь просто список
|
||||||
|
//таким образом во первых он сам может решить как его прокрутить, через for или foreach или еще как. во вторых можно будет прикрутить поддержку nativearray от unity
|
||||||
|
|
||||||
|
public class TestPool<TComponent>
|
||||||
|
{
|
||||||
|
private PoolToken _token;
|
||||||
|
public TestPool(TestWorld world)
|
||||||
|
{
|
||||||
|
_token = world.RegisterPool<TComponent>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user