This commit is contained in:
Mikhail 2023-04-09 02:52:39 +08:00
parent 5243218b73
commit eeb1620c22
10 changed files with 200 additions and 186 deletions

View File

@ -28,7 +28,7 @@
public void PreInit(EcsPipeline pipeline) public void PreInit(EcsPipeline pipeline)
{ {
#if DEBUG && !DISABLE_DEBUG #if DEBUG && !DISABLE_DEBUG
for (int i = 0; i < targets.Length; i++) for (int i = 0; i < targets.Length && targets.Length <= _markers.Length; i++)
{ {
using (_markers[i].Auto()) using (_markers[i].Auto())
targets[i].PreInit(pipeline); targets[i].PreInit(pipeline);
@ -57,7 +57,7 @@
public void Init(EcsPipeline pipeline) public void Init(EcsPipeline pipeline)
{ {
#if DEBUG && !DISABLE_DEBUG #if DEBUG && !DISABLE_DEBUG
for (int i = 0; i < targets.Length; i++) for (int i = 0; i < targets.Length && targets.Length <= _markers.Length; i++)
{ {
using (_markers[i].Auto()) using (_markers[i].Auto())
targets[i].Init(pipeline); targets[i].Init(pipeline);
@ -86,7 +86,7 @@
public void Run(EcsPipeline pipeline) public void Run(EcsPipeline pipeline)
{ {
#if DEBUG && !DISABLE_DEBUG #if DEBUG && !DISABLE_DEBUG
for (int i = 0; i < targets.Length; i++) for (int i = 0; i < targets.Length && targets.Length <= _markers.Length; i++)
{ {
using (_markers[i].Auto()) using (_markers[i].Auto())
targets[i].Run(pipeline); targets[i].Run(pipeline);
@ -116,7 +116,7 @@
public void Destroy(EcsPipeline pipeline) public void Destroy(EcsPipeline pipeline)
{ {
#if DEBUG && !DISABLE_DEBUG #if DEBUG && !DISABLE_DEBUG
for (int i = 0; i < targets.Length; i++) for (int i = 0; i < targets.Length && targets.Length <= _markers.Length; i++)
{ {
using (_markers[i].Auto()) using (_markers[i].Auto())
targets[i].Destroy(pipeline); targets[i].Destroy(pipeline);

View File

@ -11,13 +11,17 @@ namespace DCFApixels.DragonECS
{ {
private readonly EcsGroup _source; private readonly EcsGroup _source;
#region Constructors #region Constructors
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsReadonlyGroup(EcsGroup source) => _source = source; public EcsReadonlyGroup(EcsGroup source) => _source = source;
#endregion #endregion
#region Properties #region Properties
public IEcsWorld World
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _source.World;
}
public int Count public int Count
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -61,6 +65,7 @@ namespace DCFApixels.DragonECS
{ {
_source.World.ReleaseGroup(_source); _source.World.ReleaseGroup(_source);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal EcsGroup GetGroupInternal() => _source; internal EcsGroup GetGroupInternal() => _source;
#endregion #endregion
@ -72,8 +77,8 @@ namespace DCFApixels.DragonECS
// this collection can only store numbers greater than 0 // this collection can only store numbers greater than 0
public class EcsGroup public class EcsGroup
{ {
public const int DEALAYED_ADD = 0; private const int DEALAYED_ADD = 0;
public const int DEALAYED_REMOVE = int.MinValue; private const int DEALAYED_REMOVE = int.MinValue;
private IEcsWorld _source; private IEcsWorld _source;
@ -226,6 +231,7 @@ namespace DCFApixels.DragonECS
} }
#endregion #endregion
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void OnWorldResize(int newSize) internal void OnWorldResize(int newSize)
{ {
Array.Resize(ref _sparse, newSize); Array.Resize(ref _sparse, newSize);
@ -243,12 +249,22 @@ namespace DCFApixels.DragonECS
} }
} }
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Clear() => _count = 0; public void Clear() => _count = 0;
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
if (group.World != _source) throw new ArgumentException("group.World != World"); if (group.World != _source) throw new ArgumentException("groupFilter.World != World");
#endif
Clear();
foreach (var item in group)
AggressiveAdd(item.id);
}
public void CopyFrom(EcsReadonlyGroup group)
{
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
if (group.World != _source) throw new ArgumentException("groupFilter.World != World");
#endif #endif
Clear(); Clear();
foreach (var item in group) foreach (var item in group)
@ -260,7 +276,17 @@ namespace DCFApixels.DragonECS
public void AddGroup(EcsGroup group) public void AddGroup(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 != group.World"); 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>
public void AddGroup(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))
@ -270,7 +296,17 @@ namespace DCFApixels.DragonECS
public void RemoveGroup(EcsGroup group) public void RemoveGroup(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 != group.World"); 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 Except sets</summary>
public void RemoveGroup(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))
@ -280,17 +316,39 @@ namespace DCFApixels.DragonECS
public void AndWith(EcsGroup group) public void AndWith(EcsGroup group)
{ {
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS #if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
if (World != group.World) throw new ArgumentException("World != group.World"); if (World != group.World) throw new ArgumentException("World != groupFilter.World");
#endif #endif
foreach (var item in this) foreach (var item in this)
if (group.Contains(item.id)) if (!group.Contains(item.id))
AggressiveRemove(item.id);
}
/// <summary>as Intersect sets</summary>
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); 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 != group.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))
@ -316,9 +374,9 @@ namespace DCFApixels.DragonECS
{ {
delayedOp op = _delayedOps[i]; delayedOp op = _delayedOps[i];
if (op >= 0) //delayedOp.IsAdded if (op >= 0) //delayedOp.IsAdded
UncheckedAdd(op & int.MaxValue); //delayedOp.EcsEntity AggressiveAdd(op & int.MaxValue); //delayedOp.EcsEntity
else else
UncheckedRemove(op & int.MaxValue); //delayedOp.EcsEntity AggressiveRemove(op & int.MaxValue); //delayedOp.EcsEntity
} }
} }
} }
@ -332,7 +390,7 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region Enumerator #region Enumerator
public ref struct Enumerator public struct Enumerator : IDisposable
{ {
private readonly EcsGroup _source; private readonly EcsGroup _source;
private readonly int[] _dense; private readonly int[] _dense;
@ -359,7 +417,7 @@ namespace DCFApixels.DragonECS
} }
#endregion #endregion
#region OObject #region Object
public override string ToString() public override string ToString()
{ {
return string.Join(", ", _dense.AsSpan(1, _count).ToArray()); return string.Join(", ", _dense.AsSpan(1, _count).ToArray());

View File

@ -294,6 +294,10 @@ namespace DCFApixels.DragonECS
internal Type WorldArchetypeType; internal Type WorldArchetypeType;
internal int[] Inc; internal int[] Inc;
internal int[] Exc; internal int[] Exc;
public override string ToString()
{
return $"Inc({string.Join(", ", Inc)}) Exc({string.Join(", ", Exc)})";
}
} }

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using Unity.Profiling; using Unity.Profiling;
using UnityEngine;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
@ -9,6 +10,7 @@ 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);
@ -23,7 +25,7 @@ namespace DCFApixels.DragonECS
} }
public struct NullComponent { } public struct NullComponent { }
public sealed class EcsNullPool : IEcsPool<NullComponent> public sealed class EcsNullPool : EcsPool, IEcsPool<NullComponent>
{ {
public static EcsNullPool instance => new EcsNullPool(null); public static EcsNullPool instance => new EcsNullPool(null);
private readonly IEcsWorld _source; private readonly IEcsWorld _source;
@ -32,17 +34,24 @@ 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) { }
public bool Has(int index) => false; public override bool Has(int index) => false;
void IEcsPool.Write(int entityID) { } void IEcsPool.Write(int entityID) { }
public ref readonly NullComponent Read(int entity) => ref fakeComponent; public ref readonly NullComponent Read(int entity) => ref fakeComponent;
public ref NullComponent Write(int entity) => ref fakeComponent; public ref NullComponent Write(int entity) => ref fakeComponent;
void IEcsPool.OnWorldResize(int newSize) { } void IEcsPool.OnWorldResize(int newSize) { }
internal override void OnWorldResize(int newSize) { }
} }
public abstract class EcsPool
public sealed class EcsPool<T> : IEcsPool<T> {
internal EcsGroup entities;
public abstract bool Has(int entityID);
internal abstract void OnWorldResize(int newSize);
}
public sealed class EcsPool<T> : EcsPool, IEcsPool<T>
where T : struct where T : struct
{ {
private readonly int _componentID; private readonly int _componentID;
@ -55,10 +64,9 @@ namespace DCFApixels.DragonECS
private int _recycledItemsCount; private int _recycledItemsCount;
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;
@ -69,6 +77,7 @@ 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;
@ -84,62 +93,69 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region Write/Read/Has/Del #region Write/Read/Has/Del
private ProfilerMarker _addMark = new ProfilerMarker("EcsPoo.Add");
private ProfilerMarker _writeMark = new ProfilerMarker("EcsPoo.Write"); private ProfilerMarker _writeMark = new ProfilerMarker("EcsPoo.Write");
private ProfilerMarker _readMark = new ProfilerMarker("EcsPoo.Read"); private ProfilerMarker _readMark = new ProfilerMarker("EcsPoo.Read");
private ProfilerMarker _hasMark = new ProfilerMarker("EcsPoo.Has"); private ProfilerMarker _hasMark = new ProfilerMarker("EcsPoo.Has");
private ProfilerMarker _delMark = new ProfilerMarker("EcsPoo.Del"); private ProfilerMarker _delMark = new ProfilerMarker("EcsPoo.Del");
public ref T Add(int entityID)
{
using (_addMark.Auto())
{
ref int itemIndex = ref _mapping[entityID];
if (itemIndex <= 0)
{
entities.Add(entityID);
if (_recycledItemsCount > 0)
{
itemIndex = _recycledItems[--_recycledItemsCount];
_itemsCount++;
}
else
{
itemIndex = ++_itemsCount;
if (itemIndex >= _items.Length)
Array.Resize(ref _items, _items.Length << 1);
}
_mapping[entityID] = itemIndex;
_componentResetHandler.Reset(ref _items[itemIndex]);
_poolRunnres.add.OnComponentAdd<T>(entityID);
}
_poolRunnres.write.OnComponentWrite<T>(entityID);
return ref _items[itemIndex];
}
}
public ref T Write(int entityID) public ref T Write(int entityID)
{ {
// using (_writeMark.Auto()) using (_writeMark.Auto())
// { return ref _items[_mapping[entityID]];
ref int itemIndex = ref _mapping[entityID];
if (itemIndex <= 0) //åñëè 0 òî íàäî äîáàâèòü
{
if (_recycledItemsCount > 0)
{
itemIndex = _recycledItems[--_recycledItemsCount];
_itemsCount++;
}
else
{
itemIndex = _itemsCount++;
if (itemIndex >= _items.Length)
Array.Resize(ref _items, _items.Length << 1);
}
_mapping[entityID] = itemIndex;
_componentResetHandler.Reset(ref _items[itemIndex]);
_source.OnEntityComponentAdded(entityID, _componentID);
_poolRunnres.add.OnComponentAdd<T>(entityID);
}
_poolRunnres.write.OnComponentWrite<T>(entityID);
return ref _items[itemIndex];
// }
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref readonly T Read(int entityID) public ref readonly T Read(int entityID)
{ {
// using (_readMark.Auto()) using (_readMark.Auto())
return ref _items[_mapping[entityID]]; return ref _items[_mapping[entityID]];
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Has(int entityID) public sealed override bool Has(int entityID)
{ {
// using (_hasMark.Auto()) using (_hasMark.Auto())
return _mapping[entityID] > 0; return _mapping[entityID] > 0;
} }
public void Del(int entityID) public void Del(int entityID)
{ {
//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];
_mapping[entityID] = 0; _mapping[entityID] = 0;
_itemsCount--; _itemsCount--;
_source.OnEntityComponentRemoved(entityID, _componentID);
_poolRunnres.del.OnComponentDel<T>(entityID); _poolRunnres.del.OnComponentDel<T>(entityID);
// } }
} }
#endregion #endregion
@ -156,10 +172,16 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region Internal #region Internal
[MethodImpl(MethodImplOptions.AggressiveInlining)]
void IEcsPool.OnWorldResize(int newSize) void IEcsPool.OnWorldResize(int newSize)
{ {
Array.Resize(ref _mapping, newSize); Array.Resize(ref _mapping, newSize);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal sealed override void OnWorldResize(int newSize)
{
Array.Resize(ref _mapping, newSize);
}
#endregion #endregion
} }
} }

View File

@ -2,33 +2,53 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using Unity.Profiling;
using UnityEngine;
using UnityEngine.UI;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
public abstract class EcsQueryBase public abstract class EcsQueryBase
{ {
internal EcsGroup group; internal EcsGroup groupFilter;
internal EcsQueryMask mask; internal EcsQueryMask mask;
[MethodImpl(MethodImplOptions.AggressiveInlining)] public IEcsWorld World => groupFilter.World;
internal void AddEntity(int entityID) => group.Add(entityID);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void RemoveEntity(int entityID) => group.Remove(entityID);
} }
public abstract class EcsQuery<TWorldArchetype> : EcsQueryBase public abstract class EcsQuery<TWorldArchetype> : EcsQueryBase
where TWorldArchetype : EcsWorld<TWorldArchetype> where TWorldArchetype : EcsWorld<TWorldArchetype>
{ {
private int _id; private int _id;
public int ID => _id; public int ID => _id;
public EcsReadonlyGroup entities private ProfilerMarker _getEnumerator = new ProfilerMarker("EcsQuery.GetEnumerator");
public EcsGroup.Enumerator GetEnumerator()
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] using (_getEnumerator.Auto())
get => group.Readonly; {
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();
}
} }
public EcsGroup.Enumerator GetEnumerator() => group.GetEnumerator();
protected virtual void Init(Builder b) { } protected virtual void Init(Builder b) { }
#region Builder #region Builder
@ -56,7 +76,7 @@ namespace DCFApixels.DragonECS
} }
builder.End(out newQuery.mask); builder.End(out newQuery.mask);
newQuery.group = new EcsGroup(world); newQuery.groupFilter = new EcsGroup(world);
return (TQuery)(object)newQuery; return (TQuery)(object)newQuery;
} }

View File

@ -8,6 +8,7 @@ namespace DCFApixels.DragonECS
public interface IEcsQueryMember<TComponent> public interface IEcsQueryMember<TComponent>
where TComponent : struct where TComponent : struct
{ {
public ref TComponent Add(ent entityID);
public ref TComponent Write(ent entityID); public ref TComponent Write(ent entityID);
public ref readonly TComponent Read(ent entityID); public ref readonly TComponent Read(ent entityID);
public bool Has(ent entityID); public bool Has(ent entityID);
@ -22,6 +23,8 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal inc(EcsPool<TComponent> pool) => _pool = pool; internal inc(EcsPool<TComponent> pool) => _pool = pool;
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref TComponent Add(ent entityID) => ref _pool.Add(entityID.id);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref TComponent Write(ent entityID) => ref _pool.Write(entityID.id); public ref TComponent Write(ent entityID) => ref _pool.Write(entityID.id);
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref readonly TComponent Read(ent entityID) => ref _pool.Read(entityID.id); public ref readonly TComponent Read(ent entityID) => ref _pool.Read(entityID.id);
@ -44,6 +47,8 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal exc(EcsPool<TComponent> pool) => _pool = pool; internal exc(EcsPool<TComponent> pool) => _pool = pool;
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref TComponent Add(ent entityID) => ref _pool.Add(entityID.id);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref TComponent Write(ent entityID) => ref _pool.Write(entityID.id); public ref TComponent Write(ent entityID) => ref _pool.Write(entityID.id);
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref readonly TComponent Read(ent entityID) => ref _pool.Read(entityID.id); public ref readonly TComponent Read(ent entityID) => ref _pool.Read(entityID.id);
@ -66,6 +71,8 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal opt(EcsPool<TComponent> pool) => _pool = pool; internal opt(EcsPool<TComponent> pool) => _pool = pool;
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref TComponent Add(ent entityID) => ref _pool.Add(entityID.id);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref TComponent Write(ent entityID) => ref _pool.Write(entityID.id); public ref TComponent Write(ent entityID) => ref _pool.Write(entityID.id);
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref readonly TComponent Read(ent entityID) => ref _pool.Read(entityID.id); public ref readonly TComponent Read(ent entityID) => ref _pool.Read(entityID.id);

View File

@ -14,6 +14,7 @@ namespace DCFApixels.DragonECS
public EcsPipeline Pipeline { get; } public EcsPipeline Pipeline { get; }
public int EntitesCount { get; } public int EntitesCount { get; }
public int EntitesCapacity { get; } public int EntitesCapacity { get; }
public EcsReadonlyGroup Entities => default;
#endregion #endregion
#region Entities #region Entities
@ -67,12 +68,11 @@ namespace DCFApixels.DragonECS
private int _entitiesCount; private int _entitiesCount;
private short[] _gens; //старший бит указывает на то жива ли сущьность. private short[] _gens; //старший бит указывает на то жива ли сущьность.
//private short[] _componentCounts; //TODO private EcsGroup _allEntites;
private IEcsPool[] _pools;
private EcsNullPool _nullPool;
private List<EcsQueryBase>[] _filtersByIncludedComponents; //private short[] _componentCounts; //TODO
private List<EcsQueryBase>[] _filtersByExcludedComponents; private EcsPool[] _pools;
private EcsNullPool _nullPool;
private EcsQueryBase[] _queries; private EcsQueryBase[] _queries;
@ -109,7 +109,7 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region GetterMethods #region GetterMethods
public ReadOnlySpan<IEcsPool> GetAllPools() => new ReadOnlySpan<IEcsPool>(_pools); public ReadOnlySpan<EcsPool> GetAllPools() => new ReadOnlySpan<EcsPool>(_pools);
public int GetComponentID<T>() => ComponentType<T>.uniqueID; public int GetComponentID<T>() => ComponentType<T>.uniqueID;
#endregion #endregion
@ -126,6 +126,7 @@ namespace DCFApixels.DragonECS
public int EntitesCount => _entitiesCount; public int EntitesCount => _entitiesCount;
public int EntitesCapacity => _denseEntities.Length; public int EntitesCapacity => _denseEntities.Length;
public EcsReadonlyGroup Entities => _allEntites.Readonly;
#endregion #endregion
#region Constructors #region Constructors
@ -135,7 +136,7 @@ namespace DCFApixels.DragonECS
if (!_pipeline.IsInit) pipline.Init(); if (!_pipeline.IsInit) pipline.Init();
_entityDispenser = new IntDispenser(0); _entityDispenser = new IntDispenser(0);
_nullPool = EcsNullPool.instance; _nullPool = EcsNullPool.instance;
_pools = new IEcsPool[512]; _pools = new EcsPool[512];
ArrayUtility.Fill(_pools, _nullPool); ArrayUtility.Fill(_pools, _nullPool);
_gens = new short[512]; _gens = new short[512];
@ -144,15 +145,14 @@ namespace DCFApixels.DragonECS
_denseEntities = new int[512]; _denseEntities = new int[512];
_filtersByIncludedComponents = new List<EcsQueryBase>[16];
_filtersByExcludedComponents = new List<EcsQueryBase>[16];
_poolRunnres = new PoolRunnres(_pipeline); _poolRunnres = new PoolRunnres(_pipeline);
_entityCreate = _pipeline.GetRunner<IEcsEntityCreate>(); _entityCreate = _pipeline.GetRunner<IEcsEntityCreate>();
_entityDestry = _pipeline.GetRunner<IEcsEntityDestroy>(); _entityDestry = _pipeline.GetRunner<IEcsEntityDestroy>();
_pipeline.GetRunner<IEcsInject<TWorldArchetype>>().Inject((TWorldArchetype)this); _pipeline.GetRunner<IEcsInject<TWorldArchetype>>().Inject((TWorldArchetype)this);
_pipeline.GetRunner<IEcsInject<IEcsWorld>>().Inject(this); _pipeline.GetRunner<IEcsInject<IEcsWorld>>().Inject(this);
_pipeline.GetRunner<IEcsWorldCreate>().OnWorldCreate(this); _pipeline.GetRunner<IEcsWorldCreate>().OnWorldCreate(this);
_allEntites = new EcsGroup(this);
} }
#endregion #endregion
@ -166,9 +166,6 @@ namespace DCFApixels.DragonECS
int oldCapacity = _pools.Length; int oldCapacity = _pools.Length;
Array.Resize(ref _pools, ComponentType.Capacity); Array.Resize(ref _pools, ComponentType.Capacity);
ArrayUtility.Fill(_pools, _nullPool, oldCapacity, oldCapacity - _pools.Length); ArrayUtility.Fill(_pools, _nullPool, oldCapacity, oldCapacity - _pools.Length);
Array.Resize(ref _filtersByIncludedComponents, ComponentType.Capacity);
Array.Resize(ref _filtersByExcludedComponents, ComponentType.Capacity);
} }
if (_pools[uniqueID] == _nullPool) if (_pools[uniqueID] == _nullPool)
@ -190,39 +187,6 @@ namespace DCFApixels.DragonECS
if (_queries[uniqueID] == null) if (_queries[uniqueID] == null)
{ {
_queries[uniqueID] = EcsQuery<TWorldArchetype>.Builder.Build<TQuery>(this); _queries[uniqueID] = EcsQuery<TWorldArchetype>.Builder.Build<TQuery>(this);
var mask = _queries[uniqueID].mask;
var filter = _queries[uniqueID];
for (int i = 0; i < mask.Inc.Length; i++)
{
int componentID = mask.Inc[i];
var list = _filtersByIncludedComponents[componentID];
if (list == null)
{
list = new List<EcsQueryBase>(8);
_filtersByIncludedComponents[componentID] = list;
}
list.Add(filter);
}
for (int i = 0; i < mask.Exc.Length; i++)
{
int componentID = mask.Exc[i];
var list = _filtersByExcludedComponents[componentID];
if (list == null)
{
list = new List<EcsQueryBase>(8);
_filtersByExcludedComponents[componentID] = list;
}
list.Add(filter);
}
// scan exist entities for compatibility with new filter.
for (int i = 0; i < _entitiesCount && _entitiesCount <= _denseEntities.Length; i++)
{
int entity = _denseEntities[i];
if (IsMaskCompatible(mask, entity))
filter.AddEntity(entity);
}
} }
query = (TQuery)_queries[uniqueID]; query = (TQuery)_queries[uniqueID];
return query; return query;
@ -282,71 +246,6 @@ namespace DCFApixels.DragonECS
} }
#endregion #endregion
#region EntityChangedReact
void IEcsReadonlyTable.OnEntityComponentAdded(int entityID, int componentID)
{
var includeList = _filtersByIncludedComponents[componentID];
var excludeList = _filtersByExcludedComponents[componentID];
if (includeList != null)
{
foreach (var filter in includeList)
{
if (IsMaskCompatible(filter.mask, entityID))
{
filter.AddEntity(entityID);
}
}
}
if (excludeList != null)
{
foreach (var filter in excludeList)
{
if (IsMaskCompatibleWithout(filter.mask, entityID, componentID))
{
filter.RemoveEntity(entityID);
}
}
}
//TODO провести стресс тест для варианта выши и закоментированного ниже
// if (includeList != null) foreach (var filter in includeList) filter.Add(entityID);
// if (excludeList != null) foreach (var filter in excludeList) filter.Remove(entityID);
}
void IEcsReadonlyTable.OnEntityComponentRemoved(int entityID, int componentID)
{
var includeList = _filtersByIncludedComponents[componentID];
var excludeList = _filtersByExcludedComponents[componentID];
if (includeList != null)
{
foreach (var filter in includeList)
{
if (IsMaskCompatible(filter.mask, entityID))
{
filter.RemoveEntity(entityID);
}
}
}
if (excludeList != null)
{
foreach (var filter in excludeList)
{
if (IsMaskCompatibleWithout(filter.mask, entityID, componentID))
{
filter.AddEntity(entityID);
}
}
}
//TODO провести стресс тест для варианта выши и закоментированного ниже
// if (includeList != null) foreach (var filter in includeList) filter.Remove(entityID);
// if (excludeList != null) foreach (var filter in excludeList) filter.Add(entityID);
}
#endregion
#region Entity #region Entity
public EcsEntity NewEntity() public EcsEntity NewEntity()
{ {
@ -366,10 +265,12 @@ namespace DCFApixels.DragonECS
_gens[entityID] |= short.MinValue; _gens[entityID] |= short.MinValue;
EcsEntity entity = new EcsEntity(entityID, _gens[entityID]++, id); EcsEntity entity = new EcsEntity(entityID, _gens[entityID]++, id);
_entityCreate.OnEntityCreate(entity); _entityCreate.OnEntityCreate(entity);
_allEntites.Add(entityID);
return entity; return entity;
} }
public void DelEntity(EcsEntity entity) public void DelEntity(EcsEntity entity)
{ {
_allEntites.Remove(entity.id);
_entityDispenser.Release(entity.id); _entityDispenser.Release(entity.id);
_gens[entity.id] |= short.MinValue; _gens[entity.id] |= short.MinValue;
_entitiesCount--; _entitiesCount--;
@ -396,8 +297,6 @@ namespace DCFApixels.DragonECS
_gens = null; _gens = null;
_pools = null; _pools = null;
_nullPool = null; _nullPool = null;
_filtersByIncludedComponents = null;
_filtersByExcludedComponents = null;
_queries = null; _queries = null;
Realeze(); Realeze();
} }
@ -476,7 +375,7 @@ namespace DCFApixels.DragonECS
{ {
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS #if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
if (group.World != this) if (group.World != this)
throw new ArgumentException("group.World != this"); throw new ArgumentException("groupFilter.World != this");
#endif #endif
group.Clear(); group.Clear();
_pool.Push(group); _pool.Push(group);

View File

@ -97,6 +97,12 @@ namespace DCFApixels.DragonECS
//using (_ReadMarker.Auto()) //using (_ReadMarker.Auto())
return ref EcsWorld.Worlds[world].GetPool<T>().Read(id); return ref EcsWorld.Worlds[world].GetPool<T>().Read(id);
} }
public ref T Add<T>()
where T : struct
{
return ref EcsWorld.Worlds[world].GetPool<T>().Add(id);
}
public ref T Write<T>() public ref T Write<T>()
where T : struct where T : struct
{ {

View File

@ -6,7 +6,7 @@ namespace DCFApixels.DragonECS
#pragma warning disable CS0660, CS0661 #pragma warning disable CS0660, CS0661
/// <summary>Single frame entity identifier</summary> /// <summary>Single frame entity identifier</summary>
[StructLayout(LayoutKind.Sequential, Pack = 4, Size = 4)] [StructLayout(LayoutKind.Sequential, Pack = 4, Size = 4)]
public readonly ref partial struct ent public readonly ref struct ent
{ {
internal readonly int id; internal readonly int id;
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]

View File

@ -14,7 +14,7 @@ namespace DCFApixels.DragonECS
#region Methods #region Methods
public EcsPool<T> GetPool<T>() where T : struct; public EcsPool<T> GetPool<T>() where T : struct;
public ReadOnlySpan<IEcsPool> GetAllPools(); public ReadOnlySpan<EcsPool> GetAllPools();
public TQuery Query<TQuery>(out TQuery query) where TQuery : EcsQueryBase; public TQuery Query<TQuery>(out TQuery query) where TQuery : EcsQueryBase;
public int GetComponentID<T>(); public int GetComponentID<T>();
@ -24,8 +24,6 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region Internal Methods #region Internal Methods
internal void OnEntityComponentAdded(int entityID, int componentID);
internal void OnEntityComponentRemoved(int entityID, int componentID);
internal void RegisterGroup(EcsGroup group); internal void RegisterGroup(EcsGroup group);
#endregion #endregion
} }