This commit is contained in:
Mikhail 2023-06-22 11:01:43 +08:00
parent 7792ce5990
commit f815ee0aca
7 changed files with 45 additions and 26 deletions

View File

@ -1,6 +1,4 @@
using DCFApixels.DragonECS; namespace DCFApixels.DragonECS
namespace DragonECS.DragonECS
{ {
public sealed class EcsRelationWorld : EcsWorld { } public sealed class EcsRelationWorld : EcsWorld { }
} }

View File

@ -1,12 +1,8 @@
using DCFApixels.DragonECS; using DCFApixels.DragonECS.Relations.Utils;
using DCFApixels.DragonECS.Relations.Utils;
using System; using System;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Drawing;
using System.Linq;
namespace DragonECS.DragonECS namespace DCFApixels.DragonECS
{ {
[DebuggerTypeProxy(typeof(DebuggerProxy))] [DebuggerTypeProxy(typeof(DebuggerProxy))]
public class IdsBasket public class IdsBasket

View File

@ -1,4 +1,4 @@
namespace DragonECS.DragonECS namespace DCFApixels.DragonECS
{ {
public readonly struct RelationTargets public readonly struct RelationTargets
{ {
@ -10,5 +10,6 @@
this.entity = entity; this.entity = entity;
this.otherEntity = otherEntity; this.otherEntity = otherEntity;
} }
public override string ToString() => $"rel({entity}, {otherEntity})";
} }
} }

View File

@ -1,17 +1,16 @@
using DCFApixels.DragonECS; using DCFApixels.DragonECS.Relations.Utils;
using DCFApixels.DragonECS.Relations.Utils; using System;
using System.Collections;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
namespace DragonECS.DragonECS namespace DCFApixels.DragonECS
{ {
//Relation entity //Relation entity
//Relation //Relation
//Relation component //Relation component
public readonly struct Relations public readonly struct RelationData
{ {
public readonly RelationManager manager; public readonly RelationManager manager;
public Relations(RelationManager manager) public RelationData(RelationManager manager)
{ {
this.manager = manager; this.manager = manager;
} }
@ -51,8 +50,8 @@ namespace DragonECS.DragonECS
IdsBasket basket = new IdsBasket(256); IdsBasket basket = new IdsBasket(256);
IdsBasket otherBasket = new IdsBasket(256); IdsBasket otherBasket = new IdsBasket(256);
Forward = new Orientation(this, relationWorld, basket, otherBasket); Forward = new Orientation(this, _relationsMatrix, relationWorld, basket, otherBasket, false);
Reverse = new Orientation(this, relationWorld, otherBasket, basket); Reverse = new Orientation(this, _relationsMatrix, relationWorld, otherBasket, basket, true);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -88,12 +87,17 @@ namespace DragonECS.DragonECS
private readonly IdsBasket _basket; private readonly IdsBasket _basket;
private readonly IdsBasket _otherBasket; private readonly IdsBasket _otherBasket;
public Orientation(RelationManager source, EcsWorld relationWorld, IdsBasket basket, IdsBasket otherBasket) private readonly SparseArray64<int> _relationsMatrix;
private readonly bool _isReverce;
internal Orientation(RelationManager source, SparseArray64<int> relationsMatrix, EcsWorld relationWorld, IdsBasket basket, IdsBasket otherBasket, bool isReverce)
{ {
_source = source; _source = source;
_relationWorld = relationWorld; _relationWorld = relationWorld;
_basket = basket; _basket = basket;
_otherBasket = otherBasket; _otherBasket = otherBasket;
_relationsMatrix = relationsMatrix;
_isReverce = isReverce;
} }
#region New/Del #region New/Del
@ -102,6 +106,7 @@ namespace DragonECS.DragonECS
if (HasRelation(entityID, otherEntityID)) if (HasRelation(entityID, otherEntityID))
throw new EcsRelationException(); throw new EcsRelationException();
int e = _relationWorld.NewEmptyEntity(); int e = _relationWorld.NewEmptyEntity();
_relationsMatrix.Add(entityID, otherEntityID, e);
_basket.AddToHead(entityID, otherEntityID); _basket.AddToHead(entityID, otherEntityID);
_otherBasket.AddToHead(otherEntityID, entityID); _otherBasket.AddToHead(otherEntityID, entityID);
_source._relationTargets[e] = new RelationTargets(entityID, otherEntityID); _source._relationTargets[e] = new RelationTargets(entityID, otherEntityID);
@ -111,6 +116,7 @@ namespace DragonECS.DragonECS
{ {
if (!_source._relationsMatrix.TryGetValue(entityID, otherEntityID, out int e)) if (!_source._relationsMatrix.TryGetValue(entityID, otherEntityID, out int e))
throw new EcsRelationException(); throw new EcsRelationException();
_relationsMatrix.Remove(entityID, otherEntityID);
_basket.DelHead(entityID); _basket.DelHead(entityID);
_otherBasket.Del(entityID); _otherBasket.Del(entityID);
_relationWorld.DelEntity(e); _relationWorld.DelEntity(e);
@ -170,17 +176,35 @@ namespace DragonECS.DragonECS
public static class WorldRelationExtensions public static class WorldRelationExtensions
{ {
public static void SetRelationWithSelf(this EcsWorld self) => SetRelationWith(self, self);
public static void SetRelationWith(this EcsWorld self, EcsWorld otherWorld) public static void SetRelationWith(this EcsWorld self, EcsWorld otherWorld)
{ {
if (self == null || otherWorld == null)
throw new ArgumentNullException();
WorldRelationsMatrix.Register(self, otherWorld, new EcsRelationWorld()); WorldRelationsMatrix.Register(self, otherWorld, new EcsRelationWorld());
} }
public static void SetRelationWithSelf(this EcsWorld self, EcsRelationWorld relationWorld) => SetRelationWith(self, relationWorld);
public static void SetRelationWith(this EcsWorld self, EcsWorld otherWorld, EcsRelationWorld relationWorld) public static void SetRelationWith(this EcsWorld self, EcsWorld otherWorld, EcsRelationWorld relationWorld)
{ {
if (self == null || otherWorld == null || relationWorld == null)
throw new ArgumentNullException();
WorldRelationsMatrix.Register(self, otherWorld, relationWorld); WorldRelationsMatrix.Register(self, otherWorld, relationWorld);
} }
public static void DelRelationWithSelf(this EcsWorld self, EcsWorld otherWorld) => DelRelationWith(self, self);
public static void DelRelationWith(this EcsWorld self, EcsWorld otherWorld) public static void DelRelationWith(this EcsWorld self, EcsWorld otherWorld)
{ {
if (self == null || otherWorld == null)
throw new ArgumentNullException();
WorldRelationsMatrix.Unregister(self, otherWorld); WorldRelationsMatrix.Unregister(self, otherWorld);
} }
public static RelationManager GetRelationWithSelf(this EcsWorld self) => GetRelationWith(self, self);
public static RelationManager GetRelationWith(this EcsWorld self, EcsWorld otherWorld)
{
if (self == null || otherWorld == null)
throw new ArgumentNullException();
return WorldRelationsMatrix.Get(self, otherWorld);
}
} }
} }

View File

@ -1,8 +1,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Reflection;
using System.Reflection.Metadata.Ecma335;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace DCFApixels.DragonECS.Relations.Utils namespace DCFApixels.DragonECS.Relations.Utils

View File

@ -53,6 +53,8 @@ namespace DCFApixels.DragonECS.Relations.Utils
#region Add #region Add
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Add(long keyX, long keyY, TValue value) => Add(keyX + (keyY << 32), value);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Add(long key, TValue value) public void Add(long key, TValue value)
{ {
#if DEBUG #if DEBUG

View File

@ -1,11 +1,10 @@
using DCFApixels.DragonECS; using DCFApixels.DragonECS.Relations.Utils;
using DCFApixels.DragonECS.Relations.Utils;
namespace DragonECS.DragonECS namespace DCFApixels.DragonECS
{ {
internal static class WorldRelationsMatrix internal static class WorldRelationsMatrix
{ {
private static SparseArray64<RelationManager> _matrix; private static SparseArray64<RelationManager> _matrix = new SparseArray64<RelationManager>(4);
internal static RelationManager Register(EcsWorld world, EcsWorld otherWorld, EcsRelationWorld relationWorld) internal static RelationManager Register(EcsWorld world, EcsWorld otherWorld, EcsRelationWorld relationWorld)
{ {
@ -30,7 +29,7 @@ namespace DragonECS.DragonECS
internal static RelationManager Get(EcsWorld world, EcsWorld otherWorld) internal static RelationManager Get(EcsWorld world, EcsWorld otherWorld)
{ {
#if DEBUG #if DEBUG
if (_matrix.Contains(world.id, otherWorld.id)) if (!_matrix.Contains(world.id, otherWorld.id))
throw new EcsFrameworkException(); throw new EcsFrameworkException();
#endif #endif
return _matrix[world.id, otherWorld.id]; return _matrix[world.id, otherWorld.id];