fixes & update

This commit is contained in:
Mikhail 2024-01-31 04:25:48 +08:00
parent 22d873ed38
commit 9c50a88266
6 changed files with 325 additions and 204 deletions

View File

@ -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
{ }
}

View File

@ -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
{
_endBaskets = new BasketList();
}
_relMapping = new RelInfo[arc.ArcWorld.Capacity];
//if (_isLoop)
//{
// _endBaskets = _startBaskets;
//}
//else
//{
// _endBaskets = new BasketList();
//}
_endBaskets = new BasketList();
_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

View File

@ -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();
_arcWorld.DelEntity(relEntity);
}
_joinEntities.Del(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);
}
_relationsMatrix.Remove(startEntityID, endEntityID);
_arcWorld.DelEntity(relEntity);
_relEntityInfos[relEntity] = RelEntityInfo.Empty;
_relEntities.Remove(relEntity);
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();
}
return relEntityID;
}
public bool TryGet(int startEntityID, int endEntityID, out int arcEntityID)
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 (arcEntityID <= 0 || arcEntityID >= _relEntityInfos.Length)
if (relEntityID <= 0 || relEntityID >= _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);
}
#region Callbacks
public void OnDelEntity(int entityID) { }
public void OnNewEntity(int entityID) { }
public void OnReleaseDelEntityBuffer(ReadOnlySpan<int> buffer)
public void Destroy()
{
foreach (var relEntityID in buffer)
_arc.ArcWorld.RemoveListener(this);
}
#region Callbacks
public void OnReleaseDelEntityBuffer(ReadOnlySpan<int> relEntityBuffer)
{
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);
}
#region Callbacks
public void OnDelEntity(int startEntityID) { }
public void OnNewEntity(int startEntityID) { }
public void OnReleaseDelEntityBuffer(ReadOnlySpan<int> buffer)
public void Destroy()
{
foreach (var startEntityID in buffer)
_arc.StartWorld.RemoveListener(this);
}
#region Callbacks
public void OnReleaseDelEntityBuffer(ReadOnlySpan<int> startEntityBuffer)
{
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);
}
#region Callbacks
public void OnDelEntity(int endEntityID) { }
public void OnNewEntity(int endEntityID) { }
public void OnReleaseDelEntityBuffer(ReadOnlySpan<int> buffer)
public void Destroy()
{
foreach (var endEntityID in buffer)
_arc.EndWorld.RemoveListener(this);
}
#region Callbacks
public void OnReleaseDelEntityBuffer(ReadOnlySpan<int> endEntityBuffer)
{
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

View File

@ -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);

View File

@ -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);
}

View File

@ -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();
}
}
}