fix changes

This commit is contained in:
Mikhail 2023-04-18 19:35:42 +08:00
parent e7835a39d3
commit 13dfbe9e31
10 changed files with 91 additions and 172 deletions

View File

@ -7,18 +7,18 @@ namespace DCFApixels.DragonECS
/// Используется для реализации отношений. traget - это сущьность к которой крепится эта сущьность. other - это сущьность с которой traget образует связь
/// </summary>
[StructLayout(LayoutKind.Explicit, Pack = 8, Size = 16)]
public readonly struct Attach
public readonly struct Edge
{
[FieldOffset(0), MarshalAs(UnmanagedType.U8)]
public readonly EcsEntity target;
public readonly EcsEntity origin;
[FieldOffset(1), MarshalAs(UnmanagedType.U8)]
public readonly EcsEntity other;
/// <summary>alias for "target"</summary>
/// <summary>alias for "origin"</summary>
public EcsEntity left
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => target;
get => origin;
}
/// <summary>alias for "other"</summary>
public EcsEntity right

View File

@ -141,7 +141,7 @@ namespace DCFApixels.DragonECS
_source = world;
_source.RegisterGroup(this);
_dense = new int[denseCapacity];
_sparse = new int[world.EntitesCapacity];
_sparse = new int[world.Capacity];
_delayedOps = new delayedOp[delayedOpsCapacity];
@ -435,7 +435,7 @@ namespace DCFApixels.DragonECS
public ent Current
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => (ent)_dense[_index];
get => new ent(_dense[_index]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool MoveNext() => ++_index <= _count && _count<_dense.Length; // <= потму что отсчет начинается с индекса 1 //_count < _dense.Length дает среде понять что проверки на выход за границы не нужны

View File

@ -389,11 +389,11 @@ namespace DCFApixels.DragonECS
// return;
// }
//
// var id = _count++;
// var uniqueID = _count++;
// if (_count >= _capacity)
// _capacity <<= 1;
//
// instance = new EcsMask(typeof(TWorldArchetype), id, inc_, exc_);
// instance = new EcsMask(typeof(TWorldArchetype), uniqueID, inc_, exc_);
}
public readonly static EcsMask instance;

View File

@ -87,7 +87,7 @@ namespace DCFApixels.DragonECS
_source = source;
_componentID = id;
_mapping = new int[source.EntitesCapacity];
_mapping = new int[source.Capacity];
_recycledItems = new int[128];
_recycledItemsCount = 0;
_items = new T[capacity];

View File

@ -14,7 +14,7 @@ namespace DCFApixels.DragonECS
#region Builder
protected virtual void Init(Builder b) { }
protected abstract void OnBuilt();
protected abstract void OnBuildAfter();
public abstract void Execute();
public sealed class Builder : EcsQueryBuilderBase
{
@ -46,7 +46,7 @@ namespace DCFApixels.DragonECS
newQuery.groupFilter = EcsGroup.New(world);
newQuery.source = world;
builder.End(out newQuery.mask);
newQuery.OnBuilt();
newQuery.OnBuildAfter();
return (TQuery)(object)newQuery;
}
@ -80,12 +80,12 @@ namespace DCFApixels.DragonECS
public abstract class EcsJoinQuery : EcsQueryBase
{
private EcsPool<Attach> attachPool;
private EcsPool<Edge> attachPool;
private ProfilerMarker _getEnumerator = new ProfilerMarker("EcsQuery.Execute");
protected sealed override void OnBuilt()
protected sealed override void OnBuildAfter()
{
attachPool = World.GetPool<Attach>();
attachPool = World.GetPool<Edge>();
}
public sealed override void Execute()
{
@ -103,7 +103,7 @@ namespace DCFApixels.DragonECS
public abstract class EcsQuery : EcsQueryBase
{
private ProfilerMarker _getEnumerator = new ProfilerMarker("EcsQuery.Execute");
protected sealed override void OnBuilt() { }
protected sealed override void OnBuildAfter() { }
public sealed override void Execute()
{
using (_getEnumerator.Auto())

View File

@ -91,9 +91,9 @@ namespace DCFApixels.DragonECS
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// internal inc_readonly_(EcsPool<TComponent> pool) => this.pool = pool;
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public ref TComponent Read(ent entityID) => ref pool.Read(entityID.id);
// public ref TComponent Read(ent entityID) => ref pool.Read(entityID.uniqueID);
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public bool Has(ent entityID) => pool.Has(entityID.id);
// public bool Has(ent entityID) => pool.Has(entityID.uniqueID);
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
//
// public static implicit operator inc_readonly_<TComponent>(EcsQueryBuilderBase buider) => buider.Include<TComponent>();
@ -108,9 +108,9 @@ namespace DCFApixels.DragonECS
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// internal exc_readonly_(EcsPool<TComponent> pool) => this.pool = pool;
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public ref TComponent Read(ent entityID) => ref pool.Read(entityID.id);
// public ref TComponent Read(ent entityID) => ref pool.Read(entityID.uniqueID);
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public bool Has(ent entityID) => pool.Has(entityID.id);
// public bool Has(ent entityID) => pool.Has(entityID.uniqueID);
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
//
// public static implicit operator exc_readonly_<TComponent>(EcsQueryBuilderBase buider) => buider.Exclude<TComponent>();
@ -125,9 +125,9 @@ namespace DCFApixels.DragonECS
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// internal opt_readonly_(EcsPool<TComponent> pool) => this.pool = pool;
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public ref TComponent Read(ent entityID) => ref pool.Read(entityID.id);
// public ref TComponent Read(ent entityID) => ref pool.Read(entityID.uniqueID);
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public bool Has(ent entityID) => pool.Has(entityID.id);
// public bool Has(ent entityID) => pool.Has(entityID.uniqueID);
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
//
// public static implicit operator opt_readonly_<TComponent>(EcsQueryBuilderBase buider) => buider.Optional<TComponent>();
@ -137,24 +137,24 @@ namespace DCFApixels.DragonECS
//
// #region join
// [StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)]
// public readonly struct attach : IEcsQueryField<Attach>
// public readonly struct attach : IEcsQueryField<Edge>
// {
// internal readonly EcsPool<Attach> pool;
// internal readonly EcsPool<Edge> pool;
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// internal attach(EcsPool<Attach> pool) => this.pool = pool;
// internal attach(EcsPool<Edge> pool) => this.pool = pool;
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public ref Attach Add(ent entityID) => ref pool.Add(entityID.id);
// public ref Edge Add(ent entityID) => ref pool.Add(entityID.uniqueID);
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public ref Attach Write(ent entityID) => ref pool.Write(entityID.id);
// public ref Edge Write(ent entityID) => ref pool.Write(entityID.uniqueID);
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public ref Attach Read(ent entityID) => ref pool.Read(entityID.id);
// public ref Edge Read(ent entityID) => ref pool.Read(entityID.uniqueID);
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public bool Has(ent entityID) => pool.Has(entityID.id);
// public bool Has(ent entityID) => pool.Has(entityID.uniqueID);
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public void Del(ent entityID) => pool.Del(entityID.id);
// public void Del(ent entityID) => pool.Del(entityID.uniqueID);
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
// public static implicit operator attach(EcsQueryBuilderBase buider) => buider.Include<Attach>();
// public static implicit operator attach(inc_<Attach> o) => new attach(o.pool);
// public static implicit operator attach(EcsQueryBuilderBase buider) => buider.Include<Edge>();
// public static implicit operator attach(inc_<Edge> o) => new attach(o.pool);
// }
// #endregion
}

View File

@ -6,14 +6,11 @@ using System.Runtime.InteropServices;
namespace DCFApixels.DragonECS
{
public interface IEcsWorld : IEcsReadonlyTable
public interface IEcsWorld : IEcsTable
{
#region Properties
//private float _timeScale;//TODO реализовать собсвенныйтайм склей для разных миров
public int ID { get; }
public int UniqueID { get; }
public EcsPipeline Pipeline { get; }
public int EntitesCount { get; }
public int EntitesCapacity { get; }
public EcsReadonlyGroup Entities => default;
#endregion
@ -21,7 +18,7 @@ namespace DCFApixels.DragonECS
public EcsEntity NewEntity();
public void DelEntity(EcsEntity entity);
public bool EntityIsAlive(int entityID, short gen);
public EcsEntity GetEntity(int entityID);
public EcsEntity GetEcsEntity(int entityID);
public void Destroy();
#endregion
@ -36,41 +33,35 @@ namespace DCFApixels.DragonECS
public static IEcsWorld[] Worlds = new IEcsWorld[8];
private static IntDispenser _worldIdDispenser = new IntDispenser(0);
public readonly short id;
public readonly short uniqueID;
protected EcsWorld(bool isIndexable)
protected EcsWorld()
{
if(isIndexable == true)
{
id = (short)_worldIdDispenser.GetFree();
if (id >= Worlds.Length)
Array.Resize(ref Worlds, Worlds.Length << 1);
Worlds[id] = (IEcsWorld)this;
}
else
{
id = -1;
}
uniqueID = (short)_worldIdDispenser.GetFree();
if (uniqueID >= Worlds.Length)
Array.Resize(ref Worlds, Worlds.Length << 1);
Worlds[uniqueID] = (IEcsWorld)this;
}
protected void Realeze()
{
Worlds[id] = null;
_worldIdDispenser.Release(id);
Worlds[uniqueID] = null;
_worldIdDispenser.Release(uniqueID);
}
}
public abstract class EcsWorld<TWorldArchetype> : EcsWorld, IEcsWorld
where TWorldArchetype : EcsWorld<TWorldArchetype>
{
private readonly int _worldArchetypeID = ComponentIndexer.GetWorldId<TWorldArchetype>();
private IntDispenser _entityDispenser;
private int[] _denseEntities;
private int _entitiesCount;
private int _entitesCapacity;
private short[] _gens; //старший бит указывает на то жива ли сущьность.
private EcsGroup _allEntites;
//private short[] _componentCounts; //TODO
private EcsPool[] _pools;
private EcsNullPool _nullPool;
@ -79,36 +70,11 @@ namespace DCFApixels.DragonECS
private EcsPipeline _pipeline;
private List<WeakReference<EcsGroup>> _groups;
private Stack<EcsGroup> _groupsPool = new Stack<EcsGroup>(64);
public IEcsRealationTable[] _relationTables;
private readonly int _worldArchetypeID = ComponentIndexer.GetWorldId<TWorldArchetype>();
#region RelationTables
public IEcsRealationTable GetRelationTalbe<TWorldArhetype>(TWorldArhetype targetWorld)
where TWorldArhetype : EcsWorld<TWorldArhetype>
{
int targetID = targetWorld.ID;
if (targetID <= 0)
throw new ArgumentException("targetWorld.ID <= 0");
if(_relationTables.Length <= targetID)
Array.Resize(ref _relationTables, targetID + 8);
if (_relationTables[targetID] == null)
{
// _relationTables[targetID]= new EcsRelationTable
}
throw new NotImplementedException();
}
#endregion
#region RunnersCache
private PoolRunnres _poolRunnres;
private IEcsEntityCreate _entityCreate;
private IEcsEntityDestroy _entityDestry;
#endregion
#region GetterMethods
public ReadOnlySpan<EcsPool> GetAllPools() => new ReadOnlySpan<EcsPool>(_pools);
@ -116,25 +82,18 @@ namespace DCFApixels.DragonECS
#endregion
#region Internal Properties
int IEcsReadonlyTable.Count => _entitiesCount;
int IEcsReadonlyTable.Capacity => _denseEntities.Length;
#endregion
#region Properties
public Type ArchetypeType => typeof(TWorldArchetype);
public int ID => id;
public int UniqueID => uniqueID;
public int Count => _entitiesCount;
public int Capacity => _entitesCapacity; //_denseEntities.Length;
public EcsPipeline Pipeline => _pipeline;
public int EntitesCount => _entitiesCount;
public int EntitesCapacity => _denseEntities.Length;
public EcsReadonlyGroup Entities => _allEntites.Readonly;
#endregion
#region Constructors
public EcsWorld(EcsPipeline pipline = null) : this(pipline, true) { }
internal EcsWorld(EcsPipeline pipline, bool isIndexable) : base(isIndexable)
{
public EcsWorld(EcsPipeline pipline = null)
{
_pipeline = pipline ?? EcsPipeline.Empty;
if (!_pipeline.IsInit) pipline.Init();
_entityDispenser = new IntDispenser(0);
@ -143,11 +102,11 @@ namespace DCFApixels.DragonECS
ArrayUtility.Fill(_pools, _nullPool);
_gens = new short[512];
_entitesCapacity = _gens.Length;
_queries = new EcsQuery[QueryType.capacity];
_groups = new List<WeakReference<EcsGroup>>();
_denseEntities = new int[512];
_poolRunnres = new PoolRunnres(_pipeline);
_entityCreate = _pipeline.GetRunner<IEcsEntityCreate>();
_entityDestry = _pipeline.GetRunner<IEcsEntityDestroy>();
@ -162,7 +121,6 @@ namespace DCFApixels.DragonECS
#region GetPool
public EcsPool<T> GetPool<T>() where T : struct
{
//int uniqueID = ComponentType<T>.uniqueID;
int uniqueID = ComponentIndexer.GetComponentId<T>(_worldArchetypeID);
if (uniqueID >= _pools.Length)
@ -178,7 +136,6 @@ namespace DCFApixels.DragonECS
}
return (EcsPool<T>)_pools[uniqueID];
}
//public EcsPool<T> UncheckedGetPool<T>() where T : struct => (EcsPool<T>)_pools[ComponentType<T>.uniqueID];
#endregion
#region Query
@ -225,13 +182,12 @@ namespace DCFApixels.DragonECS
public EcsEntity NewEntity()
{
int entityID = _entityDispenser.GetFree();
if (_entityDispenser.LastInt >= _denseEntities.Length)
Array.Resize(ref _denseEntities, _denseEntities.Length << 1);
_denseEntities[_entitiesCount++] = entityID;
_entitiesCount++;
if (_gens.Length <= entityID)
{
Array.Resize(ref _gens, _gens.Length << 1);
_entitesCapacity = _gens.Length;
for (int i = 0; i < _groups.Count; i++)
{
if (_groups[i].TryGetTarget(out EcsGroup group))
@ -249,7 +205,7 @@ namespace DCFApixels.DragonECS
item.OnWorldResize(_gens.Length);
}
_gens[entityID] |= short.MinValue;
EcsEntity entity = new EcsEntity(entityID, _gens[entityID]++, id);
EcsEntity entity = new EcsEntity(entityID, _gens[entityID]++, uniqueID);
_entityCreate.OnEntityCreate(entity);
_allEntites.Add(entityID);
return entity;
@ -264,9 +220,9 @@ namespace DCFApixels.DragonECS
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsEntity GetEntity(int entityID)
public EcsEntity GetEcsEntity(int entityID)
{
return new EcsEntity(entityID, _gens[entityID], id);
return new EcsEntity(entityID, _gens[entityID], uniqueID);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool EntityIsAlive(int entityID, short gen)
@ -279,7 +235,7 @@ namespace DCFApixels.DragonECS
public void Destroy()
{
_entityDispenser = null;
_denseEntities = null;
//_denseEntities = null;
_gens = null;
_pools = null;
_nullPool = null;
@ -293,11 +249,27 @@ namespace DCFApixels.DragonECS
}
#endregion
#region Other
void IEcsReadonlyTable.RegisterGroup(EcsGroup group)
#region Groups
void IEcsTable.RegisterGroup(EcsGroup group)
{
_groups.Add(new WeakReference<EcsGroup>(group));
}
EcsGroup IEcsWorld.GetGroupFromPool() => GetGroupFromPool();
internal EcsGroup GetGroupFromPool()
{
if (_groupsPool.Count <= 0)
return new EcsGroup(this);
return _groupsPool.Pop();
}
void IEcsWorld.ReleaseGroup(EcsGroup group)
{
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
if (group.World != this)
throw new ArgumentException("groupFilter.World != this");
#endif
group.Clear();
_groupsPool.Push(group);
}
#endregion
#region Utils
@ -316,58 +288,10 @@ namespace DCFApixels.DragonECS
QueryType.capacity <<= 1;
}
}
/* internal static class ComponentType
{
internal static int increment = 1;
internal static int Capacity
{
get => types.Length;
}
internal static Type[] types = new Type[64];
}
internal static class ComponentType<T>
{
internal static int uniqueID;
static ComponentType()
{
uniqueID = ComponentType.increment++;
#if (DEBUG && !DISABLE_DRAGONECS_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
if (ComponentType.increment + 1 > ushort.MaxValue)
{
throw new EcsFrameworkException($"No more room for new component for this {typeof(TWorldArchetype).FullName} IWorldArchetype");
}
#endif
if (uniqueID >= ComponentType.types.Length)
{
Array.Resize(ref ComponentType.types, ComponentType.types.Length << 1);
}
ComponentType.types[uniqueID] = typeof(T);
}
}*/
#endregion
#region GroupsPool
private Stack<EcsGroup> _pool = new Stack<EcsGroup>(64);
EcsGroup IEcsWorld.GetGroupFromPool() => GetGroupFromPool();
internal EcsGroup GetGroupFromPool()
{
if (_pool.Count <= 0)
return new EcsGroup(this);
return _pool.Pop();
}
void IEcsWorld.ReleaseGroup(EcsGroup group)
{
#if (DEBUG && !DISABLE_DEBUG) || !DRAGONECS_NO_SANITIZE_CHECKS
if (group.World != this)
throw new ArgumentException("groupFilter.World != this");
#endif
group.Clear();
_pool.Push(group);
}
#endregion
}
#region Utils
[StructLayout(LayoutKind.Sequential, Pack = 8, Size = 24)]
internal readonly struct PoolRunnres
{
@ -382,9 +306,6 @@ namespace DCFApixels.DragonECS
del = pipeline.GetRunner<IEcsComponentDel>();
}
}
public static class ComponentIndexer
{
private static List<Resizer> resizer = new List<Resizer>();
@ -434,4 +355,5 @@ namespace DCFApixels.DragonECS
}
}
}
#endregion
}

View File

@ -4,14 +4,14 @@ using System.Runtime.InteropServices;
namespace DCFApixels.DragonECS
{
// uniqueID - 32 bits
// gen - 16 bits
// world - 16 bits
/// <summary>Strong identifier/Permanent entity identifier</summary>
[StructLayout(LayoutKind.Explicit, Pack = 2, Size = 8)]
public readonly partial struct EcsEntity : IEquatable<long>, IEquatable<EcsEntity>
{
public static readonly EcsEntity NULL = default;
// uniqueID - 32 bits
// gen - 16 bits
// world - 16 bits
[FieldOffset(0)]
internal readonly long full; //Union
[FieldOffset(3)]
@ -21,11 +21,8 @@ namespace DCFApixels.DragonECS
[FieldOffset(0)]
public readonly short world;
public ent Ent
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new ent(id);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ent ToEnt() => EcsWorld.Worlds[world].EntityIsAlive(id, gen) ? new ent(id) : default;
#region Constructors
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -53,7 +50,7 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetHashCode() => unchecked((int)full) ^ (int)(full >> 32);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override string ToString() => $"Entity(id:{id} gen:{gen} world:{world})";
public override string ToString() => $"Entity(uniqueID:{id} gen:{gen} world:{world})";
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override bool Equals(object obj) => obj is EcsEntity other && full == other.full;
#endregion
@ -66,7 +63,7 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static explicit operator long(in EcsEntity a) => a.full;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static explicit operator ent(in EcsEntity a) => a.Ent;
public static explicit operator ent(in EcsEntity a) => a.ToEnt();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static explicit operator EcsEntity(in long a) => new EcsEntity(a);
#endregion

View File

@ -13,7 +13,7 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal ent(int id) => this.id = id;
public static explicit operator ent(int id) => new ent(id);
//public static explicit operator ent(int uniqueID) => new ent(uniqueID);
public static explicit operator int(ent entityID) => entityID.id;
public static bool operator ==(ent a, ent b) => a.id == b.id;
@ -27,6 +27,6 @@ namespace DCFApixels.DragonECS
public struct Null { }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsEntity ToStrong(IEcsWorld world) => world.GetEntity(id);
public EcsEntity ToStrong(IEcsWorld world) => world.GetEcsEntity(id);
}
}

View File

@ -3,7 +3,7 @@ using System.Runtime.CompilerServices;
namespace DCFApixels.DragonECS
{
public interface IEcsReadonlyTable
public interface IEcsTable
{
#region Properties
/// <summary>Table Archetype</summary>
@ -30,7 +30,7 @@ namespace DCFApixels.DragonECS
public static class IEcsReadonlyTableExtensions
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsMaskCompatible<TInc>(this IEcsReadonlyTable self, int entityID) where TInc : struct, IInc
public static bool IsMaskCompatible<TInc>(this IEcsTable self, int entityID) where TInc : struct, IInc
{
return self.IsMaskCompatible<TInc, Exc>(entityID);
}