This commit is contained in:
Mikhail 2023-07-04 05:10:37 +08:00
parent c873ff08d7
commit 06aa34149c
4 changed files with 147 additions and 63 deletions

View File

@ -1,11 +1,10 @@
using DCFApixels.DragonECS.Relations.Utils;
using System;
using System;
using System.Diagnostics;
namespace DCFApixels.DragonECS
namespace DCFApixels.DragonECS.Relations.Utils
{
[DebuggerTypeProxy(typeof(DebuggerProxy))]
public class IdsBasket
internal class IdsBasket
{
private IdsLinkedList _headList = new IdsLinkedList(4);
private IdsLinkedList _valueList = new IdsLinkedList(4);
@ -83,6 +82,14 @@ namespace DCFApixels.DragonECS
else
return _headList.GetSpan(head.startNodeIndex, head.count);
}
public IdsLinkedList.LongSpan GetLongSpanFor(EcsWorld world, int value)
{
ref var head = ref _headMapping[value];
if (head.startNodeIndex <= 0)
return _headList.EmptyLongSpan(world);
else
return _headList.GetLongSpan(world, head.startNodeIndex, head.count);
}
private struct SpanInfo
{

View File

@ -1,5 +1,7 @@
using DCFApixels.DragonECS.Relations.Utils;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace DCFApixels.DragonECS
@ -158,9 +160,10 @@ namespace DCFApixels.DragonECS
public void BindRelation(int relationEntityID, int entityID, int otherEntityID) => _source.BindRelation(relationEntityID, entityID, otherEntityID);
public bool HasRelation(int entityID, int otherEntityID) => _source.HasRelation(entityID, otherEntityID);
public int GetRelation(int entityID, int otherEntityID) => _source.GetRelation(entityID, otherEntityID);
public void DelRelation(int entityID, int otherEntityID) => _source.DelRelation(entityID, otherEntityID);
public bool TryGetRelation(int entityID, int otherEntityID, out int relationEntityID) => _source.TryGetRelation(entityID, otherEntityID, out relationEntityID);
public IdsLinkedList.Span GetRelations(int entityID) => _source._basket.GetSpanFor(entityID);
public IdsLinkedList.LongSpan GetLongRelations(int entityID) => _source._basket.GetLongSpanFor(_source._world, entityID);
public void DelRelation(int entityID, int otherEntityID) => _source.DelRelation(entityID, otherEntityID);
}
public readonly struct ReverseOrientation
{
@ -170,16 +173,43 @@ namespace DCFApixels.DragonECS
public void BindRelation(int relationEntityID, int entityID, int otherEntityID) => _source.BindRelation(relationEntityID, otherEntityID, entityID);
public bool HasRelation(int otherEntityID, int entityID) => _source.HasRelation(entityID, otherEntityID);
public int GetRelation(int otherEntityID, int entityID) => _source.GetRelation(entityID, otherEntityID);
public void DelRelation(int otherEntityID, int entityID) => _source.DelRelation(entityID, otherEntityID);
public bool TryGetRelation(int otherEntityID, int entityID, out int relationEntityID) => _source.TryGetRelation(entityID, otherEntityID, out relationEntityID);
public IdsLinkedList.Span GetRelations(int otherEntityID) => _source._otherBasket.GetSpanFor(otherEntityID);
public IdsLinkedList.LongSpan GetLongRelations(int otherEntityID) => _source._otherBasket.GetLongSpanFor(_source._otherWorld, otherEntityID);
public void DelRelation(int otherEntityID, int entityID) => _source.DelRelation(entityID, otherEntityID);
}
public struct RelationsSpan
{
private readonly IdsBasket _basket;
private readonly EcsAspect _aspect;
}
//public readonly ref struct FilterIterator
//{
// private readonly IdsLinkedList.Span _listSpan;
// private readonly EcsMask _mask;
// public FilterIterator(EcsWorld world, IdsLinkedList.Span listSpan, EcsMask mask)
// {
// _listSpan = listSpan;
// _mask = mask;
// }
// public Enumerator GetEnumerator() => new Enumerator(_listSpan, _mask);
// public ref struct Enumerator
// {
// private readonly IdsLinkedList.SpanEnumerator _listEnumerator;
// private readonly EcsMask _mask;
// public Enumerator(IdsLinkedList.Span listSpan, EcsMask mask)
// {
// _listEnumerator = listSpan.GetEnumerator();
// _mask = mask;
// }
// public int Current => _listEnumerator.Current;
// public bool MoveNext()
// {
// while (_listEnumerator.MoveNext())
// {
// int e = _listEnumerator.Current;
// ...
// }
// return false;
// }
// }
//}
#endregion
}
}

View File

@ -130,16 +130,107 @@ namespace DCFApixels.DragonECS.Relations.Utils
public int Add(int id) => InsertAfter(_lastNodeIndex, id);
public ref readonly Node GetNode(int nodeIndex) => ref _nodes[nodeIndex];
#region Span/Enumerator
IEnumerator<int> IEnumerable<int>.GetEnumerator() => GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public SpanEnumerator GetEnumerator() => new SpanEnumerator(_nodes, _nodes[Head].next, _count);
public Span GetSpan(int startNodeIndex, int count) => new Span(this, startNodeIndex, count);
public Span EmptySpan() => new Span(this, 0, 0);
#region IEnumerable
IEnumerator<int> IEnumerable<int>.GetEnumerator() => GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public LongSpan GetLongs(EcsWorld world) => new LongSpan(world, this, _nodes[Head].next, _count);
public LongSpan GetLongSpan(EcsWorld world, int startNodeIndex, int count) => new LongSpan(world, this, startNodeIndex, count);
public LongSpan EmptyLongSpan(EcsWorld world) => new LongSpan(world, this, 0, 0);
public readonly ref struct Span
{
private readonly IdsLinkedList _source;
private readonly int _startNodeIndex;
private readonly int _count;
public Span(IdsLinkedList source, int startNodeIndex, int count)
{
_source = source;
_startNodeIndex = startNodeIndex;
_count = count;
}
public SpanEnumerator GetEnumerator() => new SpanEnumerator(_source._nodes, _startNodeIndex, _count);
}
public struct SpanEnumerator : IEnumerator<int>
{
private readonly Node[] _nodes;
private int _count;
private int _index;
private int _next;
public SpanEnumerator(Node[] nodes, int startIndex, int count)
{
_nodes = nodes;
_index = -1;
_count = count;
_next = startIndex;
}
public int Current => _nodes[_index].value;
object IEnumerator.Current => Current;
public bool MoveNext()
{
_index = _next;
_next = _nodes[_next].next;
return _index > 0 && _count-- > 0;
}
void IDisposable.Dispose() { }
void IEnumerator.Reset()
{
_index = -1;
_next = Head;
}
}
public readonly ref struct LongSpan
{
private readonly EcsWorld _world;
private readonly IdsLinkedList _source;
private readonly int _startNodeIndex;
private readonly int _count;
public LongSpan(EcsWorld world, IdsLinkedList source, int startNodeIndex, int count)
{
_world = world;
_source = source;
_startNodeIndex = startNodeIndex;
_count = count;
}
public LongSpanEnumerator GetEnumerator() => new LongSpanEnumerator(_world, _source._nodes, _startNodeIndex, _count);
}
public struct LongSpanEnumerator : IEnumerator<entlong>
{
private EcsWorld _world;
private readonly Node[] _nodes;
private int _count;
private int _index;
private int _next;
public LongSpanEnumerator(EcsWorld world, Node[] nodes, int startIndex, int count)
{
_world = world;
_nodes = nodes;
_index = -1;
_count = count;
_next = startIndex;
}
public entlong Current => _world.GetEntityLong(_nodes[_index].value);
object IEnumerator.Current => Current;
public bool MoveNext()
{
_index = _next;
_next = _nodes[_next].next;
return _index > 0 && _count-- > 0;
}
void IDisposable.Dispose() { }
void IEnumerator.Reset()
{
_index = -1;
_next = Head;
}
}
#endregion
#region Utils Node/Enumerator/Span
#region Node
[StructLayout(LayoutKind.Sequential, Pack = 4, Size = 8)]
public struct Node
{
@ -157,52 +248,6 @@ namespace DCFApixels.DragonECS.Relations.Utils
}
public override string ToString() => $"node({prev}<>{next} v:{value})";
}
#region Span/Enumerator
public readonly ref struct Span
{
private readonly IdsLinkedList _source;
private readonly int _startNodeIndex;
private readonly int _count;
public Span(IdsLinkedList source, int startNodeIndex, int count)
{
_source = source;
_startNodeIndex = startNodeIndex;
_count = count;
}
public SpanEnumerator GetEnumerator() => new SpanEnumerator(_source._nodes, _startNodeIndex, _count);
}
public struct SpanEnumerator : IEnumerator<int>
{
private readonly Node[] _nodes;
private int _index;
private int _count;
private int _next;
public SpanEnumerator(Node[] nodes, int startIndex, int count)
{
_nodes = nodes;
_index = -1;
_count = count;
_next = startIndex;
}
public int Current => _nodes[_index].value;
public bool MoveNext()
{
_index = _next;
_next = _nodes[_next].next;
return _index > 0 && _count-- > 0;
}
object IEnumerator.Current => Current;
void IDisposable.Dispose() { }
void IEnumerator.Reset()
{
_index = -1;
_next = Head;
}
}
#endregion
#endregion
#region Debug

View File

@ -17,6 +17,7 @@ namespace DCFApixels.DragonECS
#endif
EcsEdge edge = new EcsEdge(world, otherWorld, edgeWorld);
_matrix[worldID, otherWorldID] = edge;
_matrix[otherWorldID, worldID] = edge;
return edge;
}
internal static void Unregister(EcsWorld world, EcsWorld otherWorld)
@ -25,6 +26,7 @@ namespace DCFApixels.DragonECS
int otherWorldID = otherWorld.id;
//var manager = _matrix[worldID, otherWorldID];
_matrix.Remove(worldID, otherWorldID);
_matrix.Remove(otherWorldID, worldID);
}
internal static EcsEdge Get(EcsWorld world, EcsWorld otherWorld)
@ -64,8 +66,8 @@ namespace DCFApixels.DragonECS
WorldGraph.HasEdge(self, otherWorld);
}
public static EcsEdge GetEdgeWithSelf(this EcsWorld self) => GetRelationWith(self, self);
public static EcsEdge GetRelationWith(this EcsWorld self, EcsWorld otherWorld)
public static EcsEdge GetEdgeWithSelf(this EcsWorld self) => GetEdgeWith(self, self);
public static EcsEdge GetEdgeWith(this EcsWorld self, EcsWorld otherWorld)
{
if (self == null || otherWorld == null)
throw new ArgumentNullException();