mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 01:44:35 +08:00
rework identifier implementation
This commit is contained in:
parent
1ed1782e4a
commit
b5f134845d
@ -38,23 +38,23 @@
|
|||||||
|
|
||||||
public interface IEcsEntityCreate : IEcsSystem
|
public interface IEcsEntityCreate : IEcsSystem
|
||||||
{
|
{
|
||||||
public void OnEntityCreate(ent entity);
|
public void OnEntityCreate(EcsEntity entity);
|
||||||
}
|
}
|
||||||
public interface IEcsEntityDestroy : IEcsSystem
|
public interface IEcsEntityDestroy : IEcsSystem
|
||||||
{
|
{
|
||||||
public void OnEntityDestroy(ent entity);
|
public void OnEntityDestroy(EcsEntity entity);
|
||||||
}
|
}
|
||||||
public interface IEcsEntityLifecycle : IEcsEntityCreate, IEcsEntityDestroy { }
|
public interface IEcsEntityLifecycle : IEcsEntityCreate, IEcsEntityDestroy { }
|
||||||
public sealed class EcsEntityCreateRunner : EcsRunner<IEcsEntityCreate>, IEcsEntityCreate
|
public sealed class EcsEntityCreateRunner : EcsRunner<IEcsEntityCreate>, IEcsEntityCreate
|
||||||
{
|
{
|
||||||
public void OnEntityCreate(ent entity)
|
public void OnEntityCreate(EcsEntity entity)
|
||||||
{
|
{
|
||||||
foreach (var item in targets) item.OnEntityCreate(entity);
|
foreach (var item in targets) item.OnEntityCreate(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public sealed class EcsEntityDestroyRunner : EcsRunner<IEcsEntityDestroy>, IEcsEntityDestroy
|
public sealed class EcsEntityDestroyRunner : EcsRunner<IEcsEntityDestroy>, IEcsEntityDestroy
|
||||||
{
|
{
|
||||||
public void OnEntityDestroy(ent entity)
|
public void OnEntityDestroy(EcsEntity entity)
|
||||||
{
|
{
|
||||||
foreach (var item in targets) item.OnEntityDestroy(entity);
|
foreach (var item in targets) item.OnEntityDestroy(entity);
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,6 @@ 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
|
||||||
{
|
{
|
||||||
@ -232,9 +230,9 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
delayedOp op = _delayedOps[i];
|
delayedOp op = _delayedOps[i];
|
||||||
if (op >= 0) //delayedOp.IsAdded
|
if (op >= 0) //delayedOp.IsAdded
|
||||||
UncheckedAdd(op & int.MaxValue); //delayedOp.Entity
|
UncheckedAdd(op & int.MaxValue); //delayedOp.EcsEntity
|
||||||
else
|
else
|
||||||
UncheckedRemove(op & int.MaxValue); //delayedOp.Entity
|
UncheckedRemove(op & int.MaxValue); //delayedOp.EcsEntity
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -266,7 +264,7 @@ namespace DCFApixels.DragonECS
|
|||||||
public ent Current
|
public ent Current
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get => _source.World.GetEntity(_dense[_index]);
|
get => new ent(_dense[_index]);
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool MoveNext() => ++_index <= _count && _count<_dense.Length; // <= потму что отсчет начинается с индекса 1 //_count < _dense.Length дает среде понять что проверки на выход за границы не нужны
|
public bool MoveNext() => ++_index <= _count && _count<_dense.Length; // <= потму что отсчет начинается с индекса 1 //_count < _dense.Length дает среде понять что проверки на выход за границы не нужны
|
||||||
|
@ -8,10 +8,10 @@ namespace DCFApixels.DragonECS
|
|||||||
public interface IEcsQueryMember<TComponent>
|
public interface IEcsQueryMember<TComponent>
|
||||||
where TComponent : struct
|
where TComponent : struct
|
||||||
{
|
{
|
||||||
public ref TComponent Write(int entityID);
|
public ref TComponent Write(ent entityID);
|
||||||
public ref readonly TComponent Read(int entityID);
|
public ref readonly TComponent Read(ent entityID);
|
||||||
public bool Has(int entityID);
|
public bool Has(ent entityID);
|
||||||
public void Del(int entityID);
|
public void Del(ent entityID);
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)]
|
[StructLayout(LayoutKind.Sequential, Pack = 8, Size = 8)]
|
||||||
@ -22,21 +22,13 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal inc(EcsPool<TComponent> pool) => _pool = pool;
|
internal inc(EcsPool<TComponent> pool) => _pool = pool;
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public ref TComponent Write(ent entity) => ref _pool.Write(entity.id);
|
public ref TComponent Write(ent entityID) => ref _pool.Write(entityID.id);
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public ref TComponent Write(int entityID) => ref _pool.Write(entityID);
|
public ref readonly TComponent Read(ent entityID) => ref _pool.Read(entityID.id);
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public ref readonly TComponent Read(ent entity) => ref _pool.Read(entity.id);
|
public bool Has(ent entityID) => _pool.Has(entityID.id);
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public ref readonly TComponent Read(int entityID) => ref _pool.Read(entityID);
|
public void Del(ent entityID) => _pool.Del(entityID.id);
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public bool Has(ent entity) => _pool.Has(entity.id);
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public bool Has(int entityID) => _pool.Has(entityID);
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public void Del(ent entity) => _pool.Del(entity.id);
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public void Del(int entityID) => _pool.Del(entityID);
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override string ToString() => $"{(_pool == null ? "NULL" : _pool.World.ArchetypeType.Name)}inc<{typeof(TComponent).Name}>";
|
public override string ToString() => $"{(_pool == null ? "NULL" : _pool.World.ArchetypeType.Name)}inc<{typeof(TComponent).Name}>";
|
||||||
|
|
||||||
@ -52,21 +44,13 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal exc(EcsPool<TComponent> pool) => _pool = pool;
|
internal exc(EcsPool<TComponent> pool) => _pool = pool;
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public ref TComponent Write(ent entity) => ref _pool.Write(entity.id);
|
public ref TComponent Write(ent entityID) => ref _pool.Write(entityID.id);
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public ref TComponent Write(int entityID) => ref _pool.Write(entityID);
|
public ref readonly TComponent Read(ent entityID) => ref _pool.Read(entityID.id);
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public ref readonly TComponent Read(ent entity) => ref _pool.Read(entity.id);
|
public bool Has(ent entityID) => _pool.Has(entityID.id);
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public ref readonly TComponent Read(int entityID) => ref _pool.Read(entityID);
|
public void Del(ent entityID) => _pool.Del(entityID.id);
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public bool Has(ent entity) => _pool.Has(entity.id);
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public bool Has(int entityID) => _pool.Has(entityID);
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public void Del(ent entity) => _pool.Del(entity.id);
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public void Del(int entityID) => _pool.Del(entityID);
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override string ToString() => $"{(_pool == null ? "NULL" : _pool.World.ArchetypeType.Name)}exc<{typeof(TComponent).Name}>";
|
public override string ToString() => $"{(_pool == null ? "NULL" : _pool.World.ArchetypeType.Name)}exc<{typeof(TComponent).Name}>";
|
||||||
|
|
||||||
@ -82,21 +66,13 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal opt(EcsPool<TComponent> pool) => _pool = pool;
|
internal opt(EcsPool<TComponent> pool) => _pool = pool;
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public ref TComponent Write(ent entity) => ref _pool.Write(entity.id);
|
public ref TComponent Write(ent entityID) => ref _pool.Write(entityID.id);
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public ref TComponent Write(int entityID) => ref _pool.Write(entityID);
|
public ref readonly TComponent Read(ent entityID) => ref _pool.Read(entityID.id);
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public ref readonly TComponent Read(ent entity) => ref _pool.Read(entity.id);
|
public bool Has(ent entityID) => _pool.Has(entityID.id);
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public ref readonly TComponent Read(int entityID) => ref _pool.Read(entityID);
|
public void Del(ent entityID) => _pool.Del(entityID.id);
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public bool Has(ent entity) => _pool.Has(entity.id);
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public bool Has(int entityID) => _pool.Has(entityID);
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public void Del(ent entity) => _pool.Del(entity.id);
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public void Del(int entityID) => _pool.Del(entityID);
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override string ToString() => $"{(_pool == null ? "NULL" : _pool.World.ArchetypeType.Name)}opt<{typeof(TComponent).Name}>";
|
public override string ToString() => $"{(_pool == null ? "NULL" : _pool.World.ArchetypeType.Name)}opt<{typeof(TComponent).Name}>";
|
||||||
|
|
||||||
|
35
src/EcsTable.cs
Normal file
35
src/EcsTable.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS
|
||||||
|
{
|
||||||
|
public class EcsTable
|
||||||
|
{
|
||||||
|
private IEcsPool[] _pools;
|
||||||
|
private EcsNullPool _nullPool;
|
||||||
|
|
||||||
|
private int[] _denseEntities;
|
||||||
|
private int[] _sparceEntities;
|
||||||
|
private int _entitiesCount;
|
||||||
|
|
||||||
|
private List<EcsQueryBase>[] _filtersByIncludedComponents;
|
||||||
|
private List<EcsQueryBase>[] _filtersByExcludedComponents;
|
||||||
|
|
||||||
|
private EcsQueryBase[] _queries;
|
||||||
|
|
||||||
|
private List<EcsGroup> _groups;
|
||||||
|
|
||||||
|
#region Internal Properties
|
||||||
|
public int Count => _entitiesCount;
|
||||||
|
public int Capacity => _denseEntities.Length;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public ReadOnlySpan<IEcsPool> GetAllPools() => new ReadOnlySpan<IEcsPool>(_pools);
|
||||||
|
//public int GetComponentID<T>() => ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -18,10 +18,10 @@ namespace DCFApixels.DragonECS
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Entities
|
#region Entities
|
||||||
public ent NewEntity();
|
public EcsEntity NewEntity();
|
||||||
public void DelEntity(ent entity);
|
public void DelEntity(EcsEntity entity);
|
||||||
public bool EntityIsAlive(int entityID, short gen);
|
public bool EntityIsAlive(int entityID, short gen);
|
||||||
public ent GetEntity(int entityID);
|
public EcsEntity GetEntity(int entityID);
|
||||||
public void Destroy();
|
public void Destroy();
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
@ -344,7 +344,7 @@ namespace DCFApixels.DragonECS
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Entity
|
#region Entity
|
||||||
public ent NewEntity()
|
public EcsEntity NewEntity()
|
||||||
{
|
{
|
||||||
int entityID = _entityDispenser.GetFree();
|
int entityID = _entityDispenser.GetFree();
|
||||||
if (_entityDispenser.LastInt >= _denseEntities.Length)
|
if (_entityDispenser.LastInt >= _denseEntities.Length)
|
||||||
@ -360,11 +360,11 @@ namespace DCFApixels.DragonECS
|
|||||||
item.OnWorldResize(_gens.Length);
|
item.OnWorldResize(_gens.Length);
|
||||||
}
|
}
|
||||||
_gens[entityID] |= short.MinValue;
|
_gens[entityID] |= short.MinValue;
|
||||||
ent entity = new ent(entityID, _gens[entityID]++, id);
|
EcsEntity entity = new EcsEntity(entityID, _gens[entityID]++, id);
|
||||||
_entityCreate.OnEntityCreate(entity);
|
_entityCreate.OnEntityCreate(entity);
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
public void DelEntity(ent entity)
|
public void DelEntity(EcsEntity entity)
|
||||||
{
|
{
|
||||||
_entityDispenser.Release(entity.id);
|
_entityDispenser.Release(entity.id);
|
||||||
_gens[entity.id] |= short.MinValue;
|
_gens[entity.id] |= short.MinValue;
|
||||||
@ -373,9 +373,9 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public ent GetEntity(int entityID)
|
public EcsEntity GetEntity(int entityID)
|
||||||
{
|
{
|
||||||
return new ent(entityID, _gens[entityID], id);
|
return new EcsEntity(entityID, _gens[entityID], id);
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool EntityIsAlive(int entityID, short gen)
|
public bool EntityIsAlive(int entityID, short gen)
|
||||||
|
@ -1,28 +1,18 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
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; }
|
|
||||||
}
|
|
||||||
// uniqueID - 32 bits
|
|
||||||
// gen - 16 bits
|
|
||||||
// world - 16 bits
|
|
||||||
[StructLayout(LayoutKind.Explicit, Pack = 2, Size = 8)]
|
|
||||||
public readonly partial struct ent :
|
|
||||||
IEquatable<long>,
|
|
||||||
IEquatable<ent>,
|
|
||||||
IEntityRecord
|
|
||||||
{
|
|
||||||
public static readonly ent NULL = default;
|
|
||||||
|
|
||||||
|
/// <summary>Permanent relation entity identifier</summary>
|
||||||
|
[StructLayout(LayoutKind.Explicit, Pack = 2, Size = 8)]
|
||||||
|
public readonly partial struct EcsEntity : IEquatable<long>, IEquatable<EcsEntity>
|
||||||
|
{
|
||||||
|
public static readonly EcsEntity NULL = default;
|
||||||
|
// uniqueID - 32 bits
|
||||||
|
// gen - 16 bits
|
||||||
|
// world - 16 bits
|
||||||
[FieldOffset(0)]
|
[FieldOffset(0)]
|
||||||
internal readonly long full; //Union
|
internal readonly long full; //Union
|
||||||
[FieldOffset(3)]
|
[FieldOffset(3)]
|
||||||
@ -32,69 +22,64 @@ namespace DCFApixels.DragonECS
|
|||||||
[FieldOffset(0)]
|
[FieldOffset(0)]
|
||||||
public readonly short world;
|
public readonly short world;
|
||||||
|
|
||||||
#region IEntityRecord
|
public ent Ent
|
||||||
bool IEntityRecord.IsSpecific => false;
|
{
|
||||||
long IEntityRecord.Full => full;
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
int ITabelRecord.Id => id;
|
get => new ent(id);
|
||||||
short IEntityRecord.Gen => gen;
|
}
|
||||||
short IEntityRecord.World => world;
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public ent(int id, short gen, short world) : this()
|
public EcsEntity(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)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
internal ent(long full) : this()
|
internal EcsEntity(long full) : this()
|
||||||
{
|
{
|
||||||
this.full = full;
|
this.full = full;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region GetHashCode
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public override int GetHashCode() => unchecked((int)(full)) ^ (int)(full >> 32);
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Equals
|
#region Equals
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override bool Equals(object obj) => obj is ent other && full == other.full;
|
public bool Equals(EcsEntity other) => full == other.full;
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public bool Equals(ent other) => full == other.full;
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool Equals(long other) => full == other;
|
public bool Equals(long other) => full == other;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region ToString
|
#region Object
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public override string ToString() => $"ent(uniqueID:{id} gen:{gen} world:{world})";
|
public override int GetHashCode() => unchecked((int)full) ^ (int)(full >> 32);
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public override string ToString() => $"Entity(id:{id} gen:{gen} world:{world})";
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public override bool Equals(object obj) => obj is EcsEntity other && full == other.full;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#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 EcsEntity a, in EcsEntity 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 EcsEntity a, in EcsEntity 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 EcsEntity a) => a.full;
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static explicit operator int(in ent a) => a.id;
|
public static explicit operator ent(in EcsEntity a) => a.Ent;
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static explicit operator ent(in long a) => new ent(a);
|
public static explicit operator EcsEntity(in long a) => new EcsEntity(a);
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
public readonly partial struct ent
|
public readonly partial struct EcsEntity
|
||||||
{
|
{
|
||||||
private static EcsProfilerMarker _IsNullMarker = new EcsProfilerMarker("ent.IsNull");
|
private static EcsProfilerMarker _IsNullMarker = new EcsProfilerMarker("EcsEntity.IsNull");
|
||||||
private static EcsProfilerMarker _ReadMarker = new EcsProfilerMarker("ent.Read");
|
private static EcsProfilerMarker _ReadMarker = new EcsProfilerMarker("EcsEntity.Read");
|
||||||
private static EcsProfilerMarker _WriteMarker = new EcsProfilerMarker("ent.Write");
|
private static EcsProfilerMarker _WriteMarker = new EcsProfilerMarker("EcsEntity.Write");
|
||||||
private static EcsProfilerMarker _HasMarker = new EcsProfilerMarker("ent.Has");
|
private static EcsProfilerMarker _HasMarker = new EcsProfilerMarker("EcsEntity.Has");
|
||||||
private static EcsProfilerMarker _DelMarker = new EcsProfilerMarker("ent.Del");
|
private static EcsProfilerMarker _DelMarker = new EcsProfilerMarker("EcsEntity.Del");
|
||||||
|
|
||||||
public bool IsNull
|
public bool IsNull
|
||||||
{
|
{
|
||||||
@ -140,15 +125,15 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
public static partial class entExtensions
|
public static partial class entExtensions
|
||||||
{
|
{
|
||||||
private static EcsProfilerMarker _IsAliveMarker = new EcsProfilerMarker("ent.IsAlive");
|
private static EcsProfilerMarker _IsAliveMarker = new EcsProfilerMarker("EcsEntity.IsAlive");
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool IsAlive(this ref ent self)
|
public static bool IsAlive(this ref EcsEntity self)
|
||||||
{
|
{
|
||||||
//using (_IsAliveMarker.Auto())
|
//using (_IsAliveMarker.Auto())
|
||||||
//{
|
//{
|
||||||
bool result = EcsWorld.Worlds[self.world].EntityIsAlive(self.id, self.gen);
|
bool result = EcsWorld.Worlds[self.world].EntityIsAlive(self.id, self.gen);
|
||||||
if (!result) self = ent.NULL;
|
if (!result) self = EcsEntity.NULL;
|
||||||
return result;
|
return result;
|
||||||
//}
|
//}
|
||||||
}
|
}
|
74
src/Entities/EcsRelation.cs
Normal file
74
src/Entities/EcsRelation.cs
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS
|
||||||
|
{
|
||||||
|
/// <summary>Permanent relation entity identifier</summary>
|
||||||
|
[StructLayout(LayoutKind.Explicit, Pack = 2, Size = 8)]
|
||||||
|
public readonly partial struct EcsRelation : IEquatable<long>, IEquatable<EcsRelation>
|
||||||
|
{
|
||||||
|
public static readonly EcsEntity NULL = default;
|
||||||
|
// uniqueID - 32 bits
|
||||||
|
// gen - 16 bits
|
||||||
|
// world - 16 bits
|
||||||
|
[FieldOffset(0)]
|
||||||
|
internal readonly long full; //Union
|
||||||
|
[FieldOffset(3)]
|
||||||
|
public readonly int id;
|
||||||
|
[FieldOffset(1)]
|
||||||
|
public readonly short rightWorld;
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public readonly short leftWorld;
|
||||||
|
|
||||||
|
public ent Ent
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get => new ent(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public EcsRelation(int id, short leftWorld, short rightWorld) : this()
|
||||||
|
{
|
||||||
|
this.id = id;
|
||||||
|
this.leftWorld = leftWorld;
|
||||||
|
this.rightWorld = rightWorld;
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
internal EcsRelation(long full) : this()
|
||||||
|
{
|
||||||
|
this.full = full;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Equals
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public bool Equals(EcsRelation other) => full == other.full;
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public bool Equals(long other) => full == other;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Object
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public override int GetHashCode() => unchecked((int)full) ^ (int)(full >> 32);
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public override string ToString() => $"Relation(id:{id} leftWorld:{leftWorld} rightWorld:{rightWorld})";
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public override bool Equals(object obj) => obj is EcsRelation other && full == other.full;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region operators
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static bool operator ==(in EcsRelation a, in EcsRelation b) => a.full == b.full;
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static bool operator !=(in EcsRelation a, in EcsRelation b) => a.full != b.full;
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static explicit operator long(in EcsRelation a) => a.full;
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static explicit operator ent(in EcsRelation a) => a.Ent;
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static explicit operator EcsRelation(in long a) => new EcsRelation(a);
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
28
src/Entities/ent.cs
Normal file
28
src/Entities/ent.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS
|
||||||
|
{
|
||||||
|
#pragma warning disable CS0660, CS0661
|
||||||
|
/// <summary>Single frame entity identifier</summary>
|
||||||
|
[StructLayout(LayoutKind.Sequential, Pack = 4, Size = 4)]
|
||||||
|
public readonly ref partial struct ent
|
||||||
|
{
|
||||||
|
internal readonly int id;
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
internal ent(int id) => this.id = id;
|
||||||
|
|
||||||
|
public static explicit operator ent(int id) => new ent(id);
|
||||||
|
public static explicit operator int(ent entityID) => entityID.id;
|
||||||
|
|
||||||
|
public static bool operator ==(ent a, ent b) => a.id == b.id;
|
||||||
|
public static bool operator !=(ent a, ent b) => a.id != b.id;
|
||||||
|
|
||||||
|
public static bool operator ==(ent a, Null? _) => a.id == 0;
|
||||||
|
public static bool operator ==(Null? _, ent b) => b.id == 0;
|
||||||
|
public static bool operator !=(ent a, Null? _) => a.id != 0;
|
||||||
|
public static bool operator !=(Null? _, ent b) => b.id != 0;
|
||||||
|
|
||||||
|
public struct Null { }
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
public interface ITabelRecord
|
public interface ITabelRecord
|
||||||
{
|
{
|
||||||
//TODO rename to index; Так ent по определению станет идентификатором
|
//TODO rename to index; Так EcsEntity по определению станет идентификатором
|
||||||
public int Id { get; }
|
public int Id { get; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
36
src/rel.cs
36
src/rel.cs
@ -1,36 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS.TODO
|
|
||||||
{
|
|
||||||
//TODO реализовать систему отношений.
|
|
||||||
//идея есть миры-коннекторы, они являются наборами сущьностей-отношений
|
|
||||||
//сущьности отношения, это теже сущьности но их полный идентификатор - это 32 бита - одна сущьность и 32 - другая
|
|
||||||
//айди миров левой и правой части записываются в мир-коннектор и для конвертации айди сущьности в полный идентификатор, надо взять данные из него.
|
|
||||||
//Проблема: если хранить айди мира для левой части отношения в одном месте, а для правого в другом и только раграничивать на лево и право будет проблема с тем что связи работают только в одном направлении
|
|
||||||
//в этом мире вообще не будет вестиь учет гена, потому что для отношений он не нужен
|
|
||||||
|
|
||||||
//миры коннекторы можно назвать Relations или RealtionTable
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 0, Size = 8)]
|
|
||||||
public readonly ref partial struct rel
|
|
||||||
{
|
|
||||||
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