diff --git a/src/RelationManager.cs b/src/RelationManager.cs index b49fd32..ef9f677 100644 --- a/src/RelationManager.cs +++ b/src/RelationManager.cs @@ -24,10 +24,12 @@ namespace DCFApixels.DragonECS private EcsWorld _world; private EcsWorld _otherWorld; + private readonly IdsBasket _basket = new IdsBasket(256); + private readonly IdsBasket _otherBasket = new IdsBasket(256); private SparseArray64 _relationsMatrix = new SparseArray64(); - public readonly Orientation Forward; - public readonly Orientation Reverse; + public readonly ForwardOrientation Forward; + public readonly ReverseOrientation Reverse; private RelationTargets[] _relationTargets; @@ -47,11 +49,8 @@ namespace DCFApixels.DragonECS _relationWorld.AddListener(worldEventListener: this); _relationWorld.AddListener(entityEventListener: this); - IdsBasket basket = new IdsBasket(256); - IdsBasket otherBasket = new IdsBasket(256); - - Forward = new Orientation(this, _relationsMatrix, relationWorld, basket, otherBasket, false); - Reverse = new Orientation(this, _relationsMatrix, relationWorld, otherBasket, basket, true); + Forward = new ForwardOrientation(this); + Reverse = new ReverseOrientation(this); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -60,6 +59,76 @@ namespace DCFApixels.DragonECS 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 временная заглушка, потому тут будет спан из линкедлиста + ////public ReadOnlySpan GetRelationsWith(EcsSubject subject, int entityID) + ////{ + //// if (subject.World != _relationWorld) + //// throw new ArgumentException(); + //// throw new NotImplementedException(); + ////} + //#endregion + + #endregion + #region Callbacks void IEcsWorldEventListener.OnWorldResize(int newSize) { @@ -77,93 +146,29 @@ namespace DCFApixels.DragonECS } #endregion + #region Orientation - public readonly struct Orientation + public readonly struct ForwardOrientation { private readonly RelationManager _source; - - private readonly EcsWorld _relationWorld; - - private readonly IdsBasket _basket; - private readonly IdsBasket _otherBasket; - - private readonly SparseArray64 _relationsMatrix; - - private readonly bool _isReverce; - internal Orientation(RelationManager source, SparseArray64 relationsMatrix, EcsWorld relationWorld, IdsBasket basket, IdsBasket otherBasket, bool isReverce) - { - _source = source; - _relationWorld = relationWorld; - _basket = basket; - _otherBasket = otherBasket; - _relationsMatrix = relationsMatrix; - _isReverce = isReverce; - } - - #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 временная заглушка, потому тут будет спан из линкедлиста - //public ReadOnlySpan GetRelationsWith(EcsSubject subject, int entityID) - //{ - // if (subject.World != _relationWorld) - // throw new ArgumentException(); - // throw new NotImplementedException(); - //} - #endregion + internal ForwardOrientation(RelationManager source) => _source = source; + public int NewRelation(int entityID, int otherEntityID) => _source.NewRelation(entityID, otherEntityID); + public void DelRelation(int entityID, int otherEntityID) => _source.DelRelation(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 bool TryGetRelation(int entityID, int otherEntityID, out int relationEntityID) => _source.TryGetRelation(entityID, otherEntityID, out relationEntityID); + public IdsLinkedList.Span GetRelations(int relationEntityID) => _source._basket.GetSpanFor(relationEntityID); + } + public readonly struct ReverseOrientation + { + private readonly RelationManager _source; + internal ReverseOrientation(RelationManager source) => _source = source; + public int NewRelation(int otherEntityID, int entityID) => _source.NewRelation(entityID, otherEntityID); + public void DelRelation(int otherEntityID, int entityID) => _source.DelRelation(entityID, otherEntityID); + public bool HasRelation(int otherEntityID, int entityID) => _source.HasRelation(entityID, otherEntityID); + public int GetRelation(int otherEntityID, int entityID) => _source.GetRelation(entityID, otherEntityID); + 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); } public struct RelationsSpan