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
|
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() { }
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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();
|
||||||
|
}
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
|
@ -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,12 +34,19 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
public readonly short id;
|
public readonly short id;
|
||||||
|
|
||||||
public EcsWorld()
|
protected EcsWorld(bool isIndexed)
|
||||||
{
|
{
|
||||||
id = (short)_worldIdDispenser.GetFree();
|
if(isIndexed == true)
|
||||||
if(id >= Worlds.Length)
|
{
|
||||||
Array.Resize(ref Worlds, Worlds.Length << 1);
|
id = (short)_worldIdDispenser.GetFree();
|
||||||
Worlds[id] = (IEcsWorld)this;
|
if (id >= Worlds.Length)
|
||||||
|
Array.Resize(ref Worlds, Worlds.Length << 1);
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
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; }
|
||||||
|
}
|
||||||
|
}
|
146
src/ent.cs
146
src/ent.cs
@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
23
src/rel.cs
23
src/rel.cs
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user