mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 01:44:35 +08:00
Merge branch 'dev' into new_system_layers
This commit is contained in:
commit
0c4a3a822f
@ -10,7 +10,7 @@
|
|||||||
<RootNamespace>DCFApixels.DragonECS</RootNamespace>
|
<RootNamespace>DCFApixels.DragonECS</RootNamespace>
|
||||||
|
|
||||||
<Title>DragonECS</Title>
|
<Title>DragonECS</Title>
|
||||||
<Version>0.9.9</Version>
|
<Version>0.9.10</Version>
|
||||||
<Authors>DCFApixels</Authors>
|
<Authors>DCFApixels</Authors>
|
||||||
<Description>ECS Framework for Game Engines with C# and .Net Platform</Description>
|
<Description>ECS Framework for Game Engines with C# and .Net Platform</Description>
|
||||||
<Copyright>DCFApixels</Copyright>
|
<Copyright>DCFApixels</Copyright>
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
"displayName": "DragonECS",
|
"displayName": "DragonECS",
|
||||||
"description": "C# Entity Component System Framework",
|
"description": "C# Entity Component System Framework",
|
||||||
"unity": "2020.3",
|
"unity": "2020.3",
|
||||||
"version": "0.9.9",
|
"version": "0.9.10",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/DCFApixels/DragonECS.git"
|
"url": "https://github.com/DCFApixels/DragonECS.git"
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#if DISABLE_DEBUG
|
#if DISABLE_DEBUG
|
||||||
#undef DEBUG
|
#undef DEBUG
|
||||||
#endif
|
#endif
|
||||||
|
using DCFApixels.DragonECS.Core.Unchecked;
|
||||||
using DCFApixels.DragonECS.Internal;
|
using DCFApixels.DragonECS.Internal;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#if DISABLE_DEBUG
|
#if DISABLE_DEBUG
|
||||||
#undef DEBUG
|
#undef DEBUG
|
||||||
#endif
|
#endif
|
||||||
|
using DCFApixels.DragonECS.Core.Unchecked;
|
||||||
using DCFApixels.DragonECS.Internal;
|
using DCFApixels.DragonECS.Internal;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
@ -247,7 +247,7 @@ namespace DCFApixels.DragonECS
|
|||||||
#region Static Constructor
|
#region Static Constructor
|
||||||
static DebugService()
|
static DebugService()
|
||||||
{
|
{
|
||||||
#if !UNITY_5_3_OR_NEWER
|
#if UNITY_5_3_OR_NEWER
|
||||||
Set(new NullDebugService());
|
Set(new NullDebugService());
|
||||||
#else
|
#else
|
||||||
Set(new DefaultDebugService());
|
Set(new DefaultDebugService());
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#undef DEBUG
|
#undef DEBUG
|
||||||
#endif
|
#endif
|
||||||
using DCFApixels.DragonECS.Core;
|
using DCFApixels.DragonECS.Core;
|
||||||
|
using DCFApixels.DragonECS.Core.Unchecked;
|
||||||
using DCFApixels.DragonECS.Internal;
|
using DCFApixels.DragonECS.Internal;
|
||||||
using DCFApixels.DragonECS.PoolsCore;
|
using DCFApixels.DragonECS.PoolsCore;
|
||||||
using System;
|
using System;
|
||||||
|
@ -45,10 +45,15 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool TryGetWorld(short worldID, out EcsWorld world)
|
public static bool TryGetWorld(short worldID, out EcsWorld world)
|
||||||
{// ts
|
{// ts
|
||||||
|
if (worldID >= _worlds.Length)
|
||||||
|
{
|
||||||
|
world = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
world = _worlds[worldID];
|
world = _worlds[worldID];
|
||||||
return
|
return
|
||||||
world != null &&
|
world != null &&
|
||||||
world.IsDestroyed != false &&
|
world.IsDestroyed == false &&
|
||||||
worldID != 0;
|
worldID != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -538,7 +538,7 @@ namespace DCFApixels.DragonECS.Internal
|
|||||||
state ^= state >> 17;
|
state ^= state >> 17;
|
||||||
state ^= state << 5;
|
state ^= state << 5;
|
||||||
return state;
|
return state;
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static long NextXorShiftState(long state)
|
public static long NextXorShiftState(long state)
|
||||||
|
@ -95,6 +95,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
ref int itemIndex = ref _mapping[entityID];
|
ref int itemIndex = ref _mapping[entityID];
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
if (entityID == EcsConsts.NULL_ENTITY_ID) { Throw.Ent_ThrowIsNotAlive(_source, entityID); }
|
||||||
if (_source.IsUsed(entityID) == false) { Throw.Ent_ThrowIsNotAlive(_source, entityID); }
|
if (_source.IsUsed(entityID) == false) { Throw.Ent_ThrowIsNotAlive(_source, entityID); }
|
||||||
if (itemIndex > 0) { EcsPoolThrowHelper.ThrowAlreadyHasComponent<T>(entityID); }
|
if (itemIndex > 0) { EcsPoolThrowHelper.ThrowAlreadyHasComponent<T>(entityID); }
|
||||||
if (_isLocked) { EcsPoolThrowHelper.ThrowPoolLocked(); }
|
if (_isLocked) { EcsPoolThrowHelper.ThrowPoolLocked(); }
|
||||||
@ -144,6 +145,9 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
public ref T TryAddOrGet(int entityID)
|
public ref T TryAddOrGet(int entityID)
|
||||||
{
|
{
|
||||||
|
#if DEBUG
|
||||||
|
if (entityID == EcsConsts.NULL_ENTITY_ID) { Throw.Ent_ThrowIsNotAlive(_source, entityID); }
|
||||||
|
#endif
|
||||||
ref int itemIndex = ref _mapping[entityID];
|
ref int itemIndex = ref _mapping[entityID];
|
||||||
if (itemIndex <= 0)
|
if (itemIndex <= 0)
|
||||||
{ //Add block
|
{ //Add block
|
||||||
@ -185,6 +189,7 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
ref int itemIndex = ref _mapping[entityID];
|
ref int itemIndex = ref _mapping[entityID];
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
if (entityID == EcsConsts.NULL_ENTITY_ID) { Throw.Ent_ThrowIsNotAlive(_source, entityID); }
|
||||||
if (itemIndex <= 0) { EcsPoolThrowHelper.ThrowNotHaveComponent<T>(entityID); }
|
if (itemIndex <= 0) { EcsPoolThrowHelper.ThrowNotHaveComponent<T>(entityID); }
|
||||||
if (_isLocked) { EcsPoolThrowHelper.ThrowPoolLocked(); }
|
if (_isLocked) { EcsPoolThrowHelper.ThrowPoolLocked(); }
|
||||||
#elif DRAGONECS_STABILITY_MODE
|
#elif DRAGONECS_STABILITY_MODE
|
||||||
@ -237,9 +242,8 @@ namespace DCFApixels.DragonECS
|
|||||||
#elif DRAGONECS_STABILITY_MODE
|
#elif DRAGONECS_STABILITY_MODE
|
||||||
if (_isLocked) { return; }
|
if (_isLocked) { return; }
|
||||||
#endif
|
#endif
|
||||||
_recycledItemsCount = 0; // спереди потому чтобы обнулялось, так как Del не обнуляет
|
_recycledItemsCount = 0; // ñïåðåäè ÷òîáû îáíóëÿëîñü, òàê êàê Del íå îáíóëÿåò
|
||||||
if (_itemsCount <= 0) { return; }
|
if (_itemsCount <= 0) { return; }
|
||||||
_itemsCount = 0;
|
|
||||||
var span = _source.Where(out SingleAspect<T> _);
|
var span = _source.Where(out SingleAspect<T> _);
|
||||||
foreach (var entityID in span)
|
foreach (var entityID in span)
|
||||||
{
|
{
|
||||||
@ -251,6 +255,8 @@ namespace DCFApixels.DragonECS
|
|||||||
_listeners.InvokeOnDel(entityID, _listenersCachedCount);
|
_listeners.InvokeOnDel(entityID, _listenersCachedCount);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
_itemsCount = 0;
|
||||||
|
_recycledItemsCount = 0;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
8
src/Utils/Uncheked.meta
Normal file
8
src/Utils/Uncheked.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5f2e943735300fe40bdbff86b6089dad
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
44
src/Utils/Uncheked/EntitiesMatrix.cs
Normal file
44
src/Utils/Uncheked/EntitiesMatrix.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#if DISABLE_DEBUG
|
||||||
|
#undef DEBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS.UncheckedCore
|
||||||
|
{
|
||||||
|
public readonly struct EntitiesMatrix
|
||||||
|
{
|
||||||
|
private readonly EcsWorld _world;
|
||||||
|
public EntitiesMatrix(EcsWorld world)
|
||||||
|
{
|
||||||
|
_world = world;
|
||||||
|
}
|
||||||
|
public int PoolsCount
|
||||||
|
{
|
||||||
|
get { return _world.PoolsCount; }
|
||||||
|
}
|
||||||
|
public int EntitesCount
|
||||||
|
{
|
||||||
|
get { return _world.Capacity; }
|
||||||
|
}
|
||||||
|
public int GetEntityComponentsCount(int entityID)
|
||||||
|
{
|
||||||
|
return _world.GetComponentsCount(entityID);
|
||||||
|
}
|
||||||
|
public int GetEntityGen(int entityID)
|
||||||
|
{
|
||||||
|
return _world.GetGen(entityID);
|
||||||
|
}
|
||||||
|
public bool IsEntityUsed(int entityID)
|
||||||
|
{
|
||||||
|
return _world.IsUsed(entityID);
|
||||||
|
}
|
||||||
|
public bool this[int entityID, int poolID]
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
int entityStartChunkIndex = entityID << _world._entityComponentMaskLengthBitShift;
|
||||||
|
var chunkInfo = EcsMaskChunck.FromID(poolID);
|
||||||
|
return (_world._entityComponentMasks[entityStartChunkIndex + chunkInfo.chunkIndex] & chunkInfo.mask) != 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2
src/Utils/Uncheked/EntitiesMatrix.cs.meta
Normal file
2
src/Utils/Uncheked/EntitiesMatrix.cs.meta
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 82a4a05728fb81b4b903d9893a85f77f
|
137
src/Utils/Uncheked/EntitySlotInfo.cs
Normal file
137
src/Utils/Uncheked/EntitySlotInfo.cs
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
#if DISABLE_DEBUG
|
||||||
|
#undef DEBUG
|
||||||
|
#endif
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS.Core.Unchecked
|
||||||
|
{
|
||||||
|
[StructLayout(LayoutKind.Explicit, Pack = 2, Size = 8)]
|
||||||
|
[DebuggerTypeProxy(typeof(EntityDebuggerProxy))]
|
||||||
|
public struct EntitySlotInfo : IEquatable<EntitySlotInfo>
|
||||||
|
{
|
||||||
|
#if UNITY_EDITOR
|
||||||
|
[UnityEngine.SerializeField]
|
||||||
|
#endif
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public long full; //Union
|
||||||
|
[FieldOffset(0), NonSerialized]
|
||||||
|
public int id;
|
||||||
|
[FieldOffset(4), NonSerialized]
|
||||||
|
public short gen;
|
||||||
|
[FieldOffset(6), NonSerialized]
|
||||||
|
public short worldID;
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
public EcsWorld World { get { return EcsWorld.GetWorld(worldID); } }
|
||||||
|
public StateFlag State { get { return full == 0 ? StateFlag.Null : World.IsAlive(id, gen) ? StateFlag.Alive : StateFlag.Dead; } }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors/Deconstructors
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public EntitySlotInfo(long full) : this()
|
||||||
|
{
|
||||||
|
this.full = full;
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public EntitySlotInfo(int id, short gen, short world) : this()
|
||||||
|
{
|
||||||
|
this.id = id;
|
||||||
|
this.gen = gen;
|
||||||
|
worldID = world;
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void Deconstruct(out int id, out int gen, out int worldID)
|
||||||
|
{
|
||||||
|
id = this.id;
|
||||||
|
gen = this.gen;
|
||||||
|
worldID = this.worldID;
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void Deconstruct(out int id, out int worldID)
|
||||||
|
{
|
||||||
|
id = this.id;
|
||||||
|
worldID = this.worldID;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Operators
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static bool operator ==(EntitySlotInfo a, EntitySlotInfo b) { return a.full == b.full; }
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static bool operator !=(EntitySlotInfo a, EntitySlotInfo b) { return a.full != b.full; }
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static explicit operator EntitySlotInfo(entlong a) { return new EntitySlotInfo(a._full); }
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static explicit operator entlong(EntitySlotInfo a) { return new entlong(a.full); }
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Other
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public override int GetHashCode() { return unchecked(id ^ gen ^ (worldID * EcsConsts.MAGIC_PRIME)); }
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public override string ToString() { return $"slot(id:{id} g:{gen} w:{worldID} {(State == StateFlag.Null ? "null" : State == StateFlag.Alive ? "alive" : "not alive")})"; }
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public override bool Equals(object obj) { return obj is EntitySlotInfo other && this == other; }
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public bool Equals(EntitySlotInfo other) { return this == other; }
|
||||||
|
|
||||||
|
public enum StateFlag { Null, Dead, Alive, }
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
internal class EntityDebuggerProxy
|
||||||
|
{
|
||||||
|
private List<object> _componentsList = new List<object>();
|
||||||
|
private EntitySlotInfo _info;
|
||||||
|
public long full { get { return _info.full; } }
|
||||||
|
public int id { get { return _info.id; } }
|
||||||
|
public short gen { get { return _info.gen; } }
|
||||||
|
public short worldID { get { return _info.worldID; } }
|
||||||
|
public EntitySlotInfo.StateFlag State { get { return _info.State; } }
|
||||||
|
public EcsWorld World { get { return _info.World; } }
|
||||||
|
public IEnumerable<object> Components
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (State == EntitySlotInfo.StateFlag.Alive)
|
||||||
|
{
|
||||||
|
World.GetComponentsFor(id, _componentsList);
|
||||||
|
return _componentsList;
|
||||||
|
}
|
||||||
|
return Array.Empty<object>();
|
||||||
|
}
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (State == EntitySlotInfo.StateFlag.Alive)
|
||||||
|
{
|
||||||
|
foreach (var component in value)
|
||||||
|
{
|
||||||
|
if (component == null) { continue; }
|
||||||
|
var componentType = component.GetType();
|
||||||
|
var world = World;
|
||||||
|
|
||||||
|
if (componentType.IsValueType && world.TryFindPoolInstance(componentType, out IEcsPool pool))
|
||||||
|
{
|
||||||
|
pool.SetRaw(id, component);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public EntityDebuggerProxy(EntitySlotInfo info)
|
||||||
|
{
|
||||||
|
_info = info;
|
||||||
|
}
|
||||||
|
public EntityDebuggerProxy(int entityID, short gen, short worldID)
|
||||||
|
{
|
||||||
|
_info = new EntitySlotInfo(entityID, gen, worldID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
2
src/Utils/Uncheked/EntitySlotInfo.cs.meta
Normal file
2
src/Utils/Uncheked/EntitySlotInfo.cs.meta
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 76b422b663e6c9d488b5eb4fac26de61
|
@ -1,13 +1,13 @@
|
|||||||
#if DISABLE_DEBUG
|
#if DISABLE_DEBUG
|
||||||
#undef DEBUG
|
#undef DEBUG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS.UncheckedCore
|
namespace DCFApixels.DragonECS.UncheckedCore
|
||||||
{
|
{
|
||||||
|
[Obsolete("Use DCFApixels.DragonECS.Core.UncheckedUtility")]
|
||||||
public static class UncheckedCoreUtility
|
public static class UncheckedCoreUtility
|
||||||
{
|
{
|
||||||
#region CreateEntLong
|
#region CreateEntLong
|
||||||
@ -70,42 +70,70 @@ namespace DCFApixels.DragonECS.UncheckedCore
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public readonly struct EntitiesMatrix
|
namespace DCFApixels.DragonECS.Core.Unchecked
|
||||||
{
|
{
|
||||||
private readonly EcsWorld _world;
|
public static class UncheckedUtility
|
||||||
public EntitiesMatrix(EcsWorld world)
|
|
||||||
{
|
{
|
||||||
_world = world;
|
#region CreateEntLong
|
||||||
}
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public int PoolsCount
|
public static entlong CreateEntLong(int entityID, short gen, short worldID)
|
||||||
{
|
{
|
||||||
get { return _world.PoolsCount; }
|
return new entlong(entityID, gen, worldID);
|
||||||
}
|
}
|
||||||
public int EntitesCount
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static entlong CreateEntLong(long entityGenWorld)
|
||||||
{
|
{
|
||||||
get { return _world.Capacity; }
|
return new entlong(entityGenWorld);
|
||||||
}
|
}
|
||||||
public int GetEntityComponentsCount(int entityID)
|
#endregion
|
||||||
|
|
||||||
|
#region CreateSpan
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static EcsSpan CreateSpan(short worldID, ReadOnlySpan<int> entitesArray)
|
||||||
{
|
{
|
||||||
return _world.GetComponentsCount(entityID);
|
return new EcsSpan(worldID, entitesArray);
|
||||||
}
|
}
|
||||||
public int GetEntityGen(int entityID)
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static EcsSpan CreateSpan(short worldID, int[] entitesArray, int startIndex, int length)
|
||||||
{
|
{
|
||||||
return _world.GetGen(entityID);
|
return new EcsSpan(worldID, entitesArray, startIndex, length);
|
||||||
}
|
}
|
||||||
public bool IsEntityUsed(int entityID)
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static EcsSpan CreateSpan(short worldID, int[] entitesArray, int length)
|
||||||
{
|
{
|
||||||
return _world.IsUsed(entityID);
|
return new EcsSpan(worldID, entitesArray, length);
|
||||||
}
|
}
|
||||||
public bool this[int entityID, int poolID]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static EcsSpan CreateSpan(short worldID, int[] entitesArray)
|
||||||
{
|
{
|
||||||
get
|
return new EcsSpan(worldID, entitesArray);
|
||||||
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static EcsSpan CreateEmptySpan(short worldID)
|
||||||
{
|
{
|
||||||
int entityStartChunkIndex = entityID << _world._entityComponentMaskLengthBitShift;
|
return new EcsSpan(worldID, Array.Empty<int>());
|
||||||
var chunkInfo = EcsMaskChunck.FromID(poolID);
|
}
|
||||||
return (_world._entityComponentMasks[entityStartChunkIndex + chunkInfo.chunkIndex] & chunkInfo.mask) != 0;
|
public static bool CheckSpanValideDebug(EcsSpan span)
|
||||||
|
{
|
||||||
|
HashSet<int> set = new HashSet<int>();
|
||||||
|
foreach (var e in span)
|
||||||
|
{
|
||||||
|
if (set.Add(e) == false)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region EcsGroup
|
||||||
|
public static EcsGroup GetSourceInstance(EcsReadonlyGroup group)
|
||||||
|
{
|
||||||
|
return group.GetSource_Internal();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
155
src/entlong.cs
155
src/entlong.cs
@ -3,9 +3,9 @@
|
|||||||
#endif
|
#endif
|
||||||
#pragma warning disable IDE1006
|
#pragma warning disable IDE1006
|
||||||
#pragma warning disable CS8981
|
#pragma warning disable CS8981
|
||||||
|
using DCFApixels.DragonECS.Core.Unchecked;
|
||||||
using DCFApixels.DragonECS.Internal;
|
using DCFApixels.DragonECS.Internal;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
@ -54,6 +54,11 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get { return _full == 0L; }
|
get { return _full == 0L; }
|
||||||
}
|
}
|
||||||
|
public bool IsDeadOrNull
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
get { return IsAlive == false; }
|
||||||
|
}
|
||||||
public int ID
|
public int ID
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
@ -370,152 +375,20 @@ namespace DCFApixels.DragonECS
|
|||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool Equals(long other) { return _full == other; }
|
public bool Equals(long other) { return _full == other; }
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public int CompareTo(entlong other)
|
public int CompareTo(entlong other) { return Compare(_id, other._id); }
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static int Compare(entlong left, entlong right) { return left.CompareTo(right); }
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static int Compare(int left, int right)
|
||||||
{
|
{
|
||||||
// NOTE: Because _id cannot be less than 0,
|
// NOTE: Because _id cannot be less than 0,
|
||||||
// the case “_id - other._id > MaxValue” is impossible.
|
// the case “_id - other._id > MaxValue” is impossible.
|
||||||
return _id - other._id;
|
return left - right;
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static int Compare(entlong left, entlong right) { return left.CompareTo(right); }
|
|
||||||
|
|
||||||
|
internal class DebuggerProxy : EntityDebuggerProxy
|
||||||
internal class DebuggerProxy
|
|
||||||
{
|
{
|
||||||
private List<object> _componentsList = new List<object>();
|
public DebuggerProxy(entlong entity) : base(entity._id, entity._gen, entity._world) { }
|
||||||
private entlong _value;
|
|
||||||
public long full { get { return _value._full; } }
|
|
||||||
public int id { get { return _value._id; } }
|
|
||||||
public short gen { get { return _value._gen; } }
|
|
||||||
public short world { get { return _value._world; } }
|
|
||||||
public EntState State { get { return _value.IsNull ? EntState.Null : _value.IsAlive ? EntState.Alive : EntState.Dead; } }
|
|
||||||
public EcsWorld EcsWorld { get { return EcsWorld.GetWorld(world); } }
|
|
||||||
public IEnumerable<object> components
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
_value.World.GetComponentsFor(_value.ID, _componentsList);
|
|
||||||
return _componentsList;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public DebuggerProxy(entlong value)
|
|
||||||
{
|
|
||||||
_value = value;
|
|
||||||
}
|
|
||||||
public DebuggerProxy(EntitySlotInfo value)
|
|
||||||
{
|
|
||||||
_value = new entlong(value.id, value.gen, value.world);
|
|
||||||
}
|
|
||||||
public enum EntState { Null, Dead, Alive, }
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
|
||||||
{
|
|
||||||
[DebuggerTypeProxy(typeof(DebuggerProxy))]
|
|
||||||
public readonly struct EntitySlotInfo : IEquatable<EntitySlotInfo>
|
|
||||||
{
|
|
||||||
private readonly long _full;
|
|
||||||
public readonly int id;
|
|
||||||
public readonly short gen;
|
|
||||||
public readonly short world;
|
|
||||||
|
|
||||||
#region Properties
|
|
||||||
private EcsWorld World { get { return EcsWorld.GetWorld(world); } }
|
|
||||||
private EntState State { get { return _full == 0 ? EntState.Null : World.IsAlive(id, gen) ? EntState.Alive : EntState.Dead; } }
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Constructors
|
|
||||||
public EntitySlotInfo(long full)
|
|
||||||
{
|
|
||||||
unchecked
|
|
||||||
{
|
|
||||||
ulong ufull = (ulong)full;
|
|
||||||
id = (int)((ufull >> 0) & 0x0000_0000_FFFF_FFFF);
|
|
||||||
gen = (short)((ufull >> 32) & 0x0000_0000_0000_FFFF);
|
|
||||||
world = (short)((ufull >> 48) & 0x0000_0000_0000_FFFF);
|
|
||||||
_full = full;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public EntitySlotInfo(int id, short gen, short world)
|
|
||||||
{
|
|
||||||
this.id = id;
|
|
||||||
this.gen = gen;
|
|
||||||
this.world = world;
|
|
||||||
_full = ((long)world << 48 | (long)gen << 32 | (long)id);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Operators
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static bool operator ==(EntitySlotInfo a, EntitySlotInfo b)
|
|
||||||
{
|
|
||||||
return a.id == b.id &&
|
|
||||||
a.gen == b.gen &&
|
|
||||||
a.world == b.world;
|
|
||||||
}
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static bool operator !=(EntitySlotInfo a, EntitySlotInfo b)
|
|
||||||
{
|
|
||||||
return a.id != b.id ||
|
|
||||||
a.gen != b.gen ||
|
|
||||||
a.world != b.world;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Other
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public override int GetHashCode() { return unchecked(id ^ gen ^ (world * EcsConsts.MAGIC_PRIME)); }
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public override string ToString() { return $"slot(id:{id} g:{gen} w:{world} {(State == EntState.Null ? "null" : State == EntState.Alive ? "alive" : "not alive")})"; }
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public override bool Equals(object obj) { return obj is EntitySlotInfo other && this == other; }
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public bool Equals(EntitySlotInfo other) { return this == other; }
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public void Deconstruct(out int id, out int gen, out int world)
|
|
||||||
{
|
|
||||||
id = this.id;
|
|
||||||
gen = this.gen;
|
|
||||||
world = this.world;
|
|
||||||
}
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public void Deconstruct(out int id, out int world)
|
|
||||||
{
|
|
||||||
id = this.id;
|
|
||||||
world = this.world;
|
|
||||||
}
|
|
||||||
public enum EntState { Null, Dead, Alive, }
|
|
||||||
internal class DebuggerProxy
|
|
||||||
{
|
|
||||||
private List<object> _componentsList = new List<object>();
|
|
||||||
private EntitySlotInfo _source;
|
|
||||||
public long full { get { return _source._full; } }
|
|
||||||
public int id { get { return _source.id; } }
|
|
||||||
public short gen { get { return _source.gen; } }
|
|
||||||
public short world { get { return _source.world; } }
|
|
||||||
public EntState State { get { return _source.State; } }
|
|
||||||
public EcsWorld World { get { return _source.World; } }
|
|
||||||
public IEnumerable<object> Components
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (State == EntState.Alive)
|
|
||||||
{
|
|
||||||
World.GetComponentsFor(id, _componentsList);
|
|
||||||
return _componentsList;
|
|
||||||
}
|
|
||||||
return Array.Empty<object>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public DebuggerProxy(EntitySlotInfo value)
|
|
||||||
{
|
|
||||||
_source = value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user