mirror of
https://github.com/DCFApixels/DragonECS-Graphs.git
synced 2025-11-13 02:25:54 +08:00
fixes & update
This commit is contained in:
parent
22d873ed38
commit
9c50a88266
@ -1,4 +1,11 @@
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public sealed class EcsArcWorld : EcsWorld { }
|
||||
public abstract class EcsArcWorld : EcsWorld { }
|
||||
public sealed class EcsLoopArcWorld<TWorld> : EcsArcWorld
|
||||
where TWorld : EcsWorld
|
||||
{ }
|
||||
public sealed class EcsArcWorld<TStartWorld, TEndWorld> : EcsArcWorld
|
||||
where TStartWorld : EcsWorld
|
||||
where TEndWorld : EcsWorld
|
||||
{ }
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using DCFApixels.DragonECS.Relations.Internal;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using static DCFApixels.DragonECS.Relations.Utils.EcsJoin;
|
||||
@ -41,7 +42,7 @@ namespace DCFApixels.DragonECS.Relations.Utils
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get { return _source.IsLoopArc; }
|
||||
}
|
||||
public EnumerableArcEnd this[int startEntityID]
|
||||
public EnumerableRelEnd this[int startEntityID]
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get { return _source[startEntityID]; }
|
||||
@ -61,7 +62,7 @@ namespace DCFApixels.DragonECS.Relations.Utils
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool HasEnd(int endEntityID) { return _source.HasEnd(endEntityID); }
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public EnumerableArcEnd GetRelEnds(int startEntityID) { return _source.GetRelEnds(startEntityID); }
|
||||
public EnumerableRelEnd GetRelEnds(int startEntityID) { return _source.GetRelEnds(startEntityID); }
|
||||
#endregion
|
||||
|
||||
#region Internal
|
||||
@ -92,7 +93,7 @@ namespace DCFApixels.DragonECS.Relations.Utils
|
||||
|
||||
private readonly BasketList _startBaskets;
|
||||
private readonly BasketList _endBaskets;
|
||||
private readonly RelInfo[] _relMapping;
|
||||
private readonly RelNodesInfo[] _relNodesMapping;
|
||||
|
||||
#region Properties
|
||||
public EcsReadonlyJoin Readonly
|
||||
@ -131,7 +132,7 @@ namespace DCFApixels.DragonECS.Relations.Utils
|
||||
get { return _isLoop; }
|
||||
}
|
||||
|
||||
public EnumerableArcEnd this[int startEntityID]
|
||||
public EnumerableRelEnd this[int startEntityID]
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get { return GetRelEnds(startEntityID); }
|
||||
@ -145,60 +146,52 @@ namespace DCFApixels.DragonECS.Relations.Utils
|
||||
_isLoop = arc.IsLoop;
|
||||
|
||||
_startBaskets = new BasketList();
|
||||
if (_isLoop)
|
||||
{
|
||||
_endBaskets = _startBaskets;
|
||||
}
|
||||
else
|
||||
{
|
||||
//if (_isLoop)
|
||||
//{
|
||||
// _endBaskets = _startBaskets;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// _endBaskets = new BasketList();
|
||||
//}
|
||||
_endBaskets = new BasketList();
|
||||
}
|
||||
_relMapping = new RelInfo[arc.ArcWorld.Capacity];
|
||||
|
||||
_relNodesMapping = new RelNodesInfo[arc.ArcWorld.Capacity];
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Add/Del
|
||||
public void Add(int relEntityID)
|
||||
{
|
||||
var (startEntityID, endEntityID) = _source.GetRelInfo(relEntityID);
|
||||
ref RelInfo arcInfo = ref _relMapping[relEntityID];
|
||||
var (startEntityID, endEntityID) = _source.GetRelationInfo(relEntityID);
|
||||
ref RelNodesInfo arcInfo = ref _relNodesMapping[relEntityID];
|
||||
|
||||
arcInfo.startNodeIndex = _startBaskets.AddToBasket(startEntityID, relEntityID);
|
||||
if (_isLoop)
|
||||
{
|
||||
arcInfo.endNodeIndex = arcInfo.startNodeIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
arcInfo.endNodeIndex = _endBaskets.AddToBasket(endEntityID, relEntityID);
|
||||
}
|
||||
|
||||
//arcInfo.endNodeIndex = _endBaskets.AddToBasket(endEntityID, relEntityID);
|
||||
//if (!_isLoop)
|
||||
//if (_isLoop)
|
||||
//{
|
||||
// arcInfo.startNodeIndex = _startBaskets.AddToBasket(startEntityID, relEntityID);
|
||||
// arcInfo.endNodeIndex = arcInfo.startNodeIndex;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// arcInfo.startNodeIndex = arcInfo.endNodeIndex;
|
||||
arcInfo.endNodeIndex = _endBaskets.AddToBasket(endEntityID, relEntityID);
|
||||
//}
|
||||
}
|
||||
public void Del(int relEntityID)
|
||||
{
|
||||
var (startEntityID, endEntityID) = _source.GetRelInfo(relEntityID);
|
||||
ref RelInfo relInfo = ref _relMapping[relEntityID];
|
||||
var (startEntityID, endEntityID) = _source.GetRelationInfo(relEntityID);
|
||||
ref RelNodesInfo relInfo = ref _relNodesMapping[relEntityID];
|
||||
_startBaskets.RemoveFromBasket(startEntityID, relInfo.startNodeIndex);
|
||||
if (!_isLoop)
|
||||
{
|
||||
//if (!_isLoop)
|
||||
//{
|
||||
_startBaskets.RemoveFromBasket(endEntityID, relInfo.endNodeIndex);
|
||||
}
|
||||
//}
|
||||
}
|
||||
public void DelStart(int startEntityID)
|
||||
{
|
||||
foreach (var relEntityID in _startBaskets.GetBasketIterator(startEntityID))
|
||||
{
|
||||
var endEntityID = _source.GetRelEnd(relEntityID);
|
||||
ref RelInfo relInfo = ref _relMapping[relEntityID];
|
||||
ref RelNodesInfo relInfo = ref _relNodesMapping[relEntityID];
|
||||
_endBaskets.RemoveFromBasket(endEntityID, relInfo.startNodeIndex);
|
||||
}
|
||||
_startBaskets.RemoveBasket(startEntityID);
|
||||
@ -208,17 +201,75 @@ namespace DCFApixels.DragonECS.Relations.Utils
|
||||
foreach (var relEntityID in _endBaskets.GetBasketIterator(endEntityID))
|
||||
{
|
||||
var startEntityID = _source.GetRelStart(relEntityID);
|
||||
ref RelInfo relInfo = ref _relMapping[relEntityID];
|
||||
ref RelNodesInfo relInfo = ref _relNodesMapping[relEntityID];
|
||||
_startBaskets.RemoveFromBasket(startEntityID, relInfo.endNodeIndex);
|
||||
}
|
||||
_endBaskets.RemoveBasket(endEntityID);
|
||||
}
|
||||
|
||||
|
||||
private void DelStartAndDelRelEntities(int startEntityID, EcsArc arc)
|
||||
{
|
||||
|
||||
foreach (var relEntityID in _startBaskets.GetBasketIterator(startEntityID))
|
||||
{
|
||||
int endEntityID = _source.GetRelEnd(relEntityID);
|
||||
int endNodeIndex = _relNodesMapping[relEntityID].endNodeIndex;
|
||||
int revereceRelEntitiy = _endBaskets.Get(endNodeIndex);
|
||||
|
||||
//_endBaskets.RemoveFromBasket(endEntityID, endNodeIndex);
|
||||
|
||||
arc.ArcWorld.DelEntity(relEntityID);
|
||||
//if(!_isLoop)
|
||||
arc.ArcWorld.DelEntity(revereceRelEntitiy);
|
||||
}
|
||||
//_startBaskets.RemoveBasket(startEntityID);
|
||||
}
|
||||
private void DelEndAndDelRelEntities(int endEntityID, EcsArc arc)
|
||||
{
|
||||
foreach (var relEntityID in _endBaskets.GetBasketIterator(endEntityID))
|
||||
{
|
||||
int startEntityID = _source.GetRelStart(relEntityID);
|
||||
int startNodeIndex = _relNodesMapping[relEntityID].startNodeIndex;
|
||||
int revereceRelEntitiy = _startBaskets.Get(startNodeIndex);
|
||||
|
||||
//_startBaskets.RemoveFromBasket(startEntityID, startNodeIndex);
|
||||
|
||||
arc.ArcWorld.DelEntity(relEntityID);
|
||||
//if(!_isLoop)
|
||||
arc.ArcWorld.DelEntity(revereceRelEntitiy);
|
||||
}
|
||||
//_endBaskets.RemoveBasket(endEntityID);
|
||||
}
|
||||
public struct FriendEcsArc
|
||||
{
|
||||
private EcsJoin _join;
|
||||
public FriendEcsArc(EcsArc arc, EcsJoin join)
|
||||
{
|
||||
if (arc.IsInit_Internal != false)
|
||||
{
|
||||
Throw.UndefinedException();
|
||||
}
|
||||
_join = join;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void DelStartAndDelRelEntities(int startEntityID, EcsArc arc)
|
||||
{
|
||||
_join.DelStartAndDelRelEntities(startEntityID, arc);
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void DelEndAndDelRelEntities(int endEntityID, EcsArc arc)
|
||||
{
|
||||
_join.DelEndAndDelRelEntities(endEntityID, arc);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Has
|
||||
public bool Has(int relEntityID)
|
||||
{
|
||||
return _relMapping[relEntityID] != RelInfo.Empty;
|
||||
return _relNodesMapping[relEntityID] != RelNodesInfo.Empty;
|
||||
}
|
||||
public bool HasStart(int startEntityID)
|
||||
{
|
||||
@ -243,19 +294,19 @@ namespace DCFApixels.DragonECS.Relations.Utils
|
||||
|
||||
#region GetRelEnds
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public EnumerableArcEnd GetRelEnds(int startEntityID)
|
||||
public EnumerableRelEnd GetRelEnds(int startEntityID)
|
||||
{
|
||||
return new EnumerableArcEnd(_source, _startBaskets.GetBasketIterator(startEntityID).GetEnumerator());
|
||||
return new EnumerableRelEnd(_source, _startBaskets.GetBasketIterator(startEntityID).GetEnumerator());
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region EnumerableArcEnd
|
||||
public readonly ref struct EnumerableArcEnd //: IEnumerable<RelEnd>
|
||||
public readonly ref struct EnumerableRelEnd //: IEnumerable<RelEnd>
|
||||
{
|
||||
private readonly EcsArc _arc;
|
||||
private readonly BasketList.BasketIterator.Enumerator _iterator;
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal EnumerableArcEnd(EcsArc arc, BasketList.BasketIterator.Enumerator iterator)
|
||||
internal EnumerableRelEnd(EcsArc arc, BasketList.BasketIterator.Enumerator iterator)
|
||||
{
|
||||
_arc = arc;
|
||||
_iterator = iterator;
|
||||
@ -295,19 +346,19 @@ namespace DCFApixels.DragonECS.Relations.Utils
|
||||
#endregion
|
||||
|
||||
#region ArcInfo
|
||||
private struct RelInfo : IEquatable<RelInfo>
|
||||
private struct RelNodesInfo : IEquatable<RelNodesInfo>
|
||||
{
|
||||
public readonly static RelInfo Empty = default;
|
||||
public readonly static RelNodesInfo Empty = default;
|
||||
public int startNodeIndex;
|
||||
public int endNodeIndex;
|
||||
|
||||
#region Object
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is RelInfo && Equals((RelInfo)obj);
|
||||
return obj is RelNodesInfo && Equals((RelNodesInfo)obj);
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(RelInfo other)
|
||||
public bool Equals(RelNodesInfo other)
|
||||
{
|
||||
return startNodeIndex == other.startNodeIndex &&
|
||||
endNodeIndex == other.endNodeIndex;
|
||||
@ -321,9 +372,9 @@ namespace DCFApixels.DragonECS.Relations.Utils
|
||||
|
||||
#region operators
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator ==(RelInfo a, RelInfo b) => a.startNodeIndex == b.startNodeIndex && a.endNodeIndex == b.endNodeIndex;
|
||||
public static bool operator ==(RelNodesInfo a, RelNodesInfo b) => a.startNodeIndex == b.startNodeIndex && a.endNodeIndex == b.endNodeIndex;
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static bool operator !=(RelInfo a, RelInfo b) => a.startNodeIndex != b.startNodeIndex || a.endNodeIndex != b.endNodeIndex;
|
||||
public static bool operator !=(RelNodesInfo a, RelNodesInfo b) => a.startNodeIndex != b.startNodeIndex || a.endNodeIndex != b.endNodeIndex;
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
|
||||
194
src/EcsArc.cs
194
src/EcsArc.cs
@ -1,4 +1,5 @@
|
||||
using DCFApixels.DragonECS.Relations.Utils;
|
||||
using DCFApixels.DragonECS.Relations.Internal;
|
||||
using DCFApixels.DragonECS.Relations.Utils;
|
||||
using Leopotam.EcsLite;
|
||||
using System;
|
||||
using System.Runtime.CompilerServices;
|
||||
@ -22,12 +23,20 @@ namespace DCFApixels.DragonECS
|
||||
private readonly SparseArray64<int> _relationsMatrix = new SparseArray64<int>();
|
||||
|
||||
private EcsJoin _joinEntities;
|
||||
private EcsJoin.FriendEcsArc _joinEntitiesFriend;
|
||||
|
||||
private EcsGroup _relEntities;
|
||||
private RelEntityInfo[] _relEntityInfos; //N * (N - 1) / 2
|
||||
|
||||
private bool _isLoop;
|
||||
private bool _isInit = false;
|
||||
|
||||
#region Properties
|
||||
internal bool IsInit_Internal
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get { return _isInit; }
|
||||
}
|
||||
public EcsWorld StartWorld
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@ -65,7 +74,7 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
#region Constructors/Destroy
|
||||
internal EcsArc(EcsWorld startWorld, EcsWorld endWorld, EcsArcWorld arcWorld)
|
||||
{
|
||||
_startWorld = startWorld;
|
||||
@ -85,15 +94,27 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
_relEntities = EcsGroup.New(_arcWorld);
|
||||
_joinEntities = new EcsJoin(this);
|
||||
|
||||
_joinEntitiesFriend = new EcsJoin.FriendEcsArc(this, _joinEntities);
|
||||
_isInit = true;
|
||||
}
|
||||
public void Destroy()
|
||||
{
|
||||
_startWorldHandler.Destroy();
|
||||
_arcWorldHandler.Destroy();
|
||||
//if (!_isLoop)
|
||||
//{
|
||||
_endWorldHandler.Destroy();
|
||||
//}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region New/Del
|
||||
public int NewRelation(int startEntityID, int endEntityID)
|
||||
{
|
||||
if (Has(startEntityID, endEntityID))
|
||||
if (HasRelation(startEntityID, endEntityID))
|
||||
{
|
||||
throw new EcsRelationException();
|
||||
Throw.UndefinedRelationException();
|
||||
}
|
||||
|
||||
int relEntity = _arcWorld.NewEntity();
|
||||
@ -106,61 +127,99 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
public void DelRelation(int startEntityID, int endEntityID)
|
||||
{
|
||||
if (!_relationsMatrix.TryGetValue(startEntityID, endEntityID, out int relEntity))
|
||||
if (_relationsMatrix.TryGetValue(startEntityID, endEntityID, out int relEntity))
|
||||
{
|
||||
throw new EcsRelationException();
|
||||
}
|
||||
_joinEntities.Del(relEntity);
|
||||
|
||||
_relationsMatrix.Remove(startEntityID, endEntityID);
|
||||
_arcWorld.DelEntity(relEntity);
|
||||
}
|
||||
else
|
||||
{
|
||||
Throw.UndefinedRelationException();
|
||||
}
|
||||
//if (!_relationsMatrix.TryGetValue(startEntityID, endEntityID, out int relEntity))
|
||||
//{
|
||||
// Throw.UndefinedRelationException();
|
||||
//}
|
||||
//_joinEntities.Del(relEntity);
|
||||
//
|
||||
//_relationsMatrix.Remove(startEntityID, endEntityID);
|
||||
//_arcWorld.DelEntity(relEntity);
|
||||
//
|
||||
//_relEntityInfos[relEntity] = RelEntityInfo.Empty;
|
||||
//_relEntities.Remove(relEntity);
|
||||
}
|
||||
|
||||
_relEntityInfos[relEntity] = RelEntityInfo.Empty;
|
||||
private void ClearRelation_Internal(int startEntityID, int endEntityID)
|
||||
{
|
||||
if (_relationsMatrix.TryGetValue(startEntityID, endEntityID, out int relEntity))
|
||||
{
|
||||
_relEntities.Remove(relEntity);
|
||||
_joinEntities.Del(relEntity);
|
||||
_relationsMatrix.Remove(startEntityID, endEntityID);
|
||||
_relEntityInfos[relEntity] = RelEntityInfo.Empty;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Get/Has
|
||||
public bool Has(int startEntityID, int endEntityID)
|
||||
#region GetRelation/HasRelation
|
||||
public bool HasRelation(int startEntityID, int endEntityID)
|
||||
{
|
||||
return _relationsMatrix.Contains(startEntityID, endEntityID);
|
||||
}
|
||||
public int Get(int startEntityID, int endEntityID)
|
||||
public int GetRelation(int startEntityID, int endEntityID)
|
||||
{
|
||||
if (!_relationsMatrix.TryGetValue(startEntityID, endEntityID, out int arcEntityID))
|
||||
throw new EcsRelationException();
|
||||
return arcEntityID;
|
||||
if (!_relationsMatrix.TryGetValue(startEntityID, endEntityID, out int relEntityID))
|
||||
{
|
||||
Throw.UndefinedRelationException();
|
||||
}
|
||||
public bool TryGet(int startEntityID, int endEntityID, out int arcEntityID)
|
||||
return relEntityID;
|
||||
}
|
||||
public bool TryGetRelation(int startEntityID, int endEntityID, out int relEntityID)
|
||||
{
|
||||
return _relationsMatrix.TryGetValue(startEntityID, endEntityID, out arcEntityID);
|
||||
return _relationsMatrix.TryGetValue(startEntityID, endEntityID, out relEntityID);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ArcEntityInfo
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool IsRel(int arcEntityID)
|
||||
public bool IsRelation(int relEntityID)
|
||||
{
|
||||
if (relEntityID <= 0 || relEntityID >= _relEntityInfos.Length)
|
||||
{
|
||||
if (arcEntityID <= 0 || arcEntityID >= _relEntityInfos.Length)
|
||||
return false;
|
||||
return !_relEntityInfos[arcEntityID].IsEmpty;
|
||||
}
|
||||
return !_relEntityInfos[relEntityID].IsEmpty;
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public RelEntityInfo GetRelInfo(int arcEntityID)
|
||||
public RelEntityInfo GetRelationInfo(int relEntityID)
|
||||
{
|
||||
if (arcEntityID <= 0 || arcEntityID >= _relEntityInfos.Length)
|
||||
throw new Exception();
|
||||
return _relEntityInfos[arcEntityID];
|
||||
if (relEntityID <= 0 || relEntityID >= _relEntityInfos.Length)
|
||||
{
|
||||
Throw.UndefinedException();
|
||||
}
|
||||
return _relEntityInfos[relEntityID];
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public int GetRelStart(int arcEntityID)
|
||||
public int GetRelStart(int relEntityID)
|
||||
{
|
||||
return GetRelInfo(arcEntityID).start;
|
||||
return GetRelationInfo(relEntityID).start;
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public int GetRelEnd(int arcEntityID)
|
||||
public int GetRelEnd(int relEntityID)
|
||||
{
|
||||
return GetRelInfo(arcEntityID).end;
|
||||
return GetRelationInfo(relEntityID).end;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public int GetInversedRelation(int relEntityID)
|
||||
{
|
||||
var (startEntityID, endEntityID) = GetRelationInfo(relEntityID);
|
||||
return GetRelation(endEntityID, startEntityID);
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool TryGetInversedRelation(int relEntityID, out int inversedRelEntityID)
|
||||
{
|
||||
var (startEntityID, endEntityID) = GetRelationInfo(relEntityID);
|
||||
return TryGetRelation(endEntityID, startEntityID, out inversedRelEntityID);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -177,87 +236,84 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
|
||||
#region VertexWorldHandler
|
||||
private class ArcWorldHandler : IEcsWorldEventListener, IEcsEntityEventListener
|
||||
private class ArcWorldHandler : IEcsWorldEventListener
|
||||
{
|
||||
private readonly EcsArc _arc;
|
||||
public ArcWorldHandler(EcsArc arc)
|
||||
{
|
||||
_arc = arc;
|
||||
EcsArcWorld arcWorld = arc.ArcWorld;
|
||||
arcWorld.AddListener(worldEventListener: this);
|
||||
arcWorld.AddListener(entityEventListener: this);
|
||||
_arc.ArcWorld.AddListener(this);
|
||||
}
|
||||
public void Destroy()
|
||||
{
|
||||
_arc.ArcWorld.RemoveListener(this);
|
||||
}
|
||||
|
||||
#region Callbacks
|
||||
public void OnDelEntity(int entityID) { }
|
||||
public void OnNewEntity(int entityID) { }
|
||||
public void OnReleaseDelEntityBuffer(ReadOnlySpan<int> buffer)
|
||||
public void OnReleaseDelEntityBuffer(ReadOnlySpan<int> relEntityBuffer)
|
||||
{
|
||||
foreach (var relEntityID in buffer)
|
||||
foreach (var relEntityID in relEntityBuffer)
|
||||
{
|
||||
ref RelEntityInfo rel = ref _arc._relEntityInfos[relEntityID];
|
||||
if (_arc._relationsMatrix.Contains(rel.start, rel.end))
|
||||
{
|
||||
_arc.DelRelation(rel.start, rel.end);
|
||||
var (startEntityID, endEntityID) = _arc._relEntityInfos[relEntityID];
|
||||
_arc.ClearRelation_Internal(startEntityID, endEntityID);
|
||||
}
|
||||
}
|
||||
_arc._arcWorld.ReleaseDelEntityBuffer(buffer.Length);
|
||||
}
|
||||
public void OnWorldDestroy() { }
|
||||
public void OnWorldResize(int newSize)
|
||||
public void OnWorldResize(int arcWorldNewSize)
|
||||
{
|
||||
Array.Resize(ref _arc._relEntityInfos, newSize);
|
||||
Array.Resize(ref _arc._relEntityInfos, arcWorldNewSize);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
private class StartWorldHandler : IEcsWorldEventListener, IEcsEntityEventListener
|
||||
private class StartWorldHandler : IEcsWorldEventListener
|
||||
{
|
||||
private readonly EcsArc _arc;
|
||||
public StartWorldHandler(EcsArc arc)
|
||||
{
|
||||
_arc = arc;
|
||||
EcsWorld startWorld = arc.StartWorld;
|
||||
startWorld.AddListener(worldEventListener: this);
|
||||
startWorld.AddListener(entityEventListener: this);
|
||||
_arc.StartWorld.AddListener(this);
|
||||
}
|
||||
public void Destroy()
|
||||
{
|
||||
_arc.StartWorld.RemoveListener(this);
|
||||
}
|
||||
|
||||
#region Callbacks
|
||||
public void OnDelEntity(int startEntityID) { }
|
||||
public void OnNewEntity(int startEntityID) { }
|
||||
public void OnReleaseDelEntityBuffer(ReadOnlySpan<int> buffer)
|
||||
public void OnReleaseDelEntityBuffer(ReadOnlySpan<int> startEntityBuffer)
|
||||
{
|
||||
foreach (var startEntityID in buffer)
|
||||
foreach (var startEntityID in startEntityBuffer)
|
||||
{
|
||||
_arc._joinEntities.DelStart(startEntityID);
|
||||
//_arc._joinEntities.DelStart(startEntityID);
|
||||
_arc._joinEntitiesFriend.DelStartAndDelRelEntities(startEntityID, _arc);
|
||||
}
|
||||
_arc._arcWorld.ReleaseDelEntityBuffer(startEntityBuffer.Length);
|
||||
}
|
||||
public void OnWorldDestroy() { }
|
||||
public void OnWorldResize(int newSize) { }
|
||||
public void OnWorldResize(int startWorldNewSize) { }
|
||||
#endregion
|
||||
}
|
||||
private class EndWorldHandler : IEcsWorldEventListener, IEcsEntityEventListener
|
||||
private class EndWorldHandler : IEcsWorldEventListener
|
||||
{
|
||||
private readonly EcsArc _arc;
|
||||
public EndWorldHandler(EcsArc arc)
|
||||
{
|
||||
_arc = arc;
|
||||
EcsWorld endWorld = arc.EndWorld;
|
||||
endWorld.AddListener(worldEventListener: this);
|
||||
endWorld.AddListener(entityEventListener: this);
|
||||
_arc.EndWorld.AddListener(this);
|
||||
}
|
||||
public void Destroy()
|
||||
{
|
||||
_arc.EndWorld.RemoveListener(this);
|
||||
}
|
||||
|
||||
#region Callbacks
|
||||
public void OnDelEntity(int endEntityID) { }
|
||||
public void OnNewEntity(int endEntityID) { }
|
||||
public void OnReleaseDelEntityBuffer(ReadOnlySpan<int> buffer)
|
||||
public void OnReleaseDelEntityBuffer(ReadOnlySpan<int> endEntityBuffer)
|
||||
{
|
||||
foreach (var endEntityID in buffer)
|
||||
foreach (var endEntityID in endEntityBuffer)
|
||||
{
|
||||
_arc._joinEntities.DelEnd(endEntityID);
|
||||
//_arc._joinEntities.DelEnd(endEntityID);
|
||||
_arc._joinEntitiesFriend.DelEndAndDelRelEntities(endEntityID, _arc);
|
||||
}
|
||||
_arc._arcWorld.ReleaseDelEntityBuffer(endEntityBuffer.Length);
|
||||
}
|
||||
public void OnWorldDestroy() { }
|
||||
public void OnWorldResize(int newSize) { }
|
||||
public void OnWorldResize(int endWorldNewSize) { }
|
||||
#endregion
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -16,7 +16,7 @@ namespace DCFApixels.DragonECS
|
||||
int endWorldID = endWorld.id;
|
||||
int arcWorldID = arcWorld.id;
|
||||
|
||||
if(_arcsMapping.Length <= arcWorldID)
|
||||
if (_arcsMapping.Length <= arcWorldID)
|
||||
{
|
||||
Array.Resize(ref _arcsMapping, arcWorldID + 4);
|
||||
}
|
||||
@ -32,6 +32,10 @@ namespace DCFApixels.DragonECS
|
||||
_arcsMapping[arcWorldID] = arc;
|
||||
return arc;
|
||||
}
|
||||
public static bool IsRegistered(EcsArc arc)
|
||||
{
|
||||
return Has(arc.StartWorld.id, arc.EndWorld.id);
|
||||
}
|
||||
private static void Unregister(EcsWorld startWorld, EcsWorld endWorld)
|
||||
{
|
||||
int startWorldID = startWorld.id;
|
||||
@ -39,20 +43,21 @@ namespace DCFApixels.DragonECS
|
||||
EcsArc arc = _matrix[startWorldID, endWorldID];
|
||||
_arcsMapping[arc.ArcWorld.id] = null;
|
||||
_matrix.Remove(startWorldID, endWorldID);
|
||||
arc.Destroy();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Get/Has
|
||||
// private static EcsArc GetOrRigister(EcsWorld startWorld, EcsWorld otherWorld)
|
||||
// {
|
||||
//#if DEBUG
|
||||
// if (!_matrix.Contains(startWorld.id, otherWorld.id))
|
||||
// {
|
||||
// return Register();
|
||||
// }
|
||||
//#endif
|
||||
// return _matrix[startWorld.id, otherWorld.id];
|
||||
// }
|
||||
// private static EcsArc GetOrRigister(EcsWorld startWorld, EcsWorld otherWorld)
|
||||
// {
|
||||
//#if DEBUG
|
||||
// if (!_matrix.Contains(startWorld.id, otherWorld.id))
|
||||
// {
|
||||
// return Register();
|
||||
// }
|
||||
//#endif
|
||||
// return _matrix[startWorld.id, otherWorld.id];
|
||||
// }
|
||||
private static EcsArc Get(EcsWorld startWorld, EcsWorld otherWorld)
|
||||
{
|
||||
#if DEBUG
|
||||
@ -63,8 +68,14 @@ namespace DCFApixels.DragonECS
|
||||
#endif
|
||||
return _matrix[startWorld.id, otherWorld.id];
|
||||
}
|
||||
private static bool Has(EcsWorld startWorld, EcsWorld endWorld) => Has(startWorld.id, endWorld.id);
|
||||
private static bool Has(int startWorldID, int endWorldID) => _matrix.Contains(startWorldID, endWorldID);
|
||||
private static bool Has(EcsWorld startWorld, EcsWorld endWorld)
|
||||
{
|
||||
return Has(startWorld.id, endWorld.id);
|
||||
}
|
||||
private static bool Has(int startWorldID, int endWorldID)
|
||||
{
|
||||
return _matrix.Contains(startWorldID, endWorldID);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Extension
|
||||
@ -84,7 +95,7 @@ namespace DCFApixels.DragonECS
|
||||
Throw.ArgumentNull();
|
||||
}
|
||||
int id = self.id;
|
||||
if(id < _arcsMapping.Length && _arcsMapping[self.id] == null)
|
||||
if (id < _arcsMapping.Length && _arcsMapping[self.id] == null)
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
@ -92,15 +103,45 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static EcsArc SetLoopArcAuto(this EcsWorld self) => SetArcAuto(self, self);
|
||||
public static EcsArc SetArcAuto(this EcsWorld start, EcsWorld end)
|
||||
public static EcsArc SetLoopArcAuto<TWorld>(this TWorld self, out EcsLoopArcWorld<TWorld> arcWorld)
|
||||
where TWorld : EcsWorld
|
||||
{
|
||||
if (self == null)
|
||||
{
|
||||
Throw.ArgumentNull();
|
||||
}
|
||||
if (typeof(TWorld) != self.GetType())
|
||||
{
|
||||
EcsDebug.PrintWarning($"{nameof(TWorld)} is not {self.GetType().Name}");
|
||||
}
|
||||
arcWorld = new EcsLoopArcWorld<TWorld>();
|
||||
return Register(self, self, arcWorld);
|
||||
}
|
||||
public static EcsArc SetArcAuto<TStartWorld, TEndWorld>(this TStartWorld start, TEndWorld end, out EcsArcWorld<TStartWorld, TEndWorld> arcWorld)
|
||||
where TStartWorld : EcsWorld
|
||||
where TEndWorld : EcsWorld
|
||||
{
|
||||
if (start == null || end == null)
|
||||
{
|
||||
Throw.ArgumentNull();
|
||||
}
|
||||
return Register(start, end, new EcsArcWorld());
|
||||
if (typeof(TStartWorld) == typeof(EcsWorld) && typeof(TEndWorld) == typeof(EcsWorld))
|
||||
{
|
||||
EcsDebug.PrintWarning($"{nameof(TStartWorld)} is not {start.GetType().Name} or {nameof(TEndWorld)} is not {end.GetType().Name}");
|
||||
}
|
||||
arcWorld = new EcsArcWorld<TStartWorld, TEndWorld>();
|
||||
return Register(start, end, arcWorld);
|
||||
}
|
||||
public static EcsArc SetLoopArcAuto<TWorld>(this TWorld self)
|
||||
where TWorld : EcsWorld
|
||||
{
|
||||
return SetLoopArcAuto(self, out _);
|
||||
}
|
||||
public static EcsArc SetArcAuto<TStartWorld, TEndWorld>(this TStartWorld start, TEndWorld end)
|
||||
where TStartWorld : EcsWorld
|
||||
where TEndWorld : EcsWorld
|
||||
{
|
||||
return SetArcAuto(start, end, out _);
|
||||
}
|
||||
|
||||
public static EcsArc SetLoopArc(this EcsWorld self, EcsArcWorld arc) => SetArc(self, self, arc);
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using DCFApixels.DragonECS.Relations.Internal;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
@ -42,16 +43,6 @@ namespace DCFApixels.DragonECS
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private void Resize(int newSize)
|
||||
{
|
||||
//int oldSize = _nodes.Length;
|
||||
//Array.Resize(ref _nodes, newSize);
|
||||
//int leftNode = newSize - 1;
|
||||
//for (int i = newSize - 1, n = oldSize; i >= n; i--)
|
||||
//{
|
||||
// Link(i, leftNode);
|
||||
// leftNode = i;
|
||||
//}
|
||||
//LinkToRecycled(newSize - 1, oldSize);
|
||||
|
||||
int oldSize = _nodes.Length;
|
||||
Array.Resize(ref _nodes, newSize);
|
||||
int leftNode = newSize - 1;
|
||||
@ -65,15 +56,6 @@ namespace DCFApixels.DragonECS
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private void Initialize(int newSize)
|
||||
{
|
||||
//_nodes = new Node[newSize];
|
||||
//int leftNode = newSize - 1;
|
||||
//for (int i = newSize - 1, n = 1; i >= n; i--)
|
||||
//{
|
||||
// Link(i, leftNode);
|
||||
// leftNode = i;
|
||||
//}
|
||||
//LinkToRecycled(newSize - 1, 1);
|
||||
|
||||
_nodes = new Node[newSize];
|
||||
int leftNode = newSize - 1;
|
||||
for (int i = 1; i < newSize; i++)
|
||||
@ -101,13 +83,6 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
return _nodes[nodeIndex].value;
|
||||
}
|
||||
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
//public ref readonly Node GetNode(int nodeIndex)
|
||||
//{
|
||||
// return ref _nodes[nodeIndex];
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@ -116,10 +91,15 @@ namespace DCFApixels.DragonECS
|
||||
#if DEBUG
|
||||
if (nodeIndex <= 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
//Throw.ArgumentOutOfRange();
|
||||
}
|
||||
#endif
|
||||
ref BasketInfo basketInfo = ref _baskets[basketIndex];
|
||||
|
||||
if (basketInfo.count <= 4)
|
||||
{
|
||||
|
||||
}
|
||||
ref var node = ref _nodes[nodeIndex];
|
||||
int nextNode = node.next;
|
||||
|
||||
@ -208,20 +188,18 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
ref Node endNode = ref _nodes[endNodeIndex];
|
||||
|
||||
if (_recycledListLast != -1)
|
||||
{
|
||||
//_nodes[_recycledListLast].next = startNodeIndex; //link recycled nodes;
|
||||
//startNode.prev = _recycledListLast;
|
||||
//_recycledListLast = endNodeIndex;
|
||||
Link(_recycledListLast, startNodeIndex);
|
||||
}
|
||||
_recycledListLast = endNodeIndex;
|
||||
|
||||
LinkToRecycled(startNodeIndex, endNodeIndex);
|
||||
Link(startNode.prev, endNode.next);
|
||||
|
||||
basket.count = 0;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private void UpBasketsSize(int minSize)
|
||||
{
|
||||
int newSize = GetHighBitNumber((uint)minSize) << 1;
|
||||
Array.Resize(ref _baskets, newSize);
|
||||
}
|
||||
private static int GetHighBitNumber(uint bits)
|
||||
{
|
||||
if (bits == 0)
|
||||
@ -256,32 +234,6 @@ namespace DCFApixels.DragonECS
|
||||
return bit;
|
||||
}
|
||||
|
||||
//public int NewBasket()
|
||||
//{
|
||||
// int newBasketIndex;
|
||||
// if(_recycledBusketsCount > 0)
|
||||
// {
|
||||
// newBasketIndex = _recycledBuskets[--_recycledBusketsCount];
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// newBasketIndex = _basketsCount;
|
||||
// if(_basketsCount >= _baskets.Length)
|
||||
// {
|
||||
// Array.Resize(ref _baskets, _baskets.Length << 1);
|
||||
// }
|
||||
// }
|
||||
// _basketsCount++;
|
||||
// _baskets[newBasketIndex] = BasketInfo.Empty;
|
||||
// return newBasketIndex;
|
||||
//}
|
||||
|
||||
public static void CreateCrossRef(int leftBasketIndex, int rightBasketIndex)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
#region Node
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 4, Size = 8)]
|
||||
public struct Node
|
||||
@ -324,8 +276,7 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
if (_baskets.Length <= basketIndex)
|
||||
{
|
||||
int newSize = GetHighBitNumber((uint)basketIndex) << 1;
|
||||
Array.Resize(ref _baskets, newSize);
|
||||
UpBasketsSize(basketIndex);
|
||||
}
|
||||
return new BasketIterator(this, basketIndex);
|
||||
}
|
||||
|
||||
@ -11,6 +11,21 @@ namespace DCFApixels.DragonECS.Relations.Internal
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void UndefinedException()
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void ArgumentOutOfRange()
|
||||
{
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void UndefinedRelationException()
|
||||
{
|
||||
throw new EcsRelationException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user