fix changes

This commit is contained in:
Mikhail 2023-04-06 23:40:47 +08:00
parent b565510a69
commit b2958cd0de
10 changed files with 303 additions and 201 deletions

View File

@ -5,6 +5,8 @@ using delayedOp = System.Int32;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
[StructLayout(LayoutKind.Sequential, Pack = 0, Size = 8)] [StructLayout(LayoutKind.Sequential, Pack = 0, Size = 8)]
public readonly ref struct EcsReadonlyGroup public readonly ref struct EcsReadonlyGroup
{ {
@ -242,7 +244,7 @@ namespace DCFApixels.DragonECS
private readonly EcsGroup _source; private readonly EcsGroup _source;
private readonly int[] _dense; private readonly int[] _dense;
private readonly int _count; private readonly int _count;
private int _pointer; private int _index;
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public Enumerator(EcsGroup group) public Enumerator(EcsGroup group)
@ -250,26 +252,22 @@ namespace DCFApixels.DragonECS
_source = group; _source = group;
_dense = group._dense; _dense = group._dense;
_count = group.Count; _count = group.Count;
_pointer = 0; _index = 0;
} }
public ent Current public ent Current
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _source.World.GetEntity(_dense[_pointer]); get => _source.World.GetEntity(_dense[_index]);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool MoveNext() public bool MoveNext()
{ {
return ++_pointer <= _count && _count < _dense.Length; //_count < _dense.Length дает среде понять что проверки на выход за границы не нужны // <= потму что отсчет начинается с индекса 1
return ++_index <= _count && _count < _dense.Length; //_count < _dense.Length дает среде понять что проверки на выход за границы не нужны
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Dispose() public void Dispose() => _source.Unlock();
{
_source.Unlock();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Reset() { } public void Reset() { }

View File

@ -1,60 +1,51 @@
using System; using System;
using System.Linq;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Unity.Profiling; using Unity.Profiling;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
public interface IEcsPool public interface IEcsPool
{ {
public int EntitiesCount { get; } public Type ComponentType { get; }
public int Capacity { get; } public int ComponentID { get; }
public IEcsWorld World { get; } public IEcsWorld World { get; }
public Type DataType { get; } public int Count { get; }
public int ID { get; } public int Capacity { get; }
public bool Has(int entityID); public bool Has(int entityID);
public void Write(int entityID); public void Write(int entityID);
public void Del(int entityID); public void Del(int entityID);
internal void OnWorldResize(int newSize); internal void OnWorldResize(int newSize);
} }
public interface IEcsPool<T> : IEcsPool where T : struct
public interface IEcsPool<T> : IEcsPool
where T : struct
{ {
public ref readonly T Read(int entity); public ref readonly T Read(int entity);
public new ref T Write(int entity); public new ref T Write(int entity);
} }
public class EcsNullPool : IEcsPool public struct NullComponent { }
public sealed class EcsNullPool : IEcsPool<NullComponent>
{ {
public static EcsNullPool instance => new EcsNullPool(null);
private readonly IEcsWorld _source; private readonly IEcsWorld _source;
private EcsNullPool(IEcsWorld source) => _source = source;
public EcsNullPool(IEcsWorld source) private NullComponent fakeComponent;
{ public Type ComponentType => typeof(NullComponent);
_source = source; public int ComponentID => -1;
}
public IEcsWorld World => _source; public IEcsWorld World => _source;
public Type DataType => typeof(void); public int Count => 0;
public int ID => -1;
public int EntitiesCount => 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 bool Has(int index) => false;
public void Write(int index) { } 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) { } void IEcsPool.OnWorldResize(int newSize) { }
} }
public class EcsPool<T> : IEcsPool<T> public sealed class EcsPool<T> : IEcsPool<T>
where T : struct where T : struct
{ {
private readonly int _id; private readonly int _componentID;
private readonly IEcsWorld _source; private readonly IEcsWorld _source;
private int[] _mapping;// index = entity / value = itemIndex;/ value = 0 = no entity private int[] _mapping;// index = entity / value = itemIndex;/ value = 0 = no entity
@ -68,19 +59,18 @@ namespace DCFApixels.DragonECS
private PoolRunnres _poolRunnres; private PoolRunnres _poolRunnres;
#region Properites #region Properites
public int EntitiesCount => _itemsCount; public int Count => _itemsCount;
public int Capacity => _items.Length; public int Capacity => _items.Length;
public IEcsWorld World => _source; public IEcsWorld World => _source;
public Type DataType => typeof(T); public Type ComponentType => typeof(T);
public int ID => _id; public int ComponentID => _componentID;
#endregion #endregion
#region Constructors #region Constructors
internal EcsPool(IEcsWorld source, int id, int capacity, PoolRunnres poolRunnres) internal EcsPool(IEcsWorld source, int id, int capacity, PoolRunnres poolRunnres)
{ {
_source = source; _source = source;
_id = id; _componentID = id;
_mapping = new int[source.EntitesCapacity]; _mapping = new int[source.EntitesCapacity];
_recycledItems = new int[128]; _recycledItems = new int[128];
@ -94,7 +84,6 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region Write/Read/Has/Del #region Write/Read/Has/Del
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");
@ -119,7 +108,7 @@ namespace DCFApixels.DragonECS
} }
_mapping[entityID] = itemIndex; _mapping[entityID] = itemIndex;
_componentResetHandler.Reset(ref _items[itemIndex]); _componentResetHandler.Reset(ref _items[itemIndex]);
_source.OnEntityComponentAdded(entityID, _id); _source.OnEntityComponentAdded(entityID, _componentID);
_poolRunnres.add.OnComponentAdd<T>(entityID); _poolRunnres.add.OnComponentAdd<T>(entityID);
} }
@ -148,7 +137,7 @@ namespace DCFApixels.DragonECS
_recycledItems[_recycledItemsCount++] = _mapping[entityID]; _recycledItems[_recycledItemsCount++] = _mapping[entityID];
_mapping[entityID] = 0; _mapping[entityID] = 0;
_itemsCount--; _itemsCount--;
_source.OnEntityComponentRemoved(entityID, _id); _source.OnEntityComponentRemoved(entityID, _componentID);
_poolRunnres.del.OnComponentDel<T>(entityID); _poolRunnres.del.OnComponentDel<T>(entityID);
// } // }
} }
@ -161,17 +150,16 @@ namespace DCFApixels.DragonECS
} }
#endregion #endregion
#region Equals/GetHashCode #region Object
public override bool Equals(object obj) public override bool Equals(object obj) => base.Equals(obj);
{ public override int GetHashCode() => _source.GetHashCode() + ~ComponentID;
return base.Equals(obj);
}
public override int GetHashCode() => _source.GetHashCode() + ID;
#endregion #endregion
#region Internal
void IEcsPool.OnWorldResize(int newSize) void IEcsPool.OnWorldResize(int newSize)
{ {
Array.Resize(ref _mapping, newSize); Array.Resize(ref _mapping, newSize);
} }
#endregion
} }
} }

View File

@ -1,46 +1,51 @@
using DCFApixels.DragonECS; using DCFApixels.DragonECS;
using DCFApixels.DragonECS.Internal;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEditorInternal;
namespace DCFApixels.Assets.DragonECS.src namespace DCFApixels.DragonECS
{ {
public class EcsRelationTable /* public interface IEcsRealationTable : IEcsReadonlyTable
{
public EcsFilter Relations<TComponent>() where TComponent : struct;
}
public sealed class EcsRelationTable<TArchetype> : IEcsRealationTable
where TArchetype : EcsRelationTableArchetypeBase
{ {
public readonly IEcsWorld leftWorld; public readonly IEcsWorld leftWorld;
public readonly IEcsWorld rightWorld; public readonly IEcsWorld rightWorld;
private int[] _relations; //dense
private int[] _relationEntities; //dense
private int[] _leftMapping; private int[] _leftMapping;
private int[] _rgihtMapping; private int[] _rgihtMapping;
private int _relationsCount; private int _relationsCount;
private IEcsPool[] _pools;
private EcsNullPool _nullPool;
#region Properties #region Properties
public int RelationsCount public Type ArchetypeType => typeof(TArchetype);
{ public int EntitesCount => _relationsCount;
get => _relationsCount; public int EntitesCapacity => _relations.Length;
}
#endregion #endregion
#region Constructors
internal EcsRelationTable(IEcsWorld leftWorld, IEcsWorld rightWorld) internal EcsRelationTable(IEcsWorld leftWorld, IEcsWorld rightWorld)
{ {
this.leftWorld = leftWorld; this.leftWorld = leftWorld;
this.rightWorld = rightWorld; this.rightWorld = rightWorld;
_relationEntities = new int[512]; _relations = new int[512];
_leftMapping = new int[512]; _leftMapping = new int[512];
_rgihtMapping = new int[512]; _rgihtMapping = new int[512];
_relationsCount = 0; _relationsCount = 0;
} }
#endregion
#region RealtionControls
public void AddRelation(int leftEnttiyID, int rightEntityID) public void AddRelation(int leftEnttiyID, int rightEntityID)
{ {
@ -53,5 +58,80 @@ namespace DCFApixels.Assets.DragonECS.src
{ {
} }
#endregion
public ReadOnlySpan<IEcsPool> GetAllPools()
{
throw new NotImplementedException();
} }
public int GetComponentID<T>()
{
throw new NotImplementedException();
}
public EcsPool<T> GetPool<T>() where T : struct
{
throw new NotImplementedException();
}
public EcsPool<T> UncheckedGetPool<T>() where T : struct
{
throw new NotImplementedException();
}
public EcsFilter Entities<TComponent>() where TComponent : struct
{
throw new NotImplementedException();
}
public EcsFilter Filter<TInc>() where TInc : struct, IInc
{
throw new NotImplementedException();
}
public EcsFilter Filter<TInc, TExc>()
where TInc : struct, IInc
where TExc : struct, IExc
{
throw new NotImplementedException();
}
public bool IsMaskCompatible<TInc>(int entity) where TInc : struct, IInc
{
throw new NotImplementedException();
}
public bool IsMaskCompatible<TInc, TExc>(int entity)
where TInc : struct, IInc
where TExc : struct, IExc
{
throw new NotImplementedException();
}
public bool IsMaskCompatible(EcsMask mask, int entity)
{
throw new NotImplementedException();
}
public bool IsMaskCompatibleWithout(EcsMask mask, int entity, int otherPoolID)
{
throw new NotImplementedException();
}
void IEcsReadonlyTable.OnEntityComponentAdded(int entityID, int changedPoolID)
{
throw new NotImplementedException();
}
void IEcsReadonlyTable.OnEntityComponentRemoved(int entityID, int changedPoolID)
{
throw new NotImplementedException();
}
void IEcsReadonlyTable.RegisterGroup(EcsGroup group)
{
throw new NotImplementedException();
}
}*/
} }

View File

@ -1,52 +1,29 @@
using System; using DCFApixels.DragonECS.Internal;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
public interface IEcsWorld public interface IEcsWorld : IEcsReadonlyTable
{ {
#region Properties #region Properties
//private float _timeScale;//TODO реализовать собсвенныйтайм склей для разных миров //private float _timeScale;//TODO реализовать собсвенныйтайм склей для разных миров
public bool IsEmpty { get; }
public Type ArchetypeType { get; }
public int ID { get; } public int ID { get; }
public EcsPipeline Pipeline { get; } public EcsPipeline Pipeline { get; }
public int EntitesCount { get; } public int EntitesCount { get; }
public int EntitesCapacity { get; } public int EntitesCapacity { get; }
#endregion #endregion
#region GetterMethods #region Entities
public ReadOnlySpan<IEcsPool> GetAllPools();
#endregion
#region Methods
public EcsPool<T> GetPool<T>() where T : struct;
public EcsPool<T> UncheckedGetPool<T>() where T : struct;
public EcsFilter Entities<TComponent>() where TComponent : struct; public EcsFilter Entities<TComponent>() where TComponent : struct;
public EcsFilter Filter<TInc>() where TInc : struct, IInc;
public EcsFilter Filter<TInc, TExc>() where TInc : struct, IInc where TExc : struct, IExc;
public ent NewEntity(); public ent NewEntity();
public void DelEntity(ent entity); public void DelEntity(ent entity);
public bool EntityIsAlive(int entityID, short gen); public bool EntityIsAlive(int entityID, short gen);
public ent GetEntity(int entityID); public ent GetEntity(int entityID);
public void Destroy(); public void Destroy();
public bool IsMaskCompatible<TInc>(int entity) where TInc : struct, IInc;
public bool IsMaskCompatible<TInc, TExc>(int entity) where TInc : struct, IInc where TExc : struct, IExc;
public bool IsMaskCompatible(EcsMask mask, int entity);
public bool IsMaskCompatibleWithout(EcsMask mask, int entity, int otherPoolID);
internal void OnEntityComponentAdded(int entityID, int changedPoolID);
internal void OnEntityComponentRemoved(int entityID, int changedPoolID);
public int GetComponentID<T>();
internal void RegisterGroup(EcsGroup group);
#endregion #endregion
} }
@ -57,13 +34,20 @@ namespace DCFApixels.DragonECS
public readonly short id; public readonly short id;
public EcsWorld() protected EcsWorld(bool isIndexed)
{
if(isIndexed == true)
{ {
id = (short)_worldIdDispenser.GetFree(); id = (short)_worldIdDispenser.GetFree();
if (id >= Worlds.Length) if (id >= Worlds.Length)
Array.Resize(ref Worlds, Worlds.Length << 1); Array.Resize(ref Worlds, Worlds.Length << 1);
Worlds[id] = (IEcsWorld)this; Worlds[id] = (IEcsWorld)this;
} }
else
{
id = -1;
}
}
protected void Realeze() protected void Realeze()
{ {
@ -106,8 +90,12 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region Internal Properties
int IEcsReadonlyTable.Count => _entitiesCount;
int IEcsReadonlyTable.Capacity => _denseEntities.Length;
#endregion
#region Properties #region Properties
public bool IsEmpty => _entitiesCount < 0;
public Type ArchetypeType => typeof(TArchetype); public Type ArchetypeType => typeof(TArchetype);
public int ID => id; public int ID => id;
public EcsPipeline Pipeline => _pipeline; public EcsPipeline Pipeline => _pipeline;
@ -117,12 +105,12 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region Constructors #region Constructors
public EcsWorld(EcsPipeline pipline = null) public EcsWorld(EcsPipeline pipline = null) : base(true)
{ {
_pipeline = pipline ?? EcsPipeline.Empty; _pipeline = pipline ?? EcsPipeline.Empty;
if (!_pipeline.IsInit) pipline.Init(); if (!_pipeline.IsInit) pipline.Init();
_entityDispenser = new IntDispenser(1); _entityDispenser = new IntDispenser(1);
_nullPool = new EcsNullPool(this); _nullPool = EcsNullPool.instance;
_pools = new IEcsPool[512]; _pools = new IEcsPool[512];
FillArray(_pools, _nullPool); FillArray(_pools, _nullPool);
@ -154,7 +142,6 @@ namespace DCFApixels.DragonECS
int oldCapacity = _pools.Length; int oldCapacity = _pools.Length;
Array.Resize(ref _pools, ComponentType.Capacity); Array.Resize(ref _pools, ComponentType.Capacity);
FillArray(_pools, _nullPool, oldCapacity, oldCapacity - _pools.Length); FillArray(_pools, _nullPool, oldCapacity, oldCapacity - _pools.Length);
//Array.Fill(_pools, _nullPool, oldCapacity, oldCapacity - _pools.Length); //TODO Fix it
Array.Resize(ref _filtersByIncludedComponents, ComponentType.Capacity); Array.Resize(ref _filtersByIncludedComponents, ComponentType.Capacity);
Array.Resize(ref _filtersByExcludedComponents, ComponentType.Capacity); Array.Resize(ref _filtersByExcludedComponents, ComponentType.Capacity);
@ -285,7 +272,7 @@ namespace DCFApixels.DragonECS
#region EntityChangedReact #region EntityChangedReact
void IEcsWorld.OnEntityComponentAdded(int entityID, int componentID) void IEcsReadonlyTable.OnEntityComponentAdded(int entityID, int componentID)
{ {
var includeList = _filtersByIncludedComponents[componentID]; var includeList = _filtersByIncludedComponents[componentID];
var excludeList = _filtersByExcludedComponents[componentID]; var excludeList = _filtersByExcludedComponents[componentID];
@ -316,7 +303,7 @@ namespace DCFApixels.DragonECS
// if (excludeList != null) foreach (var filter in excludeList) filter.entities.Remove(entityID); // if (excludeList != null) foreach (var filter in excludeList) filter.entities.Remove(entityID);
} }
void IEcsWorld.OnEntityComponentRemoved(int entityID, int componentID) void IEcsReadonlyTable.OnEntityComponentRemoved(int entityID, int componentID)
{ {
var includeList = _filtersByIncludedComponents[componentID]; var includeList = _filtersByIncludedComponents[componentID];
var excludeList = _filtersByExcludedComponents[componentID]; var excludeList = _filtersByExcludedComponents[componentID];
@ -458,7 +445,7 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region Other #region Other
void IEcsWorld.RegisterGroup(EcsGroup group) void IEcsReadonlyTable.RegisterGroup(EcsGroup group)
{ {
_groups.Add(group); _groups.Add(group);
} }

View File

@ -6,45 +6,46 @@ using System.Threading.Tasks;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
public interface IEcsEntityComponentTable public interface IEcsReadonlyTable
{ {
#region Properties #region Properties
public bool IsEmpty { get; } /// <summary>Table Archetype</summary>
public Type ArchetypeType { get; } public Type ArchetypeType { get; }
//public int ID { get; }
public int EntitesCount { get; }
public int EntitesCapacity { get; }
#endregion
#region GetterMethods
public ReadOnlySpan<IEcsPool> GetAllPools();
#endregion #endregion
#region Methods #region Methods
public ReadOnlySpan<IEcsPool> GetAllPools();
public int GetComponentID<T>();
public EcsPool<T> GetPool<T>() where T : struct; public EcsPool<T> GetPool<T>() where T : struct;
public EcsPool<T> UncheckedGetPool<T>() where T : struct; public EcsPool<T> UncheckedGetPool<T>() where T : struct;
public EcsFilter Entities<TComponent>() where TComponent : struct;
public EcsFilter Filter<TInc>() where TInc : struct, IInc; public EcsFilter Filter<TInc>() where TInc : struct, IInc;
public EcsFilter Filter<TInc, TExc>() where TInc : struct, IInc where TExc : struct, IExc; public EcsFilter Filter<TInc, TExc>() where TInc : struct, IInc where TExc : struct, IExc;
public ent NewEntity();
public void DelEntity(ent entity);
public bool EntityIsAlive(int entityID, short gen);
public ent GetEntity(int entityID);
public void Destroy();
public bool IsMaskCompatible<TInc>(int entity) where TInc : struct, IInc; public bool IsMaskCompatible<TInc>(int entity) where TInc : struct, IInc;
public bool IsMaskCompatible<TInc, TExc>(int entity) where TInc : struct, IInc where TExc : struct, IExc; public bool IsMaskCompatible<TInc, TExc>(int entity) where TInc : struct, IInc where TExc : struct, IExc;
public bool IsMaskCompatible(EcsMask mask, int entity); public bool IsMaskCompatible(EcsMask mask, int entity);
public bool IsMaskCompatibleWithout(EcsMask mask, int entity, int otherPoolID); public bool IsMaskCompatibleWithout(EcsMask mask, int entity, int otherPoolID);
#endregion
#region Properties
internal int Count { get; }
internal int Capacity { get; }
#endregion
#region Internal Methods
internal void OnEntityComponentAdded(int entityID, int changedPoolID); internal void OnEntityComponentAdded(int entityID, int changedPoolID);
internal void OnEntityComponentRemoved(int entityID, int changedPoolID); internal void OnEntityComponentRemoved(int entityID, int changedPoolID);
public int GetComponentID<T>();
internal void RegisterGroup(EcsGroup group); internal void RegisterGroup(EcsGroup group);
#endregion #endregion
} }
public static class IEcsReadonlyEntityComponentTableExtensions
{
public static bool IsNullOrEmpty(this IEcsReadonlyTable self)
{
return self == null || self.Count <= 0;
}
}
} }

View File

@ -0,0 +1,7 @@
namespace DCFApixels.DragonECS
{
public interface INullDummy
{
public bool IsDummy { get; }
}
}

View File

@ -0,0 +1,16 @@
using System;
namespace DCFApixels.DragonECS.Internal
{
public abstract class EcsRelationTableArchetypeBase
{
public EcsRelationTableArchetypeBase()
{
throw new TypeAccessException("Сreating instances of EcsRelationTableArchetype class is not available.");
}
}
public sealed class EcsRelationTableArchetype<TLeftWorld, TRightWorld> : EcsRelationTableArchetypeBase
where TLeftWorld : EcsWorld<TLeftWorld>
where TRightWorld : EcsWorld<TRightWorld>
{ }
}

View File

@ -0,0 +1,8 @@
namespace DCFApixels.DragonECS
{
public interface ITabelRecord
{
//TODO rename to index; Так ent по определению станет идентификатором
public int Id { get; }
}
}

View File

@ -5,16 +5,26 @@ using System.Runtime.InteropServices;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
public interface IEntityRecord : ITabelRecord
{
public bool IsSpecific { get; }
internal long Full { get; }
public short Gen { get; }
public short World { get; }
}
// id - 32 bits // id - 32 bits
// gen - 16 bits // gen - 16 bits
// world - 16 bits // world - 16 bits
[StructLayout(LayoutKind.Explicit, Pack = 2, Size = 8)] [StructLayout(LayoutKind.Explicit, Pack = 2, Size = 8)]
public readonly struct ent : IEquatable<long>, IEquatable<ent> public readonly partial struct ent :
IEquatable<long>,
IEquatable<ent>,
IEntityRecord
{ {
public static readonly ent NULL = default; public static readonly ent NULL = default;
[FieldOffset(0)] [FieldOffset(0)]
private readonly long _full; internal readonly long full; //Union
[FieldOffset(3)] [FieldOffset(3)]
public readonly int id; public readonly int id;
[FieldOffset(1)] [FieldOffset(1)]
@ -22,44 +32,41 @@ namespace DCFApixels.DragonECS
[FieldOffset(0)] [FieldOffset(0)]
public readonly short world; public readonly short world;
#region IEntityRecord
bool IEntityRecord.IsSpecific => false;
long IEntityRecord.Full => full;
int ITabelRecord.Id => id;
short IEntityRecord.Gen => gen;
short IEntityRecord.World => world;
#endregion
#region Constructors #region Constructors
[EditorBrowsable(EditorBrowsableState.Never)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public ent(int id, short gen, short world) : this() public ent(int id, short gen, short world) : this()
{ {
this.id = id; this.id = id;
this.gen = gen; this.gen = gen;
this.world = world; this.world = world;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal ent(long full) : this() internal ent(long full) : this()
{ {
_full = full; this.full = full;
} }
#endregion #endregion
#region GetHashCode #region GetHashCode
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetHashCode() public override int GetHashCode() => unchecked((int)(full)) ^ (int)(full >> 32);
{
return unchecked((int)(_full)) ^ (int)(_full >> 32);
}
#endregion #endregion
#region Equals #region Equals
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public override bool Equals(object obj) public override bool Equals(object obj) => obj is ent other && full == other.full;
{
return obj is ent other && _full == other._full;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(ent other) public bool Equals(ent other) => full == other.full;
{
return _full == other._full;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(long other) public bool Equals(long other) => full == other;
{
return _full == other;
}
#endregion #endregion
#region ToString #region ToString
@ -69,31 +76,72 @@ namespace DCFApixels.DragonECS
#region operators #region operators
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator ==(in ent a, in ent b) => a._full == b._full; public static bool operator ==(in ent a, in ent b) => a.full == b.full;
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(in ent a, in ent b) => a._full != b._full; public static bool operator !=(in ent a, in ent b) => a.full != b.full;
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static explicit operator long(in ent a) => a._full; public static explicit operator long(in ent a) => a.full;
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static explicit operator int(in ent a) => a.id; public static explicit operator int(in ent a) => a.id;
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static explicit operator ent(in long a) => new ent(a); public static explicit operator ent(in long a) => new ent(a);
#endregion #endregion
} }
public static partial class entExtensions public readonly partial struct ent
{ {
private static EcsProfilerMarker _IsAliveMarker = new EcsProfilerMarker("ent.IsAlive");
private static EcsProfilerMarker _IsNullMarker = new EcsProfilerMarker("ent.IsNull"); private static EcsProfilerMarker _IsNullMarker = new EcsProfilerMarker("ent.IsNull");
private static EcsProfilerMarker _ReadMarker = new EcsProfilerMarker("ent.Read"); private static EcsProfilerMarker _ReadMarker = new EcsProfilerMarker("ent.Read");
private static EcsProfilerMarker _WriteMarker = new EcsProfilerMarker("ent.Write"); private static EcsProfilerMarker _WriteMarker = new EcsProfilerMarker("ent.Write");
private static EcsProfilerMarker _HasMarker = new EcsProfilerMarker("ent.Has"); private static EcsProfilerMarker _HasMarker = new EcsProfilerMarker("ent.Has");
private static EcsProfilerMarker _DelMarker = new EcsProfilerMarker("ent.Del"); private static EcsProfilerMarker _DelMarker = new EcsProfilerMarker("ent.Del");
public bool IsNull
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
//using (_IsNullMarker.Auto())
return this == NULL;
}
}
public ref readonly T Read<T>()
where T : struct
{
//using (_ReadMarker.Auto())
return ref EcsWorld.Worlds[world].GetPool<T>().Read(id);
}
public ref T Write<T>()
where T : struct
{
//using (_WriteMarker.Auto())
return ref EcsWorld.Worlds[world].GetPool<T>().Write(id);
}
public bool Has<T>()
where T : struct
{
//using (_HasMarker.Auto())
return EcsWorld.Worlds[world].GetPool<T>().Has(id);
}
public bool NotHas<T>()
where T : struct
{
//using (_HasMarker.Auto())
return EcsWorld.Worlds[world].GetPool<T>().Has(id);
}
public void Del<T>()
where T : struct
{
//using (_DelMarker.Auto())
EcsWorld.Worlds[world].GetPool<T>().Del(id);
}
}
public static partial class entExtensions
{
private static EcsProfilerMarker _IsAliveMarker = new EcsProfilerMarker("ent.IsAlive");
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsAlive(this ref ent self) public static bool IsAlive(this ref ent self)
{ {
@ -104,43 +152,5 @@ namespace DCFApixels.DragonECS
return result; return result;
//} //}
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool IsNull(this in ent self)
{
//using (_IsNullMarker.Auto())
return self == ent.NULL;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref readonly T Read<T>(this in ent self)
where T : struct
{
//using (_ReadMarker.Auto())
return ref EcsWorld.Worlds[self.world].GetPool<T>().Read(self.id);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref T Write<T>(this in ent self)
where T : struct
{
//using (_WriteMarker.Auto())
return ref EcsWorld.Worlds[self.world].GetPool<T>().Write(self.id);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool Has<T>(this in ent self)
where T : struct
{
//using (_HasMarker.Auto())
return EcsWorld.Worlds[self.world].GetPool<T>().Has(self.id);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool NotHas<T>(this in ent self) where T : struct => !Has<T>(in self);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Del<T>(this in ent self)
where T : struct
{
//using (_DelMarker.Auto())
EcsWorld.Worlds[self.world].GetPool<T>().Del(self.id);
}
} }
} }

View File

@ -16,14 +16,21 @@ namespace DCFApixels.DragonECS.TODO
// left entity id - 32 bits [StructLayout(LayoutKind.Sequential, Pack = 0, Size = 8)]
// right entity id - 32 bits public readonly ref partial struct rel
[StructLayout(LayoutKind.Explicit, Pack = 4, Size = 8)]
public struct rel
{ {
[FieldOffset(0)] public readonly int id;
public int l; public readonly short leftWorld;
[FieldOffset(1)] public readonly short rightWorld;
public int r;
#region Constructors
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public rel(int id, short leftWorld, short rightWorld)
{
this.id = id;
this.leftWorld = leftWorld;
this.rightWorld = rightWorld;
}
#endregion
} }
} }