This commit is contained in:
Mikhail 2023-06-23 01:49:13 +08:00
parent 506b7e70f6
commit 4743f14791

View File

@ -24,10 +24,12 @@ namespace DCFApixels.DragonECS
private EcsWorld _world; private EcsWorld _world;
private EcsWorld _otherWorld; private EcsWorld _otherWorld;
private readonly IdsBasket _basket = new IdsBasket(256);
private readonly IdsBasket _otherBasket = new IdsBasket(256);
private SparseArray64<int> _relationsMatrix = new SparseArray64<int>(); private SparseArray64<int> _relationsMatrix = new SparseArray64<int>();
public readonly Orientation Forward; public readonly ForwardOrientation Forward;
public readonly Orientation Reverse; public readonly ReverseOrientation Reverse;
private RelationTargets[] _relationTargets; private RelationTargets[] _relationTargets;
@ -47,11 +49,8 @@ namespace DCFApixels.DragonECS
_relationWorld.AddListener(worldEventListener: this); _relationWorld.AddListener(worldEventListener: this);
_relationWorld.AddListener(entityEventListener: this); _relationWorld.AddListener(entityEventListener: this);
IdsBasket basket = new IdsBasket(256); Forward = new ForwardOrientation(this);
IdsBasket otherBasket = new IdsBasket(256); Reverse = new ReverseOrientation(this);
Forward = new Orientation(this, _relationsMatrix, relationWorld, basket, otherBasket, false);
Reverse = new Orientation(this, _relationsMatrix, relationWorld, otherBasket, basket, true);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -60,6 +59,76 @@ namespace DCFApixels.DragonECS
return ref _relationTargets[relationEntityID]; return ref _relationTargets[relationEntityID];
} }
#region Methods
#region New/Del
private int NewRelation(int entityID, int otherEntityID)
{
if (HasRelation(entityID, otherEntityID))
throw new EcsRelationException();
int e = _relationWorld.NewEmptyEntity();
_basket.AddToHead(entityID, otherEntityID);
_otherBasket.AddToHead(otherEntityID, entityID);
_relationsMatrix.Add(entityID, otherEntityID, e);
_relationTargets[e] = new RelationTargets(entityID, otherEntityID);
return e;
}
private void DelRelation(int entityID, int otherEntityID)
{
if (!_relationsMatrix.TryGetValue(entityID, otherEntityID, out int e))
throw new EcsRelationException();
_relationsMatrix.Remove(entityID, otherEntityID);
_basket.DelHead(entityID);
_otherBasket.Del(entityID);
_relationWorld.DelEntity(e);
_relationTargets[e] = RelationTargets.Empty;
}
#endregion
#region Has
private bool HasRelation(int entityID, int otherEntityID) => _relationsMatrix.Contains(entityID, otherEntityID);
//public bool HasRelationWith(EcsSubject subject, int entityID, int otherEntityID)
//{
// if (subject.World != _relationWorld)
// throw new ArgumentException();
// return _source._relationsMatrix.TryGetValue(entityID, otherEntityID, out int entity) && subject.IsMatches(entity);
//}
#endregion
#region GetRelation
private int GetRelation(int entityID, int otherEntityID)
{
if (!_relationsMatrix.TryGetValue(entityID, otherEntityID, out int e))
throw new EcsRelationException();
return e;
}
private bool TryGetRelation(int entityID, int otherEntityID, out int entity)
{
return _relationsMatrix.TryGetValue(entityID, otherEntityID, out entity);
}
//public bool TryGetRelation(EcsSubject subject, int entityID, int otherEntityID, out int entity)
//{
// return _source._relationsMatrix.TryGetValue(entityID, otherEntityID, out entity) && subject.IsMatches(entity);
//}
#endregion
//#region GetRelations
//private IdsLinkedList.Span GetRelations(int entityID)
//{
// return _basket.GetSpanFor(entityID);
//}
////ReadOnlySpan<int> временная заглушка, потому тут будет спан из линкедлиста
////public ReadOnlySpan<int> GetRelationsWith(EcsSubject subject, int entityID)
////{
//// if (subject.World != _relationWorld)
//// throw new ArgumentException();
//// throw new NotImplementedException();
////}
//#endregion
#endregion
#region Callbacks #region Callbacks
void IEcsWorldEventListener.OnWorldResize(int newSize) void IEcsWorldEventListener.OnWorldResize(int newSize)
{ {
@ -77,93 +146,29 @@ namespace DCFApixels.DragonECS
} }
#endregion #endregion
#region Orientation #region Orientation
public readonly struct Orientation public readonly struct ForwardOrientation
{ {
private readonly RelationManager _source; private readonly RelationManager _source;
internal ForwardOrientation(RelationManager source) => _source = source;
private readonly EcsWorld _relationWorld; public int NewRelation(int entityID, int otherEntityID) => _source.NewRelation(entityID, otherEntityID);
public void DelRelation(int entityID, int otherEntityID) => _source.DelRelation(entityID, otherEntityID);
private readonly IdsBasket _basket; public bool HasRelation(int entityID, int otherEntityID) => _source.HasRelation(entityID, otherEntityID);
private readonly IdsBasket _otherBasket; public int GetRelation(int entityID, int otherEntityID) => _source.GetRelation(entityID, otherEntityID);
public bool TryGetRelation(int entityID, int otherEntityID, out int relationEntityID) => _source.TryGetRelation(entityID, otherEntityID, out relationEntityID);
private readonly SparseArray64<int> _relationsMatrix; public IdsLinkedList.Span GetRelations(int relationEntityID) => _source._basket.GetSpanFor(relationEntityID);
}
private readonly bool _isReverce; public readonly struct ReverseOrientation
internal Orientation(RelationManager source, SparseArray64<int> relationsMatrix, EcsWorld relationWorld, IdsBasket basket, IdsBasket otherBasket, bool isReverce) {
{ private readonly RelationManager _source;
_source = source; internal ReverseOrientation(RelationManager source) => _source = source;
_relationWorld = relationWorld; public int NewRelation(int otherEntityID, int entityID) => _source.NewRelation(entityID, otherEntityID);
_basket = basket; public void DelRelation(int otherEntityID, int entityID) => _source.DelRelation(entityID, otherEntityID);
_otherBasket = otherBasket; public bool HasRelation(int otherEntityID, int entityID) => _source.HasRelation(entityID, otherEntityID);
_relationsMatrix = relationsMatrix; public int GetRelation(int otherEntityID, int entityID) => _source.GetRelation(entityID, otherEntityID);
_isReverce = isReverce; public bool TryGetRelation(int otherEntityID, int entityID, out int relationEntityID) => _source.TryGetRelation(entityID, otherEntityID, out relationEntityID);
} public IdsLinkedList.Span GetRelations(int relationEntityID) => _source._otherBasket.GetSpanFor(relationEntityID);
#region New/Del
public int NewRelation(int entityID, int otherEntityID)
{
if (HasRelation(entityID, otherEntityID))
throw new EcsRelationException();
int e = _relationWorld.NewEmptyEntity();
_relationsMatrix.Add(entityID, otherEntityID, e);
_basket.AddToHead(entityID, otherEntityID);
_otherBasket.AddToHead(otherEntityID, entityID);
_source._relationTargets[e] = new RelationTargets(entityID, otherEntityID);
return e;
}
public void DelRelation(int entityID, int otherEntityID)
{
if (!_source._relationsMatrix.TryGetValue(entityID, otherEntityID, out int e))
throw new EcsRelationException();
_relationsMatrix.Remove(entityID, otherEntityID);
_basket.DelHead(entityID);
_otherBasket.Del(entityID);
_relationWorld.DelEntity(e);
_source._relationTargets[e] = RelationTargets.Empty;
}
#endregion
#region Has
public bool HasRelation(int entityID, int otherEntityID) => _source._relationsMatrix.Contains(entityID, otherEntityID);
//public bool HasRelationWith(EcsSubject subject, int entityID, int otherEntityID)
//{
// if (subject.World != _relationWorld)
// throw new ArgumentException();
// return _source._relationsMatrix.TryGetValue(entityID, otherEntityID, out int entity) && subject.IsMatches(entity);
//}
#endregion
#region GetRelation
public int GetRelation(int entityID, int otherEntityID)
{
if (!_source._relationsMatrix.TryGetValue(entityID, otherEntityID, out int e))
throw new EcsRelationException();
return e;
}
public bool TryGetRelation(int entityID, int otherEntityID, out int entity)
{
return _source._relationsMatrix.TryGetValue(entityID, otherEntityID, out entity);
}
//public bool TryGetRelation(EcsSubject subject, int entityID, int otherEntityID, out int entity)
//{
// return _source._relationsMatrix.TryGetValue(entityID, otherEntityID, out entity) && subject.IsMatches(entity);
//}
#endregion
#region GetRelations
public IdsLinkedList.Span GetRelations(int entityID)
{
return _basket.GetSpanFor(entityID);
}
//ReadOnlySpan<int> временная заглушка, потому тут будет спан из линкедлиста
//public ReadOnlySpan<int> GetRelationsWith(EcsSubject subject, int entityID)
//{
// if (subject.World != _relationWorld)
// throw new ArgumentException();
// throw new NotImplementedException();
//}
#endregion
} }
public struct RelationsSpan public struct RelationsSpan