mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 18:14:37 +08:00
update
This commit is contained in:
parent
5243218b73
commit
eeb1620c22
@ -28,7 +28,7 @@
|
||||
public void PreInit(EcsPipeline pipeline)
|
||||
{
|
||||
#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())
|
||||
targets[i].PreInit(pipeline);
|
||||
@ -57,7 +57,7 @@
|
||||
public void Init(EcsPipeline pipeline)
|
||||
{
|
||||
#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())
|
||||
targets[i].Init(pipeline);
|
||||
@ -86,7 +86,7 @@
|
||||
public void Run(EcsPipeline pipeline)
|
||||
{
|
||||
#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())
|
||||
targets[i].Run(pipeline);
|
||||
@ -116,7 +116,7 @@
|
||||
public void Destroy(EcsPipeline pipeline)
|
||||
{
|
||||
#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())
|
||||
targets[i].Destroy(pipeline);
|
||||
|
@ -11,13 +11,17 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
private readonly EcsGroup _source;
|
||||
|
||||
|
||||
#region Constructors
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public EcsReadonlyGroup(EcsGroup source) => _source = source;
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
public IEcsWorld World
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => _source.World;
|
||||
}
|
||||
public int Count
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@ -61,6 +65,7 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
_source.World.ReleaseGroup(_source);
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal EcsGroup GetGroupInternal() => _source;
|
||||
|
||||
#endregion
|
||||
@ -72,8 +77,8 @@ namespace DCFApixels.DragonECS
|
||||
// this collection can only store numbers greater than 0
|
||||
public class EcsGroup
|
||||
{
|
||||
public const int DEALAYED_ADD = 0;
|
||||
public const int DEALAYED_REMOVE = int.MinValue;
|
||||
private const int DEALAYED_ADD = 0;
|
||||
private const int DEALAYED_REMOVE = int.MinValue;
|
||||
|
||||
private IEcsWorld _source;
|
||||
|
||||
@ -226,6 +231,7 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
#endregion
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal void OnWorldResize(int newSize)
|
||||
{
|
||||
Array.Resize(ref _sparse, newSize);
|
||||
@ -243,12 +249,22 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
}
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Clear() => _count = 0;
|
||||
|
||||
public void CopyFrom(EcsGroup group)
|
||||
{
|
||||
#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
|
||||
Clear();
|
||||
foreach (var item in group)
|
||||
@ -260,7 +276,17 @@ namespace DCFApixels.DragonECS
|
||||
public void AddGroup(EcsGroup group)
|
||||
{
|
||||
#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
|
||||
foreach (var item in group)
|
||||
if (!Contains(item.id))
|
||||
@ -270,7 +296,17 @@ namespace DCFApixels.DragonECS
|
||||
public void RemoveGroup(EcsGroup group)
|
||||
{
|
||||
#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
|
||||
foreach (var item in group)
|
||||
if (Contains(item.id))
|
||||
@ -280,17 +316,39 @@ namespace DCFApixels.DragonECS
|
||||
public void AndWith(EcsGroup group)
|
||||
{
|
||||
#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
|
||||
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);
|
||||
}
|
||||
/// <summary>as Symmetric Except sets</summary>
|
||||
public void XorWith(EcsGroup group)
|
||||
{
|
||||
#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
|
||||
foreach (var item in group)
|
||||
if (Contains(item.id))
|
||||
@ -316,9 +374,9 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
delayedOp op = _delayedOps[i];
|
||||
if (op >= 0) //delayedOp.IsAdded
|
||||
UncheckedAdd(op & int.MaxValue); //delayedOp.EcsEntity
|
||||
AggressiveAdd(op & int.MaxValue); //delayedOp.EcsEntity
|
||||
else
|
||||
UncheckedRemove(op & int.MaxValue); //delayedOp.EcsEntity
|
||||
AggressiveRemove(op & int.MaxValue); //delayedOp.EcsEntity
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -332,7 +390,7 @@ namespace DCFApixels.DragonECS
|
||||
#endregion
|
||||
|
||||
#region Enumerator
|
||||
public ref struct Enumerator
|
||||
public struct Enumerator : IDisposable
|
||||
{
|
||||
private readonly EcsGroup _source;
|
||||
private readonly int[] _dense;
|
||||
@ -359,7 +417,7 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region OObject
|
||||
#region Object
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Join(", ", _dense.AsSpan(1, _count).ToArray());
|
||||
|
@ -294,6 +294,10 @@ namespace DCFApixels.DragonECS
|
||||
internal Type WorldArchetypeType;
|
||||
internal int[] Inc;
|
||||
internal int[] Exc;
|
||||
public override string ToString()
|
||||
{
|
||||
return $"Inc({string.Join(", ", Inc)}) Exc({string.Join(", ", Exc)})";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Unity.Profiling;
|
||||
using UnityEngine;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
@ -9,6 +10,7 @@ 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);
|
||||
@ -23,7 +25,7 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
|
||||
public struct NullComponent { }
|
||||
public sealed class EcsNullPool : IEcsPool<NullComponent>
|
||||
public sealed class EcsNullPool : EcsPool, IEcsPool<NullComponent>
|
||||
{
|
||||
public static EcsNullPool instance => new EcsNullPool(null);
|
||||
private readonly IEcsWorld _source;
|
||||
@ -32,17 +34,24 @@ 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) { }
|
||||
public bool Has(int index) => false;
|
||||
public override bool Has(int index) => false;
|
||||
void IEcsPool.Write(int entityID) { }
|
||||
public ref readonly NullComponent Read(int entity) => ref fakeComponent;
|
||||
public ref NullComponent Write(int entity) => ref fakeComponent;
|
||||
void IEcsPool.OnWorldResize(int newSize) { }
|
||||
internal override void OnWorldResize(int newSize) { }
|
||||
}
|
||||
|
||||
public sealed class EcsPool<T> : IEcsPool<T>
|
||||
public abstract class EcsPool
|
||||
{
|
||||
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
|
||||
{
|
||||
private readonly int _componentID;
|
||||
@ -55,10 +64,9 @@ namespace DCFApixels.DragonECS
|
||||
private int _recycledItemsCount;
|
||||
|
||||
private IEcsComponentReset<T> _componentResetHandler;
|
||||
|
||||
private PoolRunnres _poolRunnres;
|
||||
|
||||
#region Properites
|
||||
public EcsReadonlyGroup Entities => entities.Readonly;
|
||||
public int Count => _itemsCount;
|
||||
public int Capacity => _items.Length;
|
||||
public IEcsWorld World => _source;
|
||||
@ -69,6 +77,7 @@ namespace DCFApixels.DragonECS
|
||||
#region Constructors
|
||||
internal EcsPool(IEcsWorld source, int id, int capacity, PoolRunnres poolRunnres)
|
||||
{
|
||||
entities = new EcsGroup(source);
|
||||
_source = source;
|
||||
_componentID = id;
|
||||
|
||||
@ -84,62 +93,69 @@ namespace DCFApixels.DragonECS
|
||||
#endregion
|
||||
|
||||
#region Write/Read/Has/Del
|
||||
private ProfilerMarker _addMark = new ProfilerMarker("EcsPoo.Add");
|
||||
private ProfilerMarker _writeMark = new ProfilerMarker("EcsPoo.Write");
|
||||
private ProfilerMarker _readMark = new ProfilerMarker("EcsPoo.Read");
|
||||
private ProfilerMarker _hasMark = new ProfilerMarker("EcsPoo.Has");
|
||||
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)
|
||||
{
|
||||
// using (_writeMark.Auto())
|
||||
// {
|
||||
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];
|
||||
// }
|
||||
using (_writeMark.Auto())
|
||||
return ref _items[_mapping[entityID]];
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ref readonly T Read(int entityID)
|
||||
{
|
||||
// using (_readMark.Auto())
|
||||
using (_readMark.Auto())
|
||||
return ref _items[_mapping[entityID]];
|
||||
}
|
||||
[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;
|
||||
}
|
||||
public void Del(int entityID)
|
||||
{
|
||||
//using (_delMark.Auto())
|
||||
// {
|
||||
using (_delMark.Auto())
|
||||
{
|
||||
entities.Remove(entityID);
|
||||
|
||||
if (_recycledItemsCount >= _recycledItems.Length)
|
||||
Array.Resize(ref _recycledItems, _recycledItems.Length << 1);
|
||||
_recycledItems[_recycledItemsCount++] = _mapping[entityID];
|
||||
_mapping[entityID] = 0;
|
||||
_itemsCount--;
|
||||
_source.OnEntityComponentRemoved(entityID, _componentID);
|
||||
_poolRunnres.del.OnComponentDel<T>(entityID);
|
||||
// }
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -156,10 +172,16 @@ namespace DCFApixels.DragonECS
|
||||
#endregion
|
||||
|
||||
#region Internal
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
void IEcsPool.OnWorldResize(int newSize)
|
||||
{
|
||||
Array.Resize(ref _mapping, newSize);
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal sealed override void OnWorldResize(int newSize)
|
||||
{
|
||||
Array.Resize(ref _mapping, newSize);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -2,33 +2,53 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Unity.Profiling;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public abstract class EcsQueryBase
|
||||
{
|
||||
internal EcsGroup group;
|
||||
internal EcsGroup groupFilter;
|
||||
internal EcsQueryMask mask;
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal void AddEntity(int entityID) => group.Add(entityID);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal void RemoveEntity(int entityID) => group.Remove(entityID);
|
||||
public IEcsWorld World => groupFilter.World;
|
||||
}
|
||||
|
||||
public abstract class EcsQuery<TWorldArchetype> : EcsQueryBase
|
||||
where TWorldArchetype : EcsWorld<TWorldArchetype>
|
||||
{
|
||||
private int _id;
|
||||
|
||||
public int ID => _id;
|
||||
public EcsReadonlyGroup entities
|
||||
private ProfilerMarker _getEnumerator = new ProfilerMarker("EcsQuery.GetEnumerator");
|
||||
|
||||
public EcsGroup.Enumerator GetEnumerator()
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => group.Readonly;
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
public EcsGroup.Enumerator GetEnumerator() => group.GetEnumerator();
|
||||
|
||||
protected virtual void Init(Builder b) { }
|
||||
|
||||
#region Builder
|
||||
@ -56,7 +76,7 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
|
||||
builder.End(out newQuery.mask);
|
||||
newQuery.group = new EcsGroup(world);
|
||||
newQuery.groupFilter = new EcsGroup(world);
|
||||
return (TQuery)(object)newQuery;
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ namespace DCFApixels.DragonECS
|
||||
public interface IEcsQueryMember<TComponent>
|
||||
where TComponent : struct
|
||||
{
|
||||
public ref TComponent Add(ent entityID);
|
||||
public ref TComponent Write(ent entityID);
|
||||
public ref readonly TComponent Read(ent entityID);
|
||||
public bool Has(ent entityID);
|
||||
@ -22,6 +23,8 @@ namespace DCFApixels.DragonECS
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal inc(EcsPool<TComponent> pool) => _pool = pool;
|
||||
[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);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ref readonly TComponent Read(ent entityID) => ref _pool.Read(entityID.id);
|
||||
@ -44,6 +47,8 @@ namespace DCFApixels.DragonECS
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal exc(EcsPool<TComponent> pool) => _pool = pool;
|
||||
[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);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ref readonly TComponent Read(ent entityID) => ref _pool.Read(entityID.id);
|
||||
@ -66,6 +71,8 @@ namespace DCFApixels.DragonECS
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal opt(EcsPool<TComponent> pool) => _pool = pool;
|
||||
[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);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ref readonly TComponent Read(ent entityID) => ref _pool.Read(entityID.id);
|
||||
|
127
src/EcsWorld.cs
127
src/EcsWorld.cs
@ -14,6 +14,7 @@ namespace DCFApixels.DragonECS
|
||||
public EcsPipeline Pipeline { get; }
|
||||
public int EntitesCount { get; }
|
||||
public int EntitesCapacity { get; }
|
||||
public EcsReadonlyGroup Entities => default;
|
||||
#endregion
|
||||
|
||||
#region Entities
|
||||
@ -67,12 +68,11 @@ namespace DCFApixels.DragonECS
|
||||
private int _entitiesCount;
|
||||
private short[] _gens; //старший бит указывает на то жива ли сущьность.
|
||||
|
||||
//private short[] _componentCounts; //TODO
|
||||
private IEcsPool[] _pools;
|
||||
private EcsNullPool _nullPool;
|
||||
private EcsGroup _allEntites;
|
||||
|
||||
private List<EcsQueryBase>[] _filtersByIncludedComponents;
|
||||
private List<EcsQueryBase>[] _filtersByExcludedComponents;
|
||||
//private short[] _componentCounts; //TODO
|
||||
private EcsPool[] _pools;
|
||||
private EcsNullPool _nullPool;
|
||||
|
||||
private EcsQueryBase[] _queries;
|
||||
|
||||
@ -109,7 +109,7 @@ namespace DCFApixels.DragonECS
|
||||
#endregion
|
||||
|
||||
#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;
|
||||
|
||||
#endregion
|
||||
@ -126,6 +126,7 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
public int EntitesCount => _entitiesCount;
|
||||
public int EntitesCapacity => _denseEntities.Length;
|
||||
public EcsReadonlyGroup Entities => _allEntites.Readonly;
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
@ -135,7 +136,7 @@ namespace DCFApixels.DragonECS
|
||||
if (!_pipeline.IsInit) pipline.Init();
|
||||
_entityDispenser = new IntDispenser(0);
|
||||
_nullPool = EcsNullPool.instance;
|
||||
_pools = new IEcsPool[512];
|
||||
_pools = new EcsPool[512];
|
||||
ArrayUtility.Fill(_pools, _nullPool);
|
||||
|
||||
_gens = new short[512];
|
||||
@ -144,15 +145,14 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
_denseEntities = new int[512];
|
||||
|
||||
_filtersByIncludedComponents = new List<EcsQueryBase>[16];
|
||||
_filtersByExcludedComponents = new List<EcsQueryBase>[16];
|
||||
|
||||
_poolRunnres = new PoolRunnres(_pipeline);
|
||||
_entityCreate = _pipeline.GetRunner<IEcsEntityCreate>();
|
||||
_entityDestry = _pipeline.GetRunner<IEcsEntityDestroy>();
|
||||
_pipeline.GetRunner<IEcsInject<TWorldArchetype>>().Inject((TWorldArchetype)this);
|
||||
_pipeline.GetRunner<IEcsInject<IEcsWorld>>().Inject(this);
|
||||
_pipeline.GetRunner<IEcsWorldCreate>().OnWorldCreate(this);
|
||||
|
||||
_allEntites = new EcsGroup(this);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -166,9 +166,6 @@ namespace DCFApixels.DragonECS
|
||||
int oldCapacity = _pools.Length;
|
||||
Array.Resize(ref _pools, ComponentType.Capacity);
|
||||
ArrayUtility.Fill(_pools, _nullPool, oldCapacity, oldCapacity - _pools.Length);
|
||||
|
||||
Array.Resize(ref _filtersByIncludedComponents, ComponentType.Capacity);
|
||||
Array.Resize(ref _filtersByExcludedComponents, ComponentType.Capacity);
|
||||
}
|
||||
|
||||
if (_pools[uniqueID] == _nullPool)
|
||||
@ -190,39 +187,6 @@ namespace DCFApixels.DragonECS
|
||||
if (_queries[uniqueID] == null)
|
||||
{
|
||||
_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];
|
||||
return query;
|
||||
@ -282,71 +246,6 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
#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
|
||||
public EcsEntity NewEntity()
|
||||
{
|
||||
@ -366,10 +265,12 @@ namespace DCFApixels.DragonECS
|
||||
_gens[entityID] |= short.MinValue;
|
||||
EcsEntity entity = new EcsEntity(entityID, _gens[entityID]++, id);
|
||||
_entityCreate.OnEntityCreate(entity);
|
||||
_allEntites.Add(entityID);
|
||||
return entity;
|
||||
}
|
||||
public void DelEntity(EcsEntity entity)
|
||||
{
|
||||
_allEntites.Remove(entity.id);
|
||||
_entityDispenser.Release(entity.id);
|
||||
_gens[entity.id] |= short.MinValue;
|
||||
_entitiesCount--;
|
||||
@ -396,8 +297,6 @@ namespace DCFApixels.DragonECS
|
||||
_gens = null;
|
||||
_pools = null;
|
||||
_nullPool = null;
|
||||
_filtersByIncludedComponents = null;
|
||||
_filtersByExcludedComponents = null;
|
||||
_queries = null;
|
||||
Realeze();
|
||||
}
|
||||
@ -476,7 +375,7 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||
if (group.World != this)
|
||||
throw new ArgumentException("group.World != this");
|
||||
throw new ArgumentException("groupFilter.World != this");
|
||||
#endif
|
||||
group.Clear();
|
||||
_pool.Push(group);
|
||||
|
@ -97,6 +97,12 @@ namespace DCFApixels.DragonECS
|
||||
//using (_ReadMarker.Auto())
|
||||
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>()
|
||||
where T : struct
|
||||
{
|
||||
|
@ -6,7 +6,7 @@ namespace DCFApixels.DragonECS
|
||||
#pragma warning disable CS0660, CS0661
|
||||
/// <summary>Single frame entity identifier</summary>
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4, Size = 4)]
|
||||
public readonly ref partial struct ent
|
||||
public readonly ref struct ent
|
||||
{
|
||||
internal readonly int id;
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
|
@ -14,7 +14,7 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
#region Methods
|
||||
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 int GetComponentID<T>();
|
||||
@ -24,8 +24,6 @@ namespace DCFApixels.DragonECS
|
||||
#endregion
|
||||
|
||||
#region Internal Methods
|
||||
internal void OnEntityComponentAdded(int entityID, int componentID);
|
||||
internal void OnEntityComponentRemoved(int entityID, int componentID);
|
||||
internal void RegisterGroup(EcsGroup group);
|
||||
#endregion
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user