diff --git a/src/EcsGroup.cs b/src/EcsGroup.cs
index 9a25f35..ee0a76e 100644
--- a/src/EcsGroup.cs
+++ b/src/EcsGroup.cs
@@ -2,7 +2,6 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Unity.Profiling;
-using static UnityEngine.Networking.UnityWebRequest;
using delayedOp = System.Int32;
namespace DCFApixels.DragonECS
@@ -38,6 +37,11 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _source.CapacitySparce;
}
+ public bool IsReleazed
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _source.IsReleazed;
+ }
#endregion
#region Methods
@@ -46,10 +50,10 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsGroup.Enumerator GetEnumerator() => _source.GetEnumerator();
- public EcsGroup Extract()
- {
- return new EcsGroup(_source);
- }
+ /// Equivalent of the EcsGroup.Clone() method
+ /// An editable clone of this EcsReadnolyGroup
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public EcsGroup Extract() => _source.Clone();
#endregion
#region Object
@@ -59,24 +63,41 @@ namespace DCFApixels.DragonECS
return _source.ToString();
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
#region Internal
- internal void Release()
- {
- _source.World.ReleaseGroup(_source);
- }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal EcsGroup GetGroupInternal() => _source;
#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
// _delayedOps это int[] для отложенных операций, хранятся отложенные операции в виде int значения, если старший бит = 0 то это опреация добавленияб если = 1 то это операция вычитания
// this collection can only store numbers greater than 0
- public unsafe class EcsGroup
+ public unsafe class EcsGroup : IDisposable, IEquatable
{
private const int DEALAYED_ADD = 0;
private const int DEALAYED_REMOVE = int.MinValue;
@@ -93,6 +114,8 @@ namespace DCFApixels.DragonECS
private int _lockCount;
+ private bool _isReleazed = true;
+
#region Properties
public IEcsWorld World => _source;
public int Count
@@ -115,16 +138,25 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new EcsReadonlyGroup(this);
}
+ public bool IsReleazed
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => _isReleazed;
+ }
#endregion
#region Constrcutors
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public EcsGroup(IEcsWorld source, int denseCapacity = 64, int delayedOpsCapacity = 128)
+ public static EcsGroup New(IEcsWorld world)
{
- _source = source;
+ return world.GetGroupFromPool();
+ }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal EcsGroup(IEcsWorld world, int denseCapacity = 64, int delayedOpsCapacity = 128)
+ {
+ _source = world;
_source.RegisterGroup(this);
_dense = new int[denseCapacity];
- _sparse = new int[source.EntitesCapacity];
+ _sparse = new int[world.EntitesCapacity];
_delayedOps = new delayedOp[delayedOpsCapacity];
@@ -132,31 +164,13 @@ namespace DCFApixels.DragonECS
_delayedOpsCount = 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
#region Contains
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Contains(int entityID)
{
- return _sparse[entityID] > 0;
+ return _sparse[entityID] > 0;
}
#endregion
@@ -229,12 +243,7 @@ namespace DCFApixels.DragonECS
}
#endregion
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal void OnWorldResize(int newSize)
- {
- Array.Resize(ref _sparse, newSize);
- }
-
+ #region Sort/Clear
public void Sort()
{
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)
{
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
@@ -259,29 +279,20 @@ namespace DCFApixels.DragonECS
foreach (var item in group)
AggressiveAdd(item.id);
}
- public void CopyFrom(EcsReadonlyGroup group)
+ public EcsGroup Clone()
{
-#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
- if (group.World != _source) throw new ArgumentException("groupFilter.World != World");
-#endif
- Clear();
- foreach (var item in group)
- AggressiveAdd(item.id);
+ EcsGroup result = _source.GetGroupFromPool();
+ result.CopyFrom(this);
+ return result;
}
+ #endregion
#region Set operations
/// as Union sets
- public void AddGroup(EcsGroup group)
- {
-#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);
- }
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void UnionWith(EcsReadonlyGroup group) => UnionWith(group.GetGroupInternal());
/// as Union sets
- public void AddGroup(EcsReadonlyGroup group)
+ public void UnionWith(EcsGroup group)
{
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
if (_source != group.World) throw new ArgumentException("World != groupFilter.World");
@@ -290,8 +301,12 @@ namespace DCFApixels.DragonECS
if (!Contains(item.id))
AggressiveAdd(item.id);
}
+
/// as Except sets
- public void RemoveGroup(EcsGroup group)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void ExceptWith(EcsReadonlyGroup group) => ExceptWith(group.GetGroupInternal());
+ /// as Except sets
+ public void ExceptWith(EcsGroup group)
{
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
if (_source != group.World) throw new ArgumentException("World != groupFilter.World");
@@ -300,16 +315,10 @@ namespace DCFApixels.DragonECS
if (group.Contains(item.id))
AggressiveRemove(item.id);
}
- /// as Except sets
- public void RemoveGroup(EcsReadonlyGroup group)
- {
-#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))
- AggressiveRemove(item.id);
- }
+
+ /// as Intersect sets
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void AndWith(EcsReadonlyGroup group) => AndWith(group.GetGroupInternal());
/// as Intersect sets
public void AndWith(EcsGroup group)
{
@@ -320,33 +329,15 @@ namespace DCFApixels.DragonECS
if (!group.Contains(item.id))
AggressiveRemove(item.id);
}
- /// as Intersect sets
- public void AndWith(EcsReadonlyGroup group)
- {
-#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
- if (World != group.World) throw new ArgumentException("World != groupFilter.World");
-#endif
- foreach (var item in this)
- if (!group.Contains(item.id))
- AggressiveRemove(item.id);
- }
+
+ /// as Symmetric Except sets
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void XorWith(EcsReadonlyGroup group) => XorWith(group.GetGroupInternal());
/// as Symmetric Except sets
public void XorWith(EcsGroup group)
{
#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))
- AggressiveRemove(item.id);
- else
- AggressiveAdd(item.id);
- }
- /// as Symmetric Except sets
- public void XorWith(EcsReadonlyGroup group)
- {
-#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))
@@ -358,7 +349,8 @@ namespace DCFApixels.DragonECS
#region Static Set operations
/// as Except sets
- public static EcsReadonlyGroup Remove(EcsGroup a, EcsGroup b)
+ /// new group from pool
+ public static EcsGroup Except(EcsGroup a, EcsGroup b)
{
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
if (a._source != b._source) throw new ArgumentException("a.World != b.World");
@@ -368,10 +360,11 @@ namespace DCFApixels.DragonECS
if (!b.Contains(item.id))
result.AggressiveAdd(item.id);
a._source.ReleaseGroup(a);
- return result.Readonly;
+ return result;
}
/// as Intersect sets
- public static EcsReadonlyGroup And(EcsGroup a, EcsGroup b)
+ /// new group from pool
+ public static EcsGroup And(EcsGroup a, EcsGroup b)
{
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
if (a._source != b._source) throw new ArgumentException("a.World != b.World");
@@ -381,7 +374,21 @@ namespace DCFApixels.DragonECS
if (b.Contains(item.id))
result.AggressiveAdd(item.id);
a._source.ReleaseGroup(a);
- return result.Readonly;
+ return result;
+ }
+ /// as Intersect sets
+ /// new group from pool
+ 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
@@ -450,6 +457,51 @@ namespace DCFApixels.DragonECS
{
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
}
diff --git a/src/EcsPool.cs b/src/EcsPool.cs
index 8d7674d..682e784 100644
--- a/src/EcsPool.cs
+++ b/src/EcsPool.cs
@@ -10,7 +10,6 @@ namespace DCFApixels.DragonECS
public Type ComponentType { get; }
public int ComponentID { get; }
public IEcsWorld World { get; }
- public EcsReadonlyGroup Entities { get; }
public int Count { get; }
public int Capacity { get; }
public bool Has(int entityID);
@@ -34,7 +33,6 @@ namespace DCFApixels.DragonECS
public Type ComponentType => typeof(NullComponent);
public int ComponentID => -1;
public IEcsWorld World => _source;
- public EcsReadonlyGroup Entities => default;
public int Count => 0;
public int Capacity => 1;
public void Del(int index) { }
@@ -47,7 +45,6 @@ namespace DCFApixels.DragonECS
}
public abstract class EcsPool
{
- internal EcsGroup entities;
public abstract bool Has(int entityID);
internal abstract void OnWorldResize(int newSize);
}
@@ -66,7 +63,6 @@ namespace DCFApixels.DragonECS
private IEcsComponentReset _componentResetHandler;
private PoolRunnres _poolRunnres;
#region Properites
- public EcsReadonlyGroup Entities => entities.Readonly;
public int Count => _itemsCount;
public int Capacity => _items.Length;
public IEcsWorld World => _source;
@@ -77,7 +73,6 @@ namespace DCFApixels.DragonECS
#region Constructors
internal EcsPool(IEcsWorld source, int id, int capacity, PoolRunnres poolRunnres)
{
- entities = new EcsGroup(source);
_source = source;
_componentID = id;
@@ -105,7 +100,6 @@ namespace DCFApixels.DragonECS
ref int itemIndex = ref _mapping[entityID];
if (itemIndex <= 0)
{
- entities.Add(entityID);
if (_recycledItemsCount > 0)
{
itemIndex = _recycledItems[--_recycledItemsCount];
@@ -147,8 +141,6 @@ namespace DCFApixels.DragonECS
{
// using (_delMark.Auto())
// {
- entities.Remove(entityID);
-
if (_recycledItemsCount >= _recycledItems.Length)
Array.Resize(ref _recycledItems, _recycledItems.Length << 1);
_recycledItems[_recycledItemsCount++] = _mapping[entityID];
@@ -168,7 +160,7 @@ namespace DCFApixels.DragonECS
#region Object
public override bool Equals(object obj) => base.Equals(obj);
- public override int GetHashCode() => _source.GetHashCode() + ~ComponentID;
+ public override int GetHashCode() => _source.GetHashCode() ^ ~ComponentID;
#endregion
#region Internal
diff --git a/src/EcsQuery.cs b/src/EcsQuery.cs
index c081e18..35c8143 100644
--- a/src/EcsQuery.cs
+++ b/src/EcsQuery.cs
@@ -16,46 +16,37 @@ namespace DCFApixels.DragonECS
private ProfilerMarker _getEnumerator = new ProfilerMarker("EcsQuery.GetEnumerator");
+
public EcsGroup.Enumerator GetEnumerator()
{
using (_getEnumerator.Auto())
{
- // groupFilter.Clear();
- var pools = World.GetAllPools();
- //
- // if (mask.Inc.Length > 0)
- // {
- // groupFilter.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++)
+ var pools = World.GetAllPools();
+
+ EcsReadonlyGroup all = World.Entities;
+ groupFilter.Clear();
+ foreach (var e in all)
{
- sum = EcsGroup.And(sum.GetGroupInternal(), pools[mask.Inc[i]].entities);
- // Debug.Log("inc " + sum.ToString());
+ int entityID = e.id;
+
+ 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++)
- {
- sum = EcsGroup.Remove(sum.GetGroupInternal(), pools[mask.Exc[i]].entities);
- // Debug.Log("exc " + sum.ToString());
- }
- //sum.GetGroupInternal().Sort();
- return sum.GetEnumerator();
+ groupFilter.Sort();
+ return groupFilter.GetEnumerator();
}
}
protected virtual void Init(Builder b) { }
@@ -85,7 +76,8 @@ namespace DCFApixels.DragonECS
}
builder.End(out newQuery.mask);
- newQuery.groupFilter = new EcsGroup(world);
+ // newQuery.groupFilter = new EcsGroup(world);
+ newQuery.groupFilter = EcsGroup.New(world);
return (TQuery)(object)newQuery;
}
@@ -96,7 +88,6 @@ namespace DCFApixels.DragonECS
_exc = new List(4);
}
- #region Init query member methods
public override inc Include() where TComponent : struct
{
_inc.Add(_world.GetComponentID());
@@ -111,18 +102,14 @@ namespace DCFApixels.DragonECS
{
return new opt(_world.GetPool());
}
- #endregion
private void End(out EcsQueryMask mask)
{
_inc.Sort();
_exc.Sort();
mask = new EcsQueryMask(_world.ArchetypeType, _inc.ToArray(), _exc.ToArray());
-
_world = null;
- _inc.Clear();
_inc = null;
- _exc.Clear();
_exc = null;
}
}
diff --git a/src/EcsTable.cs b/src/EcsTable.cs
deleted file mode 100644
index 152beb7..0000000
--- a/src/EcsTable.cs
+++ /dev/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[] _filtersByIncludedComponents;
- private List[] _filtersByExcludedComponents;
-
- private EcsQuery[] _queries;
-
- private List _groups;
-
-
- #region Properties
- public int Count => _entitiesCount;
- public int Capacity => _gens.Length;
- public ReadOnlySpan GetAllPools() => new ReadOnlySpan(_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() => ;
- }
-
-
-}
diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs
index 79b9c6d..99f65e1 100644
--- a/src/EcsWorld.cs
+++ b/src/EcsWorld.cs
@@ -33,7 +33,7 @@ namespace DCFApixels.DragonECS
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);
public readonly short id;
@@ -196,18 +196,12 @@ namespace DCFApixels.DragonECS
}
#endregion
- #region IsMaskCompatible/IsMaskCompatibleWithout
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public bool IsMaskCompatible(int entityID) where TInc : struct, IInc
- {
- return IsMaskCompatible(EcsMaskMap.GetMask(), entityID);
- }
+ #region IsMaskCompatible
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsMaskCompatible(int entityID) where TInc : struct, IInc where TExc : struct, IExc
{
return IsMaskCompatible(EcsMaskMap.GetMask(), entityID);
}
-
public bool IsMaskCompatible(EcsComponentMask mask, int entityID)
{
#if (DEBUG && !DISABLE_DRAGONECS_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
@@ -348,9 +342,7 @@ namespace DCFApixels.DragonECS
EcsGroup IEcsWorld.GetGroupFromPool()
{
if (_pool.Count <= 0)
- {
return new EcsGroup(this);
- }
return _pool.Pop();
}
void IEcsWorld.ReleaseGroup(EcsGroup group)
diff --git a/src/Entities/ent.cs b/src/Entities/ent.cs
index b4bee19..c5ddd38 100644
--- a/src/Entities/ent.cs
+++ b/src/Entities/ent.cs
@@ -1,5 +1,6 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+using UnityEngine.Rendering;
namespace DCFApixels.DragonECS
{
diff --git a/src/TestPool.cs b/src/TestPool.cs
new file mode 100644
index 0000000..a34ae1a
--- /dev/null
+++ b/src/TestPool.cs
@@ -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()
+ {
+ 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
+ {
+ private PoolToken _token;
+ public TestPool(TestWorld world)
+ {
+ _token = world.RegisterPool();
+ }
+ }
+}