mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
Adds new functions to IComponentManager that can efficiently query for all entities with a set of components.
This commit is contained in:
@@ -98,7 +98,7 @@ namespace Robust.Client.Debugging
|
||||
var drawing = new PhysDrawingAdapter(worldHandle);
|
||||
|
||||
var viewport = _eyeManager.GetWorldViewport();
|
||||
foreach (var boundingBox in _componentManager.GetAllComponents<ICollidableComponent>())
|
||||
foreach (var boundingBox in _componentManager.EntityQuery<ICollidableComponent>())
|
||||
{
|
||||
var physBody = (IPhysBody)boundingBox;
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Robust.Client.GameStates
|
||||
{
|
||||
var worldHandle = (DrawingHandleWorld) handle;
|
||||
var viewport = _eyeManager.GetWorldViewport();
|
||||
foreach (var boundingBox in _componentManager.GetAllComponents<ICollidableComponent>())
|
||||
foreach (var boundingBox in _componentManager.EntityQuery<ICollidableComponent>())
|
||||
{
|
||||
// all entities have a TransformComponent
|
||||
var transform = ((IComponent)boundingBox).Owner.Transform;
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace Robust.Client.Physics
|
||||
|
||||
private List<ICollidableComponent> ActuallyRelevant()
|
||||
{
|
||||
var relevant = _componentManager.GetAllComponents<ICollidableComponent>().Where(p => p.Predict)
|
||||
var relevant = _componentManager.EntityQuery<ICollidableComponent>().Where(p => p.Predict)
|
||||
.ToList();
|
||||
return relevant;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using JetBrains.Annotations;
|
||||
using Robust.Shared.Exceptions;
|
||||
using Robust.Shared.GameObjects.Components;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
@@ -453,8 +454,10 @@ namespace Robust.Shared.GameObjects
|
||||
}
|
||||
}
|
||||
|
||||
#region Join Functions
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<T> GetAllComponents<T>()
|
||||
public IEnumerable<T> EntityQuery<T>()
|
||||
{
|
||||
var comps = _entTraitDict[typeof(T)];
|
||||
foreach (var comp in comps.Values)
|
||||
@@ -465,6 +468,87 @@ namespace Robust.Shared.GameObjects
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<(TComp1, TComp2)> EntityQuery<TComp1, TComp2>()
|
||||
where TComp1 : IComponent
|
||||
where TComp2 : IComponent
|
||||
{
|
||||
// this would prob be faster if trait1 was a list (or an array of structs hue).
|
||||
var trait1 = _entTraitDict[typeof(TComp1)];
|
||||
var trait2 = _entTraitDict[typeof(TComp2)];
|
||||
|
||||
// you really want trait1 to be the smaller set of components
|
||||
foreach (var kvComp in trait1)
|
||||
{
|
||||
var uid = kvComp.Key;
|
||||
|
||||
if (!trait2.TryGetValue(uid, out var t2Comp) || t2Comp.Deleted)
|
||||
continue;
|
||||
|
||||
yield return ((TComp1) (object) kvComp.Value, (TComp2) (object) t2Comp);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<(TComp1, TComp2, TComp3)> EntityQuery<TComp1, TComp2, TComp3>()
|
||||
where TComp1 : IComponent
|
||||
where TComp2 : IComponent
|
||||
where TComp3 : IComponent
|
||||
{
|
||||
var trait1 = _entTraitDict[typeof(TComp1)];
|
||||
var trait2 = _entTraitDict[typeof(TComp2)];
|
||||
var trait3 = _entTraitDict[typeof(TComp3)];
|
||||
|
||||
foreach (var kvComp in trait1)
|
||||
{
|
||||
var uid = kvComp.Key;
|
||||
|
||||
if (!trait2.TryGetValue(uid, out var t2Comp) || t2Comp.Deleted)
|
||||
continue;
|
||||
|
||||
if (!trait3.TryGetValue(uid, out var t3Comp) || t3Comp.Deleted)
|
||||
continue;
|
||||
|
||||
yield return ((TComp1) (object) kvComp.Value,
|
||||
(TComp2) (object) t2Comp,
|
||||
(TComp3) (object) t3Comp);
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<(TComp1, TComp2, TComp3, TComp4)> EntityQuery<TComp1, TComp2, TComp3, TComp4>()
|
||||
where TComp1 : IComponent
|
||||
where TComp2 : IComponent
|
||||
where TComp3 : IComponent
|
||||
where TComp4 : IComponent
|
||||
{
|
||||
var trait1 = _entTraitDict[typeof(TComp1)];
|
||||
var trait2 = _entTraitDict[typeof(TComp2)];
|
||||
var trait3 = _entTraitDict[typeof(TComp3)];
|
||||
var trait4 = _entTraitDict[typeof(TComp4)];
|
||||
|
||||
foreach (var kvComp in trait1)
|
||||
{
|
||||
var uid = kvComp.Key;
|
||||
|
||||
if (!trait2.TryGetValue(uid, out var t2Comp) || t2Comp.Deleted)
|
||||
continue;
|
||||
|
||||
if (!trait3.TryGetValue(uid, out var t3Comp) || t3Comp.Deleted)
|
||||
continue;
|
||||
|
||||
if (!trait4.TryGetValue(uid, out var t4Comp) || t4Comp.Deleted)
|
||||
continue;
|
||||
|
||||
yield return ((TComp1) (object) kvComp.Value,
|
||||
(TComp2) (object) t2Comp,
|
||||
(TComp3) (object) t3Comp,
|
||||
(TComp4) (object) t4Comp);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <inheritdoc />
|
||||
public IEnumerable<IComponent> GetAllComponents(Type type)
|
||||
{
|
||||
|
||||
@@ -98,7 +98,7 @@ namespace Robust.Shared.GameObjects
|
||||
|
||||
public IEnumerable<IEntity> Match(IEntityManager entityMan)
|
||||
{
|
||||
return entityMan.ComponentManager.GetAllComponents<T>().Select(component => component.Owner);
|
||||
return entityMan.ComponentManager.EntityQuery<T>().Select(component => component.Owner);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,5 +176,4 @@ namespace Robust.Shared.GameObjects
|
||||
return entityMan.GetEntities(new TypeEntityQuery(ComponentTypes.First())).Where(entity => Match(entity));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,10 +21,14 @@ namespace Robust.Shared.GameObjects.Systems
|
||||
public abstract class EntitySystem : IEntitySystem
|
||||
{
|
||||
[Dependency] protected readonly IEntityManager EntityManager = default!;
|
||||
[Dependency] protected readonly IComponentManager ComponentManager = default!;
|
||||
[Dependency] protected readonly IEntitySystemManager EntitySystemManager = default!;
|
||||
[Dependency] protected readonly IEntityNetworkManager EntityNetworkManager = default!;
|
||||
|
||||
[Obsolete("You need to create and store the query yourself in a field.")]
|
||||
protected IEntityQuery? EntityQuery;
|
||||
|
||||
[Obsolete("You need to use `EntityManager.GetEntities(EntityQuery)`, or store a query yourself.")]
|
||||
protected IEnumerable<IEntity> RelevantEntities => EntityQuery != null ? EntityManager.GetEntities(EntityQuery) : EntityManager.GetEntities();
|
||||
|
||||
protected internal List<Type> UpdatesAfter { get; } = new List<Type>();
|
||||
|
||||
@@ -201,7 +201,43 @@ namespace Robust.Shared.Interfaces.GameObjects
|
||||
/// </summary>
|
||||
/// <typeparam name="T">A trait or type of a component to retrieve.</typeparam>
|
||||
/// <returns>All components that have the specified type.</returns>
|
||||
IEnumerable<T> GetAllComponents<T>();
|
||||
IEnumerable<T> EntityQuery<T>();
|
||||
|
||||
/// <summary>
|
||||
/// Returns the relevant components from all entities that contain the two required components.
|
||||
/// </summary>
|
||||
/// <typeparam name="TComp1">First required component.</typeparam>
|
||||
/// <typeparam name="TComp2">Second required component.</typeparam>
|
||||
/// <returns>The pairs of components from each entity that has the two required components.</returns>
|
||||
IEnumerable<(TComp1, TComp2)> EntityQuery<TComp1, TComp2>()
|
||||
where TComp1 : IComponent
|
||||
where TComp2 : IComponent;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the relevant components from all entities that contain the three required components.
|
||||
/// </summary>
|
||||
/// <typeparam name="TComp1">First required component.</typeparam>
|
||||
/// <typeparam name="TComp2">Second required component.</typeparam>
|
||||
/// <typeparam name="TComp3">Third required component.</typeparam>
|
||||
/// <returns>The pairs of components from each entity that has the three required components.</returns>
|
||||
IEnumerable<(TComp1, TComp2, TComp3)> EntityQuery<TComp1, TComp2, TComp3>()
|
||||
where TComp1 : IComponent
|
||||
where TComp2 : IComponent
|
||||
where TComp3 : IComponent;
|
||||
|
||||
/// <summary>
|
||||
/// Returns the relevant components from all entities that contain the four required components.
|
||||
/// </summary>
|
||||
/// <typeparam name="TComp1">First required component.</typeparam>
|
||||
/// <typeparam name="TComp2">Second required component.</typeparam>
|
||||
/// <typeparam name="TComp3">Third required component.</typeparam>
|
||||
/// <typeparam name="TComp4">Fourth required component.</typeparam>
|
||||
/// <returns>The pairs of components from each entity that has the four required components.</returns>
|
||||
IEnumerable<(TComp1, TComp2, TComp3, TComp4)> EntityQuery<TComp1, TComp2, TComp3, TComp4>()
|
||||
where TComp1 : IComponent
|
||||
where TComp2 : IComponent
|
||||
where TComp3 : IComponent
|
||||
where TComp4 : IComponent;
|
||||
|
||||
/// <summary>
|
||||
/// Returns ALL component instances of a specified type.
|
||||
|
||||
@@ -209,7 +209,7 @@ namespace Robust.Shared.Map
|
||||
|
||||
// locate the entity that represents this map that was just sent to us
|
||||
IEntity? sharedMapEntity = null;
|
||||
var mapComps = _entityManager.ComponentManager.GetAllComponents<IMapComponent>();
|
||||
var mapComps = _entityManager.ComponentManager.EntityQuery<IMapComponent>();
|
||||
foreach (var mapComp in mapComps)
|
||||
{
|
||||
if (!mapComp.Owner.Uid.IsClientSide() && mapComp.WorldMap == mapId)
|
||||
@@ -259,7 +259,7 @@ namespace Robust.Shared.Map
|
||||
cGridComp.ClearGridId();
|
||||
cEntity.Delete(); // normal entities are already parented to the shared comp, client comp has no children
|
||||
|
||||
var gridComps = _entityManager.ComponentManager.GetAllComponents<IMapGridComponent>();
|
||||
var gridComps = _entityManager.ComponentManager.EntityQuery<IMapGridComponent>();
|
||||
foreach (var gridComp in gridComps)
|
||||
{
|
||||
if (gridComp.GridIndex == kvNewGrid.Key)
|
||||
|
||||
@@ -245,7 +245,7 @@ namespace Robust.Shared.Map
|
||||
|
||||
if (actualID != MapId.Nullspace) // nullspace isn't bound to an entity
|
||||
{
|
||||
var mapComps = _entityManager.ComponentManager.GetAllComponents<IMapComponent>();
|
||||
var mapComps = _entityManager.ComponentManager.EntityQuery<IMapComponent>();
|
||||
|
||||
IMapComponent? result = null;
|
||||
foreach (var mapComp in mapComps)
|
||||
@@ -446,7 +446,7 @@ namespace Robust.Shared.Map
|
||||
{
|
||||
// the entity may already exist from map deserialization
|
||||
IMapGridComponent? result = null;
|
||||
foreach (var comp in _entityManager.ComponentManager.GetAllComponents<IMapGridComponent>())
|
||||
foreach (var comp in _entityManager.ComponentManager.EntityQuery<IMapGridComponent>())
|
||||
{
|
||||
if (comp.GridIndex != actualID)
|
||||
continue;
|
||||
|
||||
@@ -208,7 +208,7 @@ namespace Robust.UnitTesting.Shared.GameObjects
|
||||
manager.AddComponent(entity, component);
|
||||
|
||||
// Act
|
||||
var result = manager.GetAllComponents<DummyComponent>();
|
||||
var result = manager.EntityQuery<DummyComponent>();
|
||||
|
||||
// Assert
|
||||
var list = result.ToList();
|
||||
|
||||
Reference in New Issue
Block a user