mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 09:54:35 +08:00
fix changes
This commit is contained in:
parent
b565510a69
commit
b2958cd0de
@ -5,6 +5,8 @@ using delayedOp = System.Int32;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 0, Size = 8)]
|
||||
public readonly ref struct EcsReadonlyGroup
|
||||
{
|
||||
@ -242,7 +244,7 @@ namespace DCFApixels.DragonECS
|
||||
private readonly EcsGroup _source;
|
||||
private readonly int[] _dense;
|
||||
private readonly int _count;
|
||||
private int _pointer;
|
||||
private int _index;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public Enumerator(EcsGroup group)
|
||||
@ -250,26 +252,22 @@ namespace DCFApixels.DragonECS
|
||||
_source = group;
|
||||
_dense = group._dense;
|
||||
_count = group.Count;
|
||||
_pointer = 0;
|
||||
_index = 0;
|
||||
}
|
||||
|
||||
public ent Current
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => _source.World.GetEntity(_dense[_pointer]);
|
||||
get => _source.World.GetEntity(_dense[_index]);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
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)]
|
||||
public void Dispose()
|
||||
{
|
||||
_source.Unlock();
|
||||
}
|
||||
public void Dispose() => _source.Unlock();
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Reset() { }
|
||||
|
@ -1,60 +1,51 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using Unity.Profiling;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public interface IEcsPool
|
||||
{
|
||||
public int EntitiesCount { get; }
|
||||
public int Capacity { get; }
|
||||
|
||||
public Type ComponentType { get; }
|
||||
public int ComponentID { get; }
|
||||
public IEcsWorld World { get; }
|
||||
public Type DataType { get; }
|
||||
public int ID { get; }
|
||||
public int Count { get; }
|
||||
public int Capacity { get; }
|
||||
public bool Has(int entityID);
|
||||
public void Write(int entityID);
|
||||
public void Del(int entityID);
|
||||
|
||||
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 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;
|
||||
|
||||
public EcsNullPool(IEcsWorld source)
|
||||
{
|
||||
_source = source;
|
||||
}
|
||||
|
||||
private EcsNullPool(IEcsWorld source) => _source = source;
|
||||
private NullComponent fakeComponent;
|
||||
public Type ComponentType => typeof(NullComponent);
|
||||
public int ComponentID => -1;
|
||||
public IEcsWorld World => _source;
|
||||
public Type DataType => typeof(void);
|
||||
public int ID => -1;
|
||||
|
||||
public int EntitiesCount => 0;
|
||||
public int Count => 0;
|
||||
public int Capacity => 1;
|
||||
|
||||
public void Del(int index) { }
|
||||
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) { }
|
||||
}
|
||||
|
||||
public class EcsPool<T> : IEcsPool<T>
|
||||
public sealed class EcsPool<T> : IEcsPool<T>
|
||||
where T : struct
|
||||
{
|
||||
private readonly int _id;
|
||||
private readonly int _componentID;
|
||||
private readonly IEcsWorld _source;
|
||||
|
||||
private int[] _mapping;// index = entity / value = itemIndex;/ value = 0 = no entity
|
||||
@ -68,19 +59,18 @@ namespace DCFApixels.DragonECS
|
||||
private PoolRunnres _poolRunnres;
|
||||
|
||||
#region Properites
|
||||
public int EntitiesCount => _itemsCount;
|
||||
public int Count => _itemsCount;
|
||||
public int Capacity => _items.Length;
|
||||
|
||||
public IEcsWorld World => _source;
|
||||
public Type DataType => typeof(T);
|
||||
public int ID => _id;
|
||||
public Type ComponentType => typeof(T);
|
||||
public int ComponentID => _componentID;
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
internal EcsPool(IEcsWorld source, int id, int capacity, PoolRunnres poolRunnres)
|
||||
{
|
||||
_source = source;
|
||||
_id = id;
|
||||
_componentID = id;
|
||||
|
||||
_mapping = new int[source.EntitesCapacity];
|
||||
_recycledItems = new int[128];
|
||||
@ -94,7 +84,6 @@ namespace DCFApixels.DragonECS
|
||||
#endregion
|
||||
|
||||
#region Write/Read/Has/Del
|
||||
|
||||
private ProfilerMarker _writeMark = new ProfilerMarker("EcsPoo.Write");
|
||||
private ProfilerMarker _readMark = new ProfilerMarker("EcsPoo.Read");
|
||||
private ProfilerMarker _hasMark = new ProfilerMarker("EcsPoo.Has");
|
||||
@ -119,7 +108,7 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
_mapping[entityID] = itemIndex;
|
||||
_componentResetHandler.Reset(ref _items[itemIndex]);
|
||||
_source.OnEntityComponentAdded(entityID, _id);
|
||||
_source.OnEntityComponentAdded(entityID, _componentID);
|
||||
_poolRunnres.add.OnComponentAdd<T>(entityID);
|
||||
}
|
||||
|
||||
@ -148,7 +137,7 @@ namespace DCFApixels.DragonECS
|
||||
_recycledItems[_recycledItemsCount++] = _mapping[entityID];
|
||||
_mapping[entityID] = 0;
|
||||
_itemsCount--;
|
||||
_source.OnEntityComponentRemoved(entityID, _id);
|
||||
_source.OnEntityComponentRemoved(entityID, _componentID);
|
||||
_poolRunnres.del.OnComponentDel<T>(entityID);
|
||||
// }
|
||||
}
|
||||
@ -161,17 +150,16 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Equals/GetHashCode
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return base.Equals(obj);
|
||||
}
|
||||
public override int GetHashCode() => _source.GetHashCode() + ID;
|
||||
#region Object
|
||||
public override bool Equals(object obj) => base.Equals(obj);
|
||||
public override int GetHashCode() => _source.GetHashCode() + ~ComponentID;
|
||||
#endregion
|
||||
|
||||
#region Internal
|
||||
void IEcsPool.OnWorldResize(int newSize)
|
||||
{
|
||||
Array.Resize(ref _mapping, newSize);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -1,46 +1,51 @@
|
||||
using DCFApixels.DragonECS;
|
||||
using DCFApixels.DragonECS.Internal;
|
||||
using System;
|
||||
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 rightWorld;
|
||||
|
||||
|
||||
private int[] _relationEntities; //dense
|
||||
private int[] _relations; //dense
|
||||
private int[] _leftMapping;
|
||||
private int[] _rgihtMapping;
|
||||
|
||||
private int _relationsCount;
|
||||
|
||||
private IEcsPool[] _pools;
|
||||
private EcsNullPool _nullPool;
|
||||
|
||||
#region Properties
|
||||
public int RelationsCount
|
||||
{
|
||||
get => _relationsCount;
|
||||
}
|
||||
public Type ArchetypeType => typeof(TArchetype);
|
||||
public int EntitesCount => _relationsCount;
|
||||
public int EntitesCapacity => _relations.Length;
|
||||
#endregion
|
||||
|
||||
|
||||
#region Constructors
|
||||
internal EcsRelationTable(IEcsWorld leftWorld, IEcsWorld rightWorld)
|
||||
{
|
||||
this.leftWorld = leftWorld;
|
||||
this.rightWorld = rightWorld;
|
||||
|
||||
_relationEntities = new int[512];
|
||||
_relations = new int[512];
|
||||
_leftMapping = new int[512];
|
||||
_rgihtMapping = new int[512];
|
||||
|
||||
_relationsCount = 0;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region RealtionControls
|
||||
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();
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
@ -1,52 +1,29 @@
|
||||
using System;
|
||||
using DCFApixels.DragonECS.Internal;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public interface IEcsWorld
|
||||
public interface IEcsWorld : IEcsReadonlyTable
|
||||
{
|
||||
#region Properties
|
||||
//private float _timeScale;//TODO реализовать собсвенныйтайм склей для разных миров
|
||||
public bool IsEmpty { get; }
|
||||
public Type ArchetypeType { get; }
|
||||
public int ID { get; }
|
||||
public EcsPipeline Pipeline { get; }
|
||||
public int EntitesCount { get; }
|
||||
public int EntitesCapacity { get; }
|
||||
#endregion
|
||||
|
||||
#region GetterMethods
|
||||
public ReadOnlySpan<IEcsPool> GetAllPools();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
public EcsPool<T> GetPool<T>() where T : struct;
|
||||
public EcsPool<T> UncheckedGetPool<T>() where T : struct;
|
||||
#region Entities
|
||||
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 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, 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
|
||||
}
|
||||
|
||||
@ -57,13 +34,20 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
public readonly short id;
|
||||
|
||||
public EcsWorld()
|
||||
protected EcsWorld(bool isIndexed)
|
||||
{
|
||||
if(isIndexed == true)
|
||||
{
|
||||
id = (short)_worldIdDispenser.GetFree();
|
||||
if (id >= Worlds.Length)
|
||||
Array.Resize(ref Worlds, Worlds.Length << 1);
|
||||
Worlds[id] = (IEcsWorld)this;
|
||||
}
|
||||
else
|
||||
{
|
||||
id = -1;
|
||||
}
|
||||
}
|
||||
|
||||
protected void Realeze()
|
||||
{
|
||||
@ -106,8 +90,12 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
#endregion
|
||||
|
||||
#region Internal Properties
|
||||
int IEcsReadonlyTable.Count => _entitiesCount;
|
||||
int IEcsReadonlyTable.Capacity => _denseEntities.Length;
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
public bool IsEmpty => _entitiesCount < 0;
|
||||
public Type ArchetypeType => typeof(TArchetype);
|
||||
public int ID => id;
|
||||
public EcsPipeline Pipeline => _pipeline;
|
||||
@ -117,12 +105,12 @@ namespace DCFApixels.DragonECS
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
public EcsWorld(EcsPipeline pipline = null)
|
||||
public EcsWorld(EcsPipeline pipline = null) : base(true)
|
||||
{
|
||||
_pipeline = pipline ?? EcsPipeline.Empty;
|
||||
if (!_pipeline.IsInit) pipline.Init();
|
||||
_entityDispenser = new IntDispenser(1);
|
||||
_nullPool = new EcsNullPool(this);
|
||||
_nullPool = EcsNullPool.instance;
|
||||
_pools = new IEcsPool[512];
|
||||
FillArray(_pools, _nullPool);
|
||||
|
||||
@ -154,7 +142,6 @@ namespace DCFApixels.DragonECS
|
||||
int oldCapacity = _pools.Length;
|
||||
Array.Resize(ref _pools, ComponentType.Capacity);
|
||||
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 _filtersByExcludedComponents, ComponentType.Capacity);
|
||||
@ -285,7 +272,7 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
#region EntityChangedReact
|
||||
|
||||
void IEcsWorld.OnEntityComponentAdded(int entityID, int componentID)
|
||||
void IEcsReadonlyTable.OnEntityComponentAdded(int entityID, int componentID)
|
||||
{
|
||||
var includeList = _filtersByIncludedComponents[componentID];
|
||||
var excludeList = _filtersByExcludedComponents[componentID];
|
||||
@ -316,7 +303,7 @@ namespace DCFApixels.DragonECS
|
||||
// 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 excludeList = _filtersByExcludedComponents[componentID];
|
||||
@ -458,7 +445,7 @@ namespace DCFApixels.DragonECS
|
||||
#endregion
|
||||
|
||||
#region Other
|
||||
void IEcsWorld.RegisterGroup(EcsGroup group)
|
||||
void IEcsReadonlyTable.RegisterGroup(EcsGroup group)
|
||||
{
|
||||
_groups.Add(group);
|
||||
}
|
||||
|
@ -6,45 +6,46 @@ using System.Threading.Tasks;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public interface IEcsEntityComponentTable
|
||||
public interface IEcsReadonlyTable
|
||||
{
|
||||
#region Properties
|
||||
public bool IsEmpty { get; }
|
||||
/// <summary>Table Archetype</summary>
|
||||
public Type ArchetypeType { get; }
|
||||
//public int ID { get; }
|
||||
public int EntitesCount { get; }
|
||||
public int EntitesCapacity { get; }
|
||||
#endregion
|
||||
|
||||
#region GetterMethods
|
||||
public ReadOnlySpan<IEcsPool> GetAllPools();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
public ReadOnlySpan<IEcsPool> GetAllPools();
|
||||
public int GetComponentID<T>();
|
||||
|
||||
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 Filter<TInc>() where TInc : struct, IInc;
|
||||
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, 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);
|
||||
#endregion
|
||||
|
||||
#region Properties
|
||||
internal int Count { get; }
|
||||
internal int Capacity { get; }
|
||||
#endregion
|
||||
|
||||
#region Internal Methods
|
||||
internal void OnEntityComponentAdded(int entityID, int changedPoolID);
|
||||
internal void OnEntityComponentRemoved(int entityID, int changedPoolID);
|
||||
|
||||
public int GetComponentID<T>();
|
||||
internal void RegisterGroup(EcsGroup group);
|
||||
#endregion
|
||||
}
|
||||
|
||||
public static class IEcsReadonlyEntityComponentTableExtensions
|
||||
{
|
||||
public static bool IsNullOrEmpty(this IEcsReadonlyTable self)
|
||||
{
|
||||
return self == null || self.Count <= 0;
|
||||
}
|
||||
}
|
||||
}
|
7
src/Interfaces/INullDummy.cs
Normal file
7
src/Interfaces/INullDummy.cs
Normal file
@ -0,0 +1,7 @@
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public interface INullDummy
|
||||
{
|
||||
public bool IsDummy { get; }
|
||||
}
|
||||
}
|
16
src/Utils/EcsRelationTableArchetype.cs
Normal file
16
src/Utils/EcsRelationTableArchetype.cs
Normal 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>
|
||||
{ }
|
||||
}
|
8
src/Utils/ITabelRecord.cs
Normal file
8
src/Utils/ITabelRecord.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public interface ITabelRecord
|
||||
{
|
||||
//TODO rename to index; Так ent по определению станет идентификатором
|
||||
public int Id { get; }
|
||||
}
|
||||
}
|
144
src/ent.cs
144
src/ent.cs
@ -5,16 +5,26 @@ using System.Runtime.InteropServices;
|
||||
|
||||
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
|
||||
// gen - 16 bits
|
||||
// world - 16 bits
|
||||
[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;
|
||||
|
||||
[FieldOffset(0)]
|
||||
private readonly long _full;
|
||||
internal readonly long full; //Union
|
||||
[FieldOffset(3)]
|
||||
public readonly int id;
|
||||
[FieldOffset(1)]
|
||||
@ -22,44 +32,41 @@ namespace DCFApixels.DragonECS
|
||||
[FieldOffset(0)]
|
||||
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
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public ent(int id, short gen, short world) : this()
|
||||
{
|
||||
this.id = id;
|
||||
this.gen = gen;
|
||||
this.world = world;
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal ent(long full) : this()
|
||||
{
|
||||
_full = full;
|
||||
this.full = full;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GetHashCode
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return unchecked((int)(_full)) ^ (int)(_full >> 32);
|
||||
}
|
||||
public override int GetHashCode() => unchecked((int)(full)) ^ (int)(full >> 32);
|
||||
#endregion
|
||||
|
||||
#region Equals
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is ent other && _full == other._full;
|
||||
}
|
||||
public override bool Equals(object obj) => obj is ent other && full == other.full;
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(ent other)
|
||||
{
|
||||
return _full == other._full;
|
||||
}
|
||||
public bool Equals(ent other) => full == other.full;
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(long other)
|
||||
{
|
||||
return _full == other;
|
||||
}
|
||||
public bool Equals(long other) => full == other;
|
||||
#endregion
|
||||
|
||||
#region ToString
|
||||
@ -69,31 +76,72 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
#region operators
|
||||
[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)]
|
||||
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)]
|
||||
public static explicit operator long(in ent a) => a._full;
|
||||
|
||||
public static explicit operator long(in ent a) => a.full;
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static explicit operator int(in ent a) => a.id;
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static explicit operator ent(in long a) => new ent(a);
|
||||
#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 _ReadMarker = new EcsProfilerMarker("ent.Read");
|
||||
private static EcsProfilerMarker _WriteMarker = new EcsProfilerMarker("ent.Write");
|
||||
private static EcsProfilerMarker _HasMarker = new EcsProfilerMarker("ent.Has");
|
||||
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)]
|
||||
public static bool IsAlive(this ref ent self)
|
||||
{
|
||||
@ -104,43 +152,5 @@ namespace DCFApixels.DragonECS
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
23
src/rel.cs
23
src/rel.cs
@ -16,14 +16,21 @@ namespace DCFApixels.DragonECS.TODO
|
||||
|
||||
|
||||
|
||||
// left entity id - 32 bits
|
||||
// right entity id - 32 bits
|
||||
[StructLayout(LayoutKind.Explicit, Pack = 4, Size = 8)]
|
||||
public struct rel
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 0, Size = 8)]
|
||||
public readonly ref partial struct rel
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public int l;
|
||||
[FieldOffset(1)]
|
||||
public int r;
|
||||
public readonly int id;
|
||||
public readonly short leftWorld;
|
||||
public readonly short rightWorld;
|
||||
|
||||
#region Constructors
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public rel(int id, short leftWorld, short rightWorld)
|
||||
{
|
||||
this.id = id;
|
||||
this.leftWorld = leftWorld;
|
||||
this.rightWorld = rightWorld;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user