Compare commits

..

4 Commits

Author SHA1 Message Date
Pieter-Jan Briers
10ab707427 Version: 167.0.2 2024-03-10 21:27:10 +01:00
Pieter-Jan Briers
f061a8c018 global.json force .NET 7
(cherry picked from commit 6211cf2e03)
2024-03-10 21:27:00 +01:00
Pieter-Jan Briers
91d4b32c66 Version: 167.0.1 2024-03-10 20:50:30 +01:00
Pieter-Jan Briers
e788f03a28 Backport 859f150404
(cherry picked from commit 24d5c26fa6)
(cherry picked from commit 688efac67b634c613539b783a9fb6e679948cd53)
2024-03-10 20:50:30 +01:00
117 changed files with 1290 additions and 2090 deletions

View File

@@ -1,4 +1,4 @@
<Project>
<!-- This file automatically reset by Tools/version.py -->
<!-- This file automatically reset by Tools/version.py -->

View File

@@ -54,23 +54,10 @@ END TEMPLATE-->
*None yet*
## 169.0.0
### Breaking changes
* Entity<T> has been introduced to hold a component and its owning entity. Some methods that returned and accepted components directly have been removed or obsoleted to reflect this.
### Other
* By-value events may now be subscribed to by-ref.
* The manifest's assemblyPrefix value is now respected on the server.
## 167.0.2
## 168.0.0
### Breaking changes
* The Component.OnRemove method has been removed. Use SubscribeLocalEvent<TComp, ComponentRemove>(OnRemove) from an EntitySystem instead.
## 167.0.1
## 167.0.0
@@ -117,7 +104,7 @@ END TEMPLATE-->
### New features
* The YAML validator now checks the default values of ProtoId<T> and EntProtoId data fields.
* The YAML validator now checks the default values of ProtoId<T> and EntProtoId data fields.
### Bugfixes

View File

@@ -23,6 +23,16 @@ public sealed class ByRefEventAnalyzer : DiagnosticAnalyzer
"Make sure that methods subscribing to a ref event have the ref keyword for the event argument."
);
private static readonly DiagnosticDescriptor ByValueEventSubscribedByRefRule = new(
Diagnostics.IdValueEventRaisedByRef,
"Value event subscribed to by-ref",
"Tried to subscribe to a value event '{0}' by-ref.",
"Usage",
DiagnosticSeverity.Error,
true,
"Make sure that methods subscribing to value events do not have the ref keyword for the event argument."
);
private static readonly DiagnosticDescriptor ByRefEventRaisedByValueRule = new(
Diagnostics.IdByRefEventRaisedByValue,
"By-ref event raised by value",
@@ -45,6 +55,7 @@ public sealed class ByRefEventAnalyzer : DiagnosticAnalyzer
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(
ByRefEventSubscribedByValueRule,
ByValueEventSubscribedByRefRule,
ByRefEventRaisedByValueRule,
ByValueEventRaisedByRefRule
);
@@ -53,9 +64,71 @@ public sealed class ByRefEventAnalyzer : DiagnosticAnalyzer
{
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
context.EnableConcurrentExecution();
context.RegisterOperationAction(CheckEventSubscription, OperationKind.Invocation);
context.RegisterOperationAction(CheckEventRaise, OperationKind.Invocation);
}
private void CheckEventSubscription(OperationAnalysisContext context)
{
if (context.Operation is not IInvocationOperation operation)
return;
var subscribeMethods = context.Compilation
.GetTypeByMetadataName("Robust.Shared.GameObjects.EntitySystem")?
.GetMembers()
.Where(m => m.Name.Contains("SubscribeLocalEvent"))
.Cast<IMethodSymbol>();
if (subscribeMethods == null)
return;
if (!subscribeMethods.Any(m => m.Equals(operation.TargetMethod.OriginalDefinition, Default)))
return;
var typeArguments = operation.TargetMethod.TypeArguments;
if (typeArguments.Length < 1 || typeArguments.Length > 2)
return;
if (operation.Arguments.First().Value is not IDelegateCreationOperation delegateCreation)
return;
if (delegateCreation.Target is not IMethodReferenceOperation methodReference)
return;
var eventParameter = methodReference.Method.Parameters.LastOrDefault();
if (eventParameter == null)
return;
ITypeSymbol eventArgument;
switch (typeArguments.Length)
{
case 1:
eventArgument = typeArguments[0];
break;
case 2:
eventArgument = typeArguments[1];
break;
default:
return;
}
var byRefAttribute = context.Compilation.GetTypeByMetadataName(ByRefAttribute);
if (byRefAttribute == null)
return;
var isByRefEventType = eventArgument
.GetAttributes()
.Any(attribute => attribute.AttributeClass?.Equals(byRefAttribute, Default) ?? false);
var parameterIsRef = eventParameter.RefKind == RefKind.Ref;
if (isByRefEventType != parameterIsRef)
{
var descriptor = isByRefEventType ? ByRefEventSubscribedByValueRule : ByValueEventSubscribedByRefRule;
var diagnostic = Diagnostic.Create(descriptor, operation.Syntax.GetLocation(), eventArgument);
context.ReportDiagnostic(diagnostic);
}
}
private void CheckEventRaise(OperationAnalysisContext context)
{
if (context.Operation is not IInvocationOperation operation)

View File

@@ -18,6 +18,7 @@ public static class Diagnostics
public const string IdInvalidNotNullableFlagType = "RA0011";
public const string IdNotNullableFlagValueType = "RA0012";
public const string IdByRefEventSubscribedByValue = "RA0013";
public const string IdValueEventSubscribedByRef = "RA0014";
public const string IdByRefEventRaisedByValue = "RA0015";
public const string IdValueEventRaisedByRef = "RA0016";
public const string IdDataDefinitionPartial = "RA0017";

View File

@@ -54,7 +54,7 @@ public class RecursiveMoveBenchmark
var mapSys = _entMan.System<SharedMapSystem>();
var mapId = mapMan.CreateMap();
var map = mapMan.GetMapEntityId(mapId);
var gridComp = mapMan.CreateGridEntity(mapId);
var gridComp = mapMan.CreateGrid(mapId);
var grid = gridComp.Owner;
_gridCoords = new EntityCoordinates(grid, .5f, .5f);
_mapCoords = new EntityCoordinates(map, 100, 100);

View File

@@ -26,7 +26,10 @@ namespace Robust.Client.Console.Commands
var entity = _entityManager.GetEntity(netEntity);
var componentName = args[1];
var component = _componentFactory.GetComponent(componentName);
var component = (Component) _componentFactory.GetComponent(componentName);
component.Owner = entity;
_entityManager.AddComponent(entity, component);
}
}

View File

@@ -1,7 +1,6 @@
#if DEBUG
using System.Numerics;
using System.Text;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Input;
using Robust.Client.UserInterface;
@@ -9,6 +8,7 @@ using Robust.Client.UserInterface.Controls;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
namespace Robust.Client.Debugging
@@ -19,7 +19,6 @@ namespace Robust.Client.Debugging
[Dependency] private readonly IInputManager _inputManager = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IUserInterfaceManager _userInterface = default!;
[Dependency] private readonly MapSystem _mapSystem = default!;
private Label? _label;
@@ -71,7 +70,7 @@ namespace Robust.Client.Debugging
return;
}
var tile = _mapSystem.GetTileRef(gridUid, grid, spot);
var tile = grid.GetTileRef(spot);
_label.Position = mouseSpot.Position + new Vector2(32, 0);
if (_hovered?.GridId == gridUid && _hovered?.Tile == tile) return;
@@ -80,7 +79,7 @@ namespace Robust.Client.Debugging
var text = new StringBuilder();
foreach (var ent in _mapSystem.GetAnchoredEntities(gridUid, grid, spot))
foreach (var ent in grid.GetAnchoredEntities(spot))
{
if (EntityManager.TryGetComponent<MetaDataComponent>(ent, out var meta))
{

View File

@@ -46,6 +46,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Robust.Client.Graphics;
using Robust.Client.Input;
@@ -206,7 +207,6 @@ namespace Robust.Client.Debugging
private readonly Font _font;
private HashSet<Joint> _drawnJoints = new();
private List<Entity<MapGridComponent>> _grids = new();
public PhysicsDebugOverlay(IEntityManager entityManager, IEyeManager eyeManager, IInputManager inputManager, IMapManager mapManager, IPlayerManager playerManager, IResourceCache cache, DebugPhysicsSystem system, EntityLookupSystem lookup, SharedPhysicsSystem physicsSystem)
{
@@ -231,33 +231,32 @@ namespace Robust.Client.Debugging
{
foreach (var physBody in _physicsSystem.GetCollidingEntities(mapId, viewBounds))
{
if (_entityManager.HasComponent<MapGridComponent>(physBody)) continue;
if (_entityManager.HasComponent<MapGridComponent>(physBody.Owner)) continue;
var xform = _physicsSystem.GetPhysicsTransform(physBody);
var comp = physBody.Comp;
var xform = _physicsSystem.GetPhysicsTransform(physBody.Owner);
const float AlphaModifier = 0.2f;
foreach (var fixture in _entityManager.GetComponent<FixturesComponent>(physBody).Fixtures.Values)
foreach (var fixture in _entityManager.GetComponent<FixturesComponent>(physBody.Owner).Fixtures.Values)
{
// Invalid shape - Box2D doesn't check for IsSensor but we will for sanity.
if (comp.BodyType == BodyType.Dynamic && fixture.Density == 0f && fixture.Hard)
if (physBody.BodyType == BodyType.Dynamic && fixture.Density == 0f && fixture.Hard)
{
DrawShape(worldHandle, fixture, xform, Color.Red.WithAlpha(AlphaModifier));
}
else if (!comp.CanCollide)
else if (!physBody.CanCollide)
{
DrawShape(worldHandle, fixture, xform, new Color(0.5f, 0.5f, 0.3f).WithAlpha(AlphaModifier));
}
else if (comp.BodyType == BodyType.Static)
else if (physBody.BodyType == BodyType.Static)
{
DrawShape(worldHandle, fixture, xform, new Color(0.5f, 0.9f, 0.5f).WithAlpha(AlphaModifier));
}
else if ((comp.BodyType & (BodyType.Kinematic | BodyType.KinematicController)) != 0x0)
else if ((physBody.BodyType & (BodyType.Kinematic | BodyType.KinematicController)) != 0x0)
{
DrawShape(worldHandle, fixture, xform, new Color(0.5f, 0.5f, 0.9f).WithAlpha(AlphaModifier));
}
else if (!comp.Awake)
else if (!physBody.Awake)
{
DrawShape(worldHandle, fixture, xform, new Color(0.6f, 0.6f, 0.6f).WithAlpha(AlphaModifier));
}
@@ -276,18 +275,15 @@ namespace Robust.Client.Debugging
foreach (var physBody in _physicsSystem.GetCollidingEntities(mapId, viewBounds))
{
var color = Color.Purple.WithAlpha(Alpha);
var transform = _physicsSystem.GetPhysicsTransform(physBody);
worldHandle.DrawCircle(Transform.Mul(transform, physBody.Comp.LocalCenter), 0.2f, color);
var transform = _physicsSystem.GetPhysicsTransform(physBody.Owner);
worldHandle.DrawCircle(Transform.Mul(transform, physBody.LocalCenter), 0.2f, color);
}
_grids.Clear();
_mapManager.FindGridsIntersecting(mapId, viewBounds, ref _grids);
foreach (var grid in _grids)
foreach (var grid in _mapManager.FindGridsIntersecting(mapId, viewBounds))
{
var physBody = _entityManager.GetComponent<PhysicsComponent>(grid);
var physBody = _entityManager.GetComponent<PhysicsComponent>(grid.Owner);
var color = Color.Orange.WithAlpha(Alpha);
var transform = _physicsSystem.GetPhysicsTransform(grid);
var transform = _physicsSystem.GetPhysicsTransform(grid.Owner);
worldHandle.DrawCircle(Transform.Mul(transform, physBody.LocalCenter), 1f, color);
}
}
@@ -296,14 +292,14 @@ namespace Robust.Client.Debugging
{
foreach (var physBody in _physicsSystem.GetCollidingEntities(mapId, viewBounds))
{
if (_entityManager.HasComponent<MapGridComponent>(physBody)) continue;
if (_entityManager.HasComponent<MapGridComponent>(physBody.Owner)) continue;
var xform = _physicsSystem.GetPhysicsTransform(physBody);
var xform = _physicsSystem.GetPhysicsTransform(physBody.Owner);
const float AlphaModifier = 0.2f;
Box2? aabb = null;
foreach (var fixture in _entityManager.GetComponent<FixturesComponent>(physBody).Fixtures.Values)
foreach (var fixture in _entityManager.GetComponent<FixturesComponent>(physBody.Owner).Fixtures.Values)
{
for (var i = 0; i < fixture.Shape.ChildCount; i++)
{
@@ -322,11 +318,10 @@ namespace Robust.Client.Debugging
{
_drawnJoints.Clear();
var query = _entityManager.AllEntityQueryEnumerator<JointComponent>();
while (query.MoveNext(out var uid, out var jointComponent))
foreach (var jointComponent in _entityManager.EntityQuery<JointComponent>(true))
{
if (jointComponent.JointCount == 0 ||
!_entityManager.TryGetComponent(uid, out TransformComponent? xf1) ||
!_entityManager.TryGetComponent(jointComponent.Owner, out TransformComponent? xf1) ||
!viewAABB.Contains(xf1.WorldPosition)) continue;
foreach (var (_, joint) in jointComponent.Joints)
@@ -375,31 +370,28 @@ namespace Robust.Client.Debugging
if ((_debugPhysicsSystem.Flags & PhysicsDebugFlags.ShapeInfo) != 0x0)
{
var hoverBodies = new List<Entity<PhysicsComponent>>();
var hoverBodies = new List<PhysicsComponent>();
var bounds = Box2.UnitCentered.Translated(_eyeManager.PixelToMap(mousePos.Position).Position);
foreach (var physBody in _physicsSystem.GetCollidingEntities(mapId, bounds))
{
var uid = physBody.Owner;
if (_entityManager.HasComponent<MapGridComponent>(uid)) continue;
hoverBodies.Add((uid, physBody));
if (_entityManager.HasComponent<MapGridComponent>(physBody.Owner)) continue;
hoverBodies.Add(physBody);
}
var lineHeight = _font.GetLineHeight(1f);
var drawPos = mousePos.Position + new Vector2(20, 0) + new Vector2(0, -(hoverBodies.Count * 4 * lineHeight / 2f));
int row = 0;
foreach (var bodyEnt in hoverBodies)
foreach (var body in hoverBodies)
{
if (bodyEnt != hoverBodies[0])
if (body != hoverBodies[0])
{
screenHandle.DrawString(_font, drawPos + new Vector2(0, row * lineHeight), "------");
row++;
}
var body = bodyEnt.Comp;
screenHandle.DrawString(_font, drawPos + new Vector2(0, row * lineHeight), $"Ent: {bodyEnt.Owner}");
screenHandle.DrawString(_font, drawPos + new Vector2(0, row * lineHeight), $"Ent: {body.Owner}");
row++;
screenHandle.DrawString(_font, drawPos + new Vector2(0, row * lineHeight), $"Layer: {Convert.ToString(body.CollisionLayer, 2)}");
row++;

View File

@@ -3,7 +3,6 @@ using System.IO;
using System.Reflection;
using System.Runtime.Loader;
using Robust.Client.WebViewHook;
using Robust.Shared.ContentPack;
using Robust.Shared.Log;
using Robust.Shared.Utility;

View File

@@ -287,6 +287,78 @@ namespace Robust.Client
return true;
}
private ResourceManifestData LoadResourceManifest()
{
// Parses /manifest.yml for game-specific settings that cannot be exclusively set up by content code.
if (!_resourceCache.TryContentFileRead("/manifest.yml", out var stream))
return ResourceManifestData.Default;
var yamlStream = new YamlStream();
using (stream)
{
using var streamReader = new StreamReader(stream, EncodingHelpers.UTF8);
yamlStream.Load(streamReader);
}
if (yamlStream.Documents.Count == 0)
return ResourceManifestData.Default;
if (yamlStream.Documents.Count != 1 || yamlStream.Documents[0].RootNode is not YamlMappingNode mapping)
{
throw new InvalidOperationException(
"Expected a single YAML document with root mapping for /manifest.yml");
}
var modules = ReadStringArray(mapping, "modules") ?? Array.Empty<string>();
string? assemblyPrefix = null;
if (mapping.TryGetNode("assemblyPrefix", out var prefixNode))
assemblyPrefix = prefixNode.AsString();
string? defaultWindowTitle = null;
if (mapping.TryGetNode("defaultWindowTitle", out var winTitleNode))
defaultWindowTitle = winTitleNode.AsString();
string? windowIconSet = null;
if (mapping.TryGetNode("windowIconSet", out var iconSetNode))
windowIconSet = iconSetNode.AsString();
string? splashLogo = null;
if (mapping.TryGetNode("splashLogo", out var splashNode))
splashLogo = splashNode.AsString();
bool autoConnect = true;
if (mapping.TryGetNode("autoConnect", out var autoConnectNode))
autoConnect = autoConnectNode.AsBool();
var clientAssemblies = ReadStringArray(mapping, "clientAssemblies");
return new ResourceManifestData(
modules,
assemblyPrefix,
defaultWindowTitle,
windowIconSet,
splashLogo,
autoConnect,
clientAssemblies
);
static string[]? ReadStringArray(YamlMappingNode mapping, string key)
{
if (!mapping.TryGetNode(key, out var node))
return null;
var sequence = (YamlSequenceNode)node;
var array = new string[sequence.Children.Count];
for (var i = 0; i < array.Length; i++)
{
array[i] = sequence[i].AsString();
}
return array;
}
}
internal bool StartupSystemSplash(
GameControllerOptions options,
Func<ILogHandler>? logHandlerFactory,
@@ -385,7 +457,7 @@ namespace Robust.Client
_modLoader.VerifierExtraLoadHandler = VerifierExtraLoadHandler;
}
_resourceManifest = ResourceManifestData.LoadResourceManifest(_resourceCache);
_resourceManifest = LoadResourceManifest();
{
// Handle GameControllerOptions implicit CVar overrides.
@@ -714,6 +786,20 @@ namespace Robust.Client
_clydeAudio.Shutdown();
}
private sealed record ResourceManifestData(
string[] Modules,
string? AssemblyPrefix,
string? DefaultWindowTitle,
string? WindowIconSet,
string? SplashLogo,
bool AutoConnect,
string[]? ClientAssemblies
)
{
public static readonly ResourceManifestData Default =
new ResourceManifestData(Array.Empty<string>(), null, null, null, null, true, null);
}
public event Action<FrameEventArgs>? TickUpdateOverride;
}
}

View File

@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Prometheus;
using Robust.Client.GameStates;
using Robust.Client.Player;
@@ -85,17 +86,11 @@ namespace Robust.Client.GameObjects
}
/// <inheritdoc />
public override void Dirty(EntityUid uid, IComponent component, MetaDataComponent? meta = null)
{
Dirty(new Entity<IComponent>(uid, component), meta);
}
/// <inheritdoc />
public override void Dirty(Entity<IComponent> ent, MetaDataComponent? meta = null)
public override void Dirty(EntityUid uid, Component component, MetaDataComponent? meta = null)
{
// Client only dirties during prediction
if (_gameTiming.InPrediction)
base.Dirty(ent, meta);
base.Dirty(uid, component, meta);
}
public override EntityStringRepresentation ToPrettyString(EntityUid uid, MetaDataComponent? metaDataComponent = null)

View File

@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using Robust.Client.Animations;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using static Robust.Client.Animations.AnimationPlaybackShared;
namespace Robust.Client.GameObjects
@@ -19,5 +21,42 @@ namespace Robust.Client.GameObjects
= new();
internal bool HasPlayingAnimation = false;
/// <summary>
/// Start playing an animation.
/// </summary>
/// <param name="animation">The animation to play.</param>
/// <param name="key">
/// The key for this animation play. This key can be used to stop playback short later.
/// </param>
[Obsolete("Use AnimationPlayerSystem.Play() instead")]
public void Play(Animation animation, string key)
{
IoCManager.Resolve<IEntitySystemManager>().GetEntitySystem<AnimationPlayerSystem>().AddComponent(this);
var playback = new AnimationPlayback(animation);
PlayingAnimations.Add(key, playback);
}
[Obsolete("Use AnimationPlayerSystem.HasRunningAnimation() instead")]
public bool HasRunningAnimation(string key)
{
return PlayingAnimations.ContainsKey(key);
}
[Obsolete("Use AnimationPlayerSystem.Stop() instead")]
public void Stop(string key)
{
PlayingAnimations.Remove(key);
}
[Obsolete("Temporary method until the event is replaced with eventbus")]
internal void AnimationComplete(string key)
{
AnimationCompleted?.Invoke(key);
}
[Obsolete("Use AnimationCompletedEvent instead")]
public event Action<string>? AnimationCompleted;
}
}

View File

@@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using Robust.Client.Animations;
using Robust.Shared.GameObjects;
@@ -10,7 +9,7 @@ namespace Robust.Client.GameObjects
{
public sealed class AnimationPlayerSystem : EntitySystem, IPostInjectInit
{
private readonly List<Entity<AnimationPlayerComponent>> _activeAnimations = new();
private readonly List<AnimationPlayerComponent> _activeAnimations = new();
private EntityQuery<MetaDataComponent> _metaQuery;
@@ -39,22 +38,22 @@ namespace Robust.Client.GameObjects
continue;
}
if (!Update(uid, anim.Comp, frameTime))
if (!Update(uid, anim, frameTime))
{
continue;
}
_activeAnimations.RemoveSwap(i);
i--;
anim.Comp.HasPlayingAnimation = false;
anim.HasPlayingAnimation = false;
}
}
internal void AddComponent(Entity<AnimationPlayerComponent> ent)
internal void AddComponent(AnimationPlayerComponent component)
{
if (ent.Comp.HasPlayingAnimation) return;
_activeAnimations.Add(ent);
ent.Comp.HasPlayingAnimation = true;
if (component.HasPlayingAnimation) return;
_activeAnimations.Add(component);
component.HasPlayingAnimation = true;
}
private bool Update(EntityUid uid, AnimationPlayerComponent component, float frameTime)
@@ -79,6 +78,7 @@ namespace Robust.Client.GameObjects
{
component.PlayingAnimations.Remove(key);
EntityManager.EventBus.RaiseLocalEvent(uid, new AnimationCompletedEvent {Uid = uid, Key = key}, true);
component.AnimationComplete(key);
}
return false;
@@ -89,29 +89,22 @@ namespace Robust.Client.GameObjects
/// </summary>
public void Play(EntityUid uid, Animation animation, string key)
{
var component = EnsureComp<AnimationPlayerComponent>(uid);
Play(new Entity<AnimationPlayerComponent>(uid, component), animation, key);
var component = EntityManager.EnsureComponent<AnimationPlayerComponent>(uid);
Play(component, animation, key);
}
[Obsolete("Use Play(EntityUid<AnimationPlayerComponent> ent, Animation animation, string key) instead")]
public void Play(EntityUid uid, AnimationPlayerComponent? component, Animation animation, string key)
{
component ??= EntityManager.EnsureComponent<AnimationPlayerComponent>(uid);
Play(new Entity<AnimationPlayerComponent>(uid, component), animation, key);
Play(component, animation, key);
}
/// <summary>
/// Start playing an animation.
/// </summary>
[Obsolete("Use Play(EntityUid<AnimationPlayerComponent> ent, Animation animation, string key) instead")]
public void Play(AnimationPlayerComponent component, Animation animation, string key)
{
Play(new Entity<AnimationPlayerComponent>(component.Owner, component), animation, key);
}
public void Play(Entity<AnimationPlayerComponent> ent, Animation animation, string key)
{
AddComponent(ent);
AddComponent(component);
var playback = new AnimationPlaybackShared.AnimationPlayback(animation);
#if DEBUG
@@ -127,14 +120,14 @@ namespace Robust.Client.GameObjects
return;
}
if (!EntityManager.TryGetComponent(ent, compTrack.ComponentType, out var animatedComp))
if (!EntityManager.TryGetComponent(component.Owner, compTrack.ComponentType, out var animatedComp))
{
_sawmill.Error(
$"Attempted to play a component animation, but the entity {ToPrettyString(ent)} does not have the component to be animated: {compTrack.ComponentType}.");
$"Attempted to play a component animation, but the entity {ToPrettyString(component.Owner)} does not have the component to be animated: {compTrack.ComponentType}.");
return;
}
if (IsClientSide(ent) || !animatedComp.NetSyncEnabled)
if (IsClientSide(component.Owner) || !animatedComp.NetSyncEnabled)
continue;
var reg = _compFact.GetRegistration(animatedComp);
@@ -147,13 +140,13 @@ namespace Robust.Client.GameObjects
if (animatedComp.GetType().GetProperty(compTrack.Property) is { } property &&
property.HasCustomAttribute<AutoNetworkedFieldAttribute>())
{
_sawmill.Warning($"Playing a component animation on a networked component {reg.Name} belonging to {ToPrettyString(ent)}");
_sawmill.Warning($"Playing a component animation on a networked component {reg.Name} belonging to {ToPrettyString(component.Owner)}");
}
}
}
#endif
ent.Comp.PlayingAnimations.Add(key, playback);
component.PlayingAnimations.Add(key, playback);
}
public bool HasRunningAnimation(EntityUid uid, string key)

View File

@@ -1,4 +1,3 @@
using System.Collections.Generic;
using System.Numerics;
using Robust.Client.Graphics;
using Robust.Shared.Enums;
@@ -59,8 +58,6 @@ namespace Robust.Client.GameObjects
public override OverlaySpace Space => OverlaySpace.WorldSpace;
private List<Entity<MapGridComponent>> _grids = new();
public GridChunkBoundsOverlay(IEntityManager entManager, IEyeManager eyeManager, IMapManager mapManager)
{
_entityManager = entManager;
@@ -74,15 +71,13 @@ namespace Robust.Client.GameObjects
var viewport = args.WorldBounds;
var worldHandle = args.WorldHandle;
_grids.Clear();
_mapManager.FindGridsIntersecting(currentMap, viewport, ref _grids);
foreach (var grid in _grids)
foreach (var grid in _mapManager.FindGridsIntersecting(currentMap, viewport))
{
var worldMatrix = _entityManager.GetComponent<TransformComponent>(grid).WorldMatrix;
var worldMatrix = _entityManager.GetComponent<TransformComponent>(grid.Owner).WorldMatrix;
worldHandle.SetTransform(worldMatrix);
var transform = new Transform(Vector2.Zero, Angle.Zero);
var chunkEnumerator = grid.Comp.GetMapChunks(viewport);
var chunkEnumerator = grid.GetMapChunks(viewport);
while (chunkEnumerator.MoveNext(out var chunk))
{

View File

@@ -28,11 +28,11 @@ namespace Robust.Client.GameObjects
// Only keep track of transforms actively lerping.
// Much faster than iterating 3000+ transforms every frame.
[ViewVariables] private readonly List<Entity<TransformComponent>> _lerpingTransforms = new();
[ViewVariables] private readonly List<TransformComponent> _lerpingTransforms = new();
public void Reset()
{
foreach (var (_, xform) in _lerpingTransforms)
foreach (var xform in _lerpingTransforms)
{
xform.ActivelyLerping = false;
xform.NextPosition = null;
@@ -77,7 +77,7 @@ namespace Robust.Client.GameObjects
return;
}
_lerpingTransforms.Add((uid, xform));
_lerpingTransforms.Add(xform);
xform.ActivelyLerping = true;
xform.PredictedLerp = false;
xform.LerpParent = xform.ParentUid;
@@ -96,7 +96,7 @@ namespace Robust.Client.GameObjects
if (!xform.ActivelyLerping)
{
_lerpingTransforms.Add((uid, xform));
_lerpingTransforms.Add(xform);
xform.ActivelyLerping = true;
xform.PredictedLerp = true;
xform.PrevRotation = xform._localRotation;
@@ -123,7 +123,8 @@ namespace Robust.Client.GameObjects
for (var i = 0; i < _lerpingTransforms.Count; i++)
{
var (uid, transform) = _lerpingTransforms[i];
var transform = _lerpingTransforms[i];
var uid = transform.Owner;
var found = false;
// Only lerp if parent didn't change.

View File

@@ -55,7 +55,7 @@ namespace Robust.Client.GameStates
private readonly Dictionary<EntityUid, HashSet<Type>> _pendingReapplyNetStates = new();
private readonly HashSet<NetEntity> _stateEnts = new();
private readonly List<EntityUid> _toDelete = new();
private readonly List<IComponent> _toRemove = new();
private readonly List<Component> _toRemove = new();
private readonly Dictionary<NetEntity, Dictionary<ushort, ComponentState>> _outputData = new();
private readonly List<(EntityUid, TransformComponent)> _queuedBroadphaseUpdates = new();
@@ -499,7 +499,7 @@ namespace Robust.Client.GameStates
var countReset = 0;
var system = _entitySystemManager.GetEntitySystem<ClientDirtySystem>();
var metaQuery = _entityManager.GetEntityQuery<MetaDataComponent>();
RemQueue<IComponent> toRemove = new();
RemQueue<Component> toRemove = new();
foreach (var entity in system.DirtyEntities)
{
@@ -604,7 +604,7 @@ namespace Robust.Client.GameStates
/// Whenever a new entity is created, the server doesn't send full state data, given that much of the data
/// can simply be obtained from the entity prototype information. This function basically creates a fake
/// initial server state for any newly created entity. It does this by simply using the standard <see
/// cref="IEntityManager.GetComponentState"/>.
/// cref="IEntityManager.GetComponentState(IEventBus, IComponent)"/>.
/// </remarks>
private void MergeImplicitData(IEnumerable<NetEntity> createdEntities)
{
@@ -1187,7 +1187,8 @@ namespace Robust.Client.GameStates
{
if (!meta.NetComponents.TryGetValue(id, out var comp))
{
comp = _compFactory.GetComponent(id);
comp = (Component) _compFactory.GetComponent(id);
comp.Owner = uid;
_entityManager.AddComponent(uid, comp, true, metadata: meta);
}
@@ -1200,7 +1201,8 @@ namespace Robust.Client.GameStates
{
if (!meta.NetComponents.TryGetValue(compChange.NetID, out var comp))
{
comp = _compFactory.GetComponent(compChange.NetID);
comp = (Component) _compFactory.GetComponent(compChange.NetID);
comp.Owner = uid;
_entityManager.AddComponent(uid, comp, true, metadata:meta);
}
else if (compChange.LastModifiedTick <= lastApplied && lastApplied != GameTick.Zero)
@@ -1270,9 +1272,7 @@ namespace Robust.Client.GameStates
var handleState = new ComponentHandleState(cur, next);
bus.RaiseComponentEvent(comp, ref handleState);
}
#pragma warning disable CS0168 // Variable is declared but never used
catch (Exception e)
#pragma warning restore CS0168 // Variable is declared but never used
{
#if EXCEPTION_TOLERANCE
_sawmill.Error($"Failed to apply comp state: entity={_entities.ToPrettyString(uid)}, comp={comp.GetType()}");
@@ -1428,7 +1428,8 @@ namespace Robust.Client.GameStates
{
if (!meta.NetComponents.TryGetValue(id, out var comp))
{
comp = _compFactory.GetComponent(id);
comp = (Component) _compFactory.GetComponent(id);
comp.Owner = uid;
_entityManager.AddComponent(uid, comp, true, meta);
}

View File

@@ -4,6 +4,7 @@ using OpenToolkit.Graphics.OpenGL4;
using Robust.Shared.GameObjects;
using Robust.Shared.Graphics;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Maths;
@@ -40,23 +41,21 @@ namespace Robust.Client.Graphics.Clyde
gridProgram.SetUniformTextureMaybe(UniILightTexture, TextureUnit.Texture1);
gridProgram.SetUniform(UniIModUV, new Vector4(0, 0, 1, 1));
var grids = new List<Entity<MapGridComponent>>();
_mapManager.FindGridsIntersecting(mapId, worldBounds, ref grids);
foreach (var mapGrid in grids)
foreach (var mapGrid in _mapManager.FindGridsIntersecting(mapId, worldBounds))
{
if (!_mapChunkData.ContainsKey(mapGrid))
if (!_mapChunkData.ContainsKey(mapGrid.Owner))
continue;
var transform = _entityManager.GetComponent<TransformComponent>(mapGrid);
var transform = _entityManager.GetComponent<TransformComponent>(mapGrid.Owner);
gridProgram.SetUniform(UniIModelMatrix, transform.WorldMatrix);
var enumerator = mapGrid.Comp.GetMapChunks(worldBounds);
var enumerator = mapGrid.GetMapChunks(worldBounds);
while (enumerator.MoveNext(out var chunk))
{
if (_isChunkDirty(mapGrid, chunk))
_updateChunkMesh(mapGrid, chunk);
var datum = _mapChunkData[mapGrid][chunk.Indices];
var datum = _mapChunkData[mapGrid.Owner][chunk.Indices];
if (datum.TileCount == 0)
continue;
@@ -71,9 +70,9 @@ namespace Robust.Client.Graphics.Clyde
}
}
private void _updateChunkMesh(Entity<MapGridComponent> grid, MapChunk chunk)
private void _updateChunkMesh(MapGridComponent grid, MapChunk chunk)
{
var data = _mapChunkData[grid];
var data = _mapChunkData[grid.Owner];
if (!data.TryGetValue(chunk.Indices, out var datum))
{
@@ -84,7 +83,7 @@ namespace Robust.Client.Graphics.Clyde
Span<Vertex2D> vertexBuffer = stackalloc Vertex2D[_verticesPerChunk(chunk)];
var i = 0;
var cSz = grid.Comp.ChunkSize;
var cSz = grid.ChunkSize;
var cScaled = chunk.Indices * cSz;
for (ushort x = 0; x < cSz; x++)
{
@@ -131,7 +130,7 @@ namespace Robust.Client.Graphics.Clyde
datum.TileCount = i;
}
private unsafe MapChunkData _initChunkBuffers(Entity<MapGridComponent> grid, MapChunk chunk)
private unsafe MapChunkData _initChunkBuffers(MapGridComponent grid, MapChunk chunk)
{
var vao = GenVertexArray();
BindVertexArray(vao);
@@ -159,19 +158,19 @@ namespace Robust.Client.Graphics.Clyde
Dirty = true
};
_mapChunkData[grid].Add(chunk.Indices, datum);
_mapChunkData[grid.Owner].Add(chunk.Indices, datum);
return datum;
}
private bool _isChunkDirty(Entity<MapGridComponent> grid, MapChunk chunk)
private bool _isChunkDirty(MapGridComponent grid, MapChunk chunk)
{
var data = _mapChunkData[grid];
var data = _mapChunkData[grid.Owner];
return !data.TryGetValue(chunk.Indices, out var datum) || datum.Dirty;
}
public void _setChunkDirty(Entity<MapGridComponent> grid, Vector2i chunk)
public void _setChunkDirty(MapGridComponent grid, Vector2i chunk)
{
var data = _mapChunkData.GetOrNew(grid);
var data = _mapChunkData.GetOrNew(grid.Owner);
if (data.TryGetValue(chunk, out var datum))
{
datum.Dirty = true;
@@ -185,7 +184,7 @@ namespace Robust.Client.Graphics.Clyde
{
var grid = args.Grid;
var chunk = grid.GridTileToChunkIndices(pos);
_setChunkDirty((args.GridEnt, grid), chunk);
_setChunkDirty(grid, chunk);
}
}
@@ -193,7 +192,7 @@ namespace Robust.Client.Graphics.Clyde
{
var grid = _mapManager.GetGrid(args.NewTile.GridUid);
var chunk = grid.GridTileToChunkIndices(new Vector2i(args.NewTile.X, args.NewTile.Y));
_setChunkDirty((args.NewTile.GridUid, grid), chunk);
_setChunkDirty(grid, chunk);
}
private void _updateOnGridCreated(GridStartupEvent ev)

View File

@@ -350,7 +350,7 @@ namespace Robust.Client.Graphics.Clyde
_renderHandle.Viewport(Box2i.FromDimensions(-flippedPos, screenSize));
if (entry.Sprite.RaiseShaderEvent)
_entityManager.EventBus.RaiseLocalEvent(entry.Uid,
_entityManager.EventBus.RaiseLocalEvent(entry.Sprite.Owner,
new BeforePostShaderRenderEvent(entry.Sprite, viewport), false);
}
}

View File

@@ -1,3 +1,11 @@
using Robust.Client.ComponentTrees;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
using Robust.Shared.Threading;
using Robust.Shared.Utility;
using System;
using System.Buffers;
using System.Collections.Generic;
@@ -6,15 +14,7 @@ using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics;
using System.Runtime.Intrinsics.X86;
using System.Threading.Tasks;
using Robust.Client.ComponentTrees;
using Robust.Client.GameObjects;
using Robust.Shared.GameObjects;
using Robust.Shared.Graphics;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
using Robust.Shared.Threading;
using Robust.Shared.Utility;
namespace Robust.Client.Graphics.Clyde;
@@ -260,7 +260,7 @@ internal partial class Clyde
if (cmp != 0)
return cmp;
return a.Uid.CompareTo(b.Uid);
return a.Sprite.Owner.CompareTo(b.Sprite.Owner);
}
}
}

View File

@@ -17,9 +17,11 @@ using Robust.Shared.IoC;
using Robust.Shared.Localization;
using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Profiling;
using Robust.Shared.Timing;
using SixLabors.ImageSharp;
using Color = Robust.Shared.Maths.Color;
using DependencyAttribute = Robust.Shared.IoC.DependencyAttribute;
using TextureWrapMode = Robust.Shared.Graphics.TextureWrapMode;
namespace Robust.Client.Graphics.Clyde

View File

@@ -1,13 +1,12 @@
using System;
using System.Collections.Generic;
using System.Numerics;
using Robust.Client.Graphics;
using Robust.Client.ResourceManagement;
using Robust.Shared.Enums;
using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Maths;
using Direction = Robust.Shared.Maths.Direction;
namespace Robust.Client.Map;
@@ -23,8 +22,6 @@ public sealed class TileEdgeOverlay : Overlay
public override OverlaySpace Space => OverlaySpace.WorldSpaceBelowEntities;
private List<Entity<MapGridComponent>> _grids = new();
public TileEdgeOverlay(IEntityManager entManager, IMapManager mapManager, IResourceCache resource, ITileDefinitionManager tileDefManager)
{
_entManager = entManager;
@@ -39,18 +36,16 @@ public sealed class TileEdgeOverlay : Overlay
if (args.MapId == MapId.Nullspace)
return;
_grids.Clear();
_mapManager.FindGridsIntersecting(args.MapId, args.WorldBounds, ref _grids);
var xformQuery = _entManager.GetEntityQuery<TransformComponent>();
foreach (var grid in _grids)
foreach (var grid in _mapManager.FindGridsIntersecting(args.MapId, args.WorldBounds))
{
var tileSize = grid.Comp.TileSize;
var tileSize = grid.TileSize;
var tileDimensions = new Vector2(tileSize, tileSize);
var xform = xformQuery.GetComponent(grid);
var xform = xformQuery.GetComponent(grid.Owner);
args.WorldHandle.SetTransform(xform.WorldMatrix);
foreach (var tileRef in grid.Comp.GetTilesIntersecting(args.WorldBounds, false))
foreach (var tileRef in grid.GetTilesIntersecting(args.WorldBounds, false))
{
var tileDef = _tileDefManager[tileRef.Tile.TypeId];
@@ -66,7 +61,7 @@ public sealed class TileEdgeOverlay : Overlay
continue;
var neighborIndices = new Vector2i(tileRef.GridIndices.X + x, tileRef.GridIndices.Y + y);
var neighborTile = grid.Comp.GetTileRef(neighborIndices);
var neighborTile = grid.GetTileRef(neighborIndices);
var neighborDef = _tileDefManager[neighborTile.Tile.TypeId];
// If it's the same tile then no edge to be drawn.

View File

@@ -1,5 +1,6 @@
using System.Collections.Generic;
using JetBrains.Annotations;
using Robust.Client.Player;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Physics;
@@ -25,7 +26,7 @@ namespace Robust.Client.Physics
protected override void Cleanup(PhysicsMapComponent component, float frameTime)
{
var toRemove = new List<Entity<PhysicsComponent>>();
var toRemove = new List<PhysicsComponent>();
// Because we're not predicting 99% of bodies its sleep timer never gets incremented so we'll just do it ourselves.
// (and serializing it over the network isn't necessary?)
@@ -37,13 +38,13 @@ namespace Robust.Client.Physics
body.SleepTime += frameTime;
if (body.SleepTime > TimeToSleep)
{
toRemove.Add(new Entity<PhysicsComponent>(body.Owner, body));
toRemove.Add(body);
}
}
foreach (var body in toRemove)
{
SetAwake(body, false);
SetAwake(body.Owner, body, false);
}
base.Cleanup(component, frameTime);

View File

@@ -17,7 +17,7 @@
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="2.1.2" Condition="'$(UseSystemSqlite)' != 'True'" PrivateAssets="compile" />
<PackageReference Include="SpaceWizards.NFluidsynth" Version="0.1.1" PrivateAssets="compile" />
<PackageReference Include="NVorbis" Version="0.10.1" PrivateAssets="compile" />
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.3" />
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.7" />
<PackageReference Include="OpenToolkit.Graphics" Version="4.0.0-pre9.1" PrivateAssets="compile" />
<PackageReference Include="OpenTK.OpenAL" Version="4.7.5" PrivateAssets="compile" />
<PackageReference Include="SpaceWizards.SharpFont" Version="1.0.1" PrivateAssets="compile" />

View File

@@ -7,6 +7,7 @@ using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
using Robust.Shared.ViewVariables;
using Direction = Robust.Shared.Maths.Direction;
namespace Robust.Client.UserInterface.Controls
{
@@ -17,14 +18,18 @@ namespace Robust.Client.UserInterface.Controls
IEntityManager _entMan;
[ViewVariables]
public SpriteComponent? Sprite { get; private set; }
private SpriteComponent? _sprite;
public SpriteComponent? Sprite
{
get => _sprite;
[Obsolete("Use SetEntity()")]
set => SetEntity(value?.Owner);
}
[ViewVariables]
public EntityUid? Entity { get; private set; }
public Entity<SpriteComponent>? Ent => Entity == null || Sprite == null ? null : (Entity.Value, Sprite);
/// <summary>
/// This field configures automatic scaling of the sprite. This automatic scaling is done before
/// applying the explicitly set scale <see cref="SpriteView.Scale"/>.
@@ -119,22 +124,14 @@ namespace Robust.Client.UserInterface.Controls
public SpriteView()
{
_entMan = IoCManager.Resolve<IEntityManager>();
if (_entMan.TryGetComponent(Entity, out SpriteComponent? sprite))
{
Sprite = sprite;
}
_entMan.TryGetComponent(Entity, out _sprite);
RectClipContent = true;
}
public void SetEntity(EntityUid? uid)
{
Entity = uid;
if (_entMan.TryGetComponent(Entity, out SpriteComponent? sprite))
{
Sprite = sprite;
}
_entMan.TryGetComponent(Entity, out _sprite);
}
protected override Vector2 MeasureOverride(Vector2 availableSize)
@@ -146,13 +143,13 @@ namespace Robust.Client.UserInterface.Controls
private void UpdateSize()
{
if (Entity == null || Sprite == null)
if (Entity == null || _sprite == null)
{
_spriteSize = default;
return;
}
var spriteBox = Sprite.CalculateRotatedBoundingBox(default, _worldRotation ?? Angle.Zero, _eyeRotation)
var spriteBox = _sprite.CalculateRotatedBoundingBox(default, _worldRotation ?? Angle.Zero, _eyeRotation)
.CalcBoundingBox();
if (!SpriteOffset)
@@ -194,10 +191,10 @@ namespace Robust.Client.UserInterface.Controls
internal override void DrawInternal(IRenderHandle renderHandle)
{
if (Entity is not {} uid || Sprite == null)
if (Entity is not {} uid || _sprite == null)
return;
if (Sprite.Deleted)
if (_sprite.Deleted)
{
SetEntity(null);
return;
@@ -217,11 +214,11 @@ namespace Robust.Client.UserInterface.Controls
var offset = SpriteOffset
? Vector2.Zero
: - (-_eyeRotation).RotateVec(Sprite.Offset) * new Vector2(1, -1) * EyeManager.PixelsPerMeter;
: - (-_eyeRotation).RotateVec(_sprite.Offset) * new Vector2(1, -1) * EyeManager.PixelsPerMeter;
var position = PixelSize / 2 + offset * stretch * UIScale;
var scale = Scale * UIScale * stretch;
renderHandle.DrawEntity(uid, position, scale, _worldRotation, _eyeRotation, OverrideDirection, Sprite);
renderHandle.DrawEntity(uid, position, scale, _worldRotation, _eyeRotation, OverrideDirection, _sprite);
}
}
}

View File

@@ -117,7 +117,7 @@ Mouse Pos:
{playerWorldOffset}
{playerCoordinates}
Rotation: {playerRotation.Degrees:F2}°
EntId: {controlledEntity}
EntId: {entityTransform.Owner}
GridUid: {entityTransform.GridUid}
Grid Rotation: {gridRotation.Degrees:F2}°");
}

View File

@@ -5,7 +5,7 @@ using Robust.Client.UserInterface.Controls;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Maths;
using static Robust.Client.UserInterface.Controls.BoxContainer;
namespace Robust.Client.ViewVariables.Editors
@@ -67,13 +67,13 @@ namespace Robust.Client.ViewVariables.Editors
var xVal = float.Parse(x.Text, CultureInfo.InvariantCulture);
var yVal = float.Parse(y.Text, CultureInfo.InvariantCulture);
if (!entityManager.HasComponent<MapGridComponent>(gridVal))
if (!mapManager.TryGetGrid(gridVal, out var grid))
{
ValueChanged(new EntityCoordinates(EntityUid.Invalid, new(xVal, yVal)));
return;
}
ValueChanged(new EntityCoordinates(gridVal, new(xVal, yVal)));
ValueChanged(new EntityCoordinates(grid.Owner, new(xVal, yVal)));
}
if (!ReadOnly)

View File

@@ -120,11 +120,7 @@ namespace Robust.Client.ViewVariables.Instances
};
top.HorizontalExpand = true;
hBox.AddChild(top);
var view = new SpriteView { OverrideDirection = Direction.South };
view.SetEntity(_entity);
hBox.AddChild(view);
hBox.AddChild(new SpriteView {Sprite = sprite, OverrideDirection = Direction.South});
vBoxContainer.AddChild(hBox);
}
else
@@ -435,7 +431,8 @@ namespace Robust.Client.ViewVariables.Instances
try
{
var comp = componentFactory.GetComponent(registration.Type);
var comp = (Component) componentFactory.GetComponent(registration.Type);
comp.Owner = _entity;
_entityManager.AddComponent(_entity, comp);
}
catch (Exception e)

View File

@@ -306,9 +306,7 @@ namespace Robust.Server
_modLoader.SetUseLoadContext(!ContentStart);
_modLoader.SetEnableSandboxing(Options.Sandboxing);
var resourceManifest = ResourceManifestData.LoadResourceManifest(_resources);
if (!_modLoader.TryLoadModulesFrom(Options.AssemblyDirectory, resourceManifest.AssemblyPrefix ?? Options.ContentModulePrefix))
if (!_modLoader.TryLoadModulesFrom(Options.AssemblyDirectory, Options.ContentModulePrefix))
{
_logger.Fatal("Errors while loading content assemblies.");
return true;

View File

@@ -1,4 +1,5 @@
using JetBrains.Annotations;
using System;
using JetBrains.Annotations;
using Robust.Shared.Console;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
@@ -46,7 +47,11 @@ namespace Robust.Server.Console.Commands
shell.WriteLine($"Entity {_entityManager.GetComponent<MetaDataComponent>(uid.Value).EntityName} already has a {componentName} component.");
}
var component = _componentFactory.GetComponent(registration.Type);
var component = (Component) _componentFactory.GetComponent(registration.Type);
#pragma warning disable CS0618
component.Owner = uid.Value;
#pragma warning restore CS0618
_entityManager.AddComponent(uid.Value, component);
shell.WriteLine($"Added {componentName} component to entity {_entityManager.GetComponent<MetaDataComponent>(uid.Value).EntityName}.");

View File

@@ -1,4 +1,5 @@
using System;
using Robust.Shared.Analyzers;
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.ViewVariables;
@@ -21,7 +22,7 @@ namespace Robust.Server.GameObjects
public int LayerVV
{
get => Layer;
set => EntitySystem.Get<VisibilitySystem>().SetLayer(Owner, this, value);
set => EntitySystem.Get<VisibilitySystem>().SetLayer(this, value);
}
}
}

View File

@@ -6,6 +6,7 @@ using System.IO;
using System.Linq;
using System.Numerics;
using Robust.Server.Maps;
using Robust.Shared.Collections;
using Robust.Shared.ContentPack;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
@@ -732,7 +733,7 @@ public sealed class MapLoaderSystem : EntitySystem
return;
// get ents that the grids will bind to
var gridComps = new Entity<MapGridComponent>[yamlGrids.Count];
var gridComps = new MapGridComponent[yamlGrids.Count];
var gridQuery = _serverEntityManager.GetEntityQuery<MapGridComponent>();
// linear search for new grid comps
@@ -744,7 +745,7 @@ public sealed class MapLoaderSystem : EntitySystem
// These should actually be new, pre-init
DebugTools.Assert(gridComp.LifeStage == ComponentLifeStage.Added);
gridComps[gridComp.GridIndex] = new Entity<MapGridComponent>(uid, gridComp);
gridComps[gridComp.GridIndex] = gridComp;
}
for (var index = 0; index < yamlGrids.Count; index++)
@@ -763,18 +764,18 @@ public sealed class MapLoaderSystem : EntitySystem
MappingDataNode yamlGridInfo = (MappingDataNode)yamlGrid["settings"];
SequenceDataNode yamlGridChunks = (SequenceDataNode)yamlGrid["chunks"];
AllocateMapGrid(gridComp, yamlGridInfo);
var gridUid = gridComp.Owner;
var grid = AllocateMapGrid(gridComp, yamlGridInfo);
var gridUid = grid.Owner;
foreach (var chunkNode in yamlGridChunks.Cast<MappingDataNode>())
{
var (chunkOffsetX, chunkOffsetY) = _serManager.Read<Vector2i>(chunkNode["ind"]);
_serManager.Read(chunkNode, _context, instanceProvider: () => _mapSystem.GetOrAddChunk(gridUid, gridComp, chunkOffsetX, chunkOffsetY), notNullableOverride: true);
_serManager.Read(chunkNode, _context, instanceProvider: () => _mapSystem.GetOrAddChunk(gridUid, grid, chunkOffsetX, chunkOffsetY), notNullableOverride: true);
}
}
}
private static void AllocateMapGrid(MapGridComponent gridComp, MappingDataNode yamlGridInfo)
private static MapGridComponent AllocateMapGrid(MapGridComponent gridComp, MappingDataNode yamlGridInfo)
{
// sane defaults
ushort csz = 16;
@@ -794,6 +795,8 @@ public sealed class MapLoaderSystem : EntitySystem
gridComp.ChunkSize = csz;
gridComp.TileSize = tsz;
return gridComp;
}
private void StartupEntities(MapData data)

View File

@@ -260,7 +260,7 @@ namespace Robust.Server.Physics
for (var i = 0; i < grids.Count - 1; i++)
{
var group = grids[i];
var newGrid = _mapManager.CreateGridEntity(mapId);
var newGrid = _mapManager.CreateGrid(mapId);
var newGridUid = newGrid.Owner;
var newGridXform = xformQuery.GetComponent(newGridUid);
newGrids[i] = newGridUid;
@@ -287,7 +287,7 @@ namespace Robust.Server.Physics
}
}
newGrid.Comp.SetTiles(tileData);
newGrid.SetTiles(tileData);
DebugTools.Assert(_mapManager.IsGrid(newGridUid), "A split grid had no tiles?");
// Set tiles on new grid + update anchored entities

View File

@@ -199,11 +199,11 @@ namespace Robust.Server.Placement
}
else if (tileType != 0) // create a new grid
{
var newGrid = _mapManager.CreateGridEntity(coordinates.GetMapId(_entityManager));
var newGridXform = _entityManager.GetComponent<TransformComponent>(newGrid);
newGridXform.WorldPosition = coordinates.Position - newGrid.Comp.TileSizeHalfVector; // assume bottom left tile origin
var tilePos = newGrid.Comp.WorldToTile(coordinates.Position);
newGrid.Comp.SetTile(tilePos, new Tile(tileType));
var newGrid = _mapManager.CreateGrid(coordinates.GetMapId(_entityManager));
var newGridXform = _entityManager.GetComponent<TransformComponent>(newGrid.Owner);
newGridXform.WorldPosition = coordinates.Position - newGrid.TileSizeHalfVector; // assume bottom left tile origin
var tilePos = newGrid.WorldToTile(coordinates.Position);
newGrid.SetTile(tilePos, new Tile(tileType));
var placementEraseEvent = new PlacementTileEvent(tileType, coordinates, placingUserId);
_entityManager.EventBus.RaiseEvent(EventSource.Local, placementEraseEvent);

View File

@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Numerics;
using System.Reflection;
using System.Text;
@@ -187,10 +188,10 @@ namespace Robust.Shared.Scripting
}
#region EntityManager proxy methods
public T Comp<T>(EntityUid uid) where T : IComponent
public T Comp<T>(EntityUid uid) where T : Component
=> ent.GetComponent<T>(uid);
public bool TryComp<T>(EntityUid uid, out T? comp) where T : IComponent
public bool TryComp<T>(EntityUid uid, out T? comp) where T : Component
=> ent.TryGetComponent(uid, out comp);
public bool HasComp<T>(EntityUid uid)

View File

@@ -10,7 +10,7 @@ namespace Robust.Shared.Analyzers;
/// component state replication beyond just directly setting variables should not use this attribute.
/// </summary>
[AttributeUsage(AttributeTargets.Class, Inherited = false)]
[BaseTypeRequired(typeof(IComponent))]
[BaseTypeRequired(typeof(Component))]
public sealed class AutoGenerateComponentStateAttribute : Attribute
{
/// <summary>

View File

@@ -132,11 +132,6 @@ namespace Robust.Shared.Configuration
return long.Parse(input);
}
if (type == typeof(ushort))
{
return ushort.Parse(input);
}
throw new NotSupportedException();
}
}

View File

@@ -617,11 +617,6 @@ namespace Robust.Shared.Configuration
return long.Parse(value);
}
if (type == typeof(ushort))
{
return ushort.Parse(value);
}
// Must be a string.
return value;
}

View File

@@ -148,7 +148,7 @@ internal sealed class ListMapsCommand : LocalizedCommands
mapId, _map.IsMapInitialized(mapId),
_map.IsMapPaused(mapId),
_map.GetMapEntityId(mapId),
string.Join(",", _map.GetAllGrids(mapId).Select(grid => grid.Owner)));
string.Join(",", _map.GetAllMapGrids(mapId).Select(grid => grid.Owner)));
}
shell.WriteLine(msg.ToString());

View File

@@ -1,9 +1,11 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using Robust.Shared.ContentPack;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Players;
using Robust.Shared.Prototypes;
@@ -171,7 +173,7 @@ public static class CompletionHelper
}
}
public static IEnumerable<CompletionOption> Components<T>(string text, IEntityManager? entManager = null) where T : IComponent
public static IEnumerable<CompletionOption> Components<T>(string text, IEntityManager? entManager = null) where T : Component
{
IoCManager.Resolve(ref entManager);

View File

@@ -1,3 +1,4 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
@@ -8,7 +9,7 @@ namespace Robust.Shared.Console
/// Basic interface to handle console commands. Any class implementing this will be
/// registered with the console system through reflection.
/// </summary>
[UsedImplicitly(ImplicitUseTargetFlags.WithInheritors)]
[UsedImplicitly(ImplicitUseTargetFlags.WithInheritors), Obsolete("New commands should utilize ToolshedCommand.")]
public interface IConsoleCommand
{
/// <summary>

View File

@@ -1,3 +1,4 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using Robust.Shared.IoC;
@@ -5,6 +6,7 @@ using Robust.Shared.Localization;
namespace Robust.Shared.Console;
[Obsolete("You should use ToolshedCommand instead.")]
public abstract class LocalizedCommands : IConsoleCommand
{
[Dependency] protected readonly ILocalizationManager LocalizationManager = default!;

View File

@@ -1,10 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Network;
@@ -14,6 +9,12 @@ using Robust.Shared.Physics.Systems;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using Robust.Shared.ViewVariables;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Robust.Shared.Log;
using Robust.Shared.Serialization;
namespace Robust.Shared.Containers
{
@@ -61,7 +62,7 @@ namespace Robust.Shared.Containers
/// The entity that owns this container.
/// </summary>
[ViewVariables]
public EntityUid Owner { get; internal set; }
public EntityUid Owner => Manager.Owner;
/// <summary>
/// Should the contents of this container be shown? False for closed containers like lockers, true for
@@ -76,7 +77,10 @@ namespace Robust.Shared.Containers
DebugTools.AssertNull(ID);
ID = id;
Manager = component;
Owner = owner;
// TODO fix container init.
// Eventually, we want an owner field, but currently it needs to use component.Owner
// Owner = owner;
}
/// <summary>
@@ -103,9 +107,10 @@ namespace Robust.Shared.Containers
bool force = false)
{
IoCManager.Resolve(ref entMan);
DebugTools.AssertOwner(toinsert, transform);
DebugTools.AssertOwner(Owner, ownerTransform);
DebugTools.AssertOwner(toinsert, physics);
DebugTools.Assert(transform == null || transform.Owner == toinsert);
DebugTools.Assert(ownerTransform == null || ownerTransform.Owner == Owner);
DebugTools.Assert(ownerTransform == null || ownerTransform.Owner == Owner);
DebugTools.Assert(physics == null || physics.Owner == toinsert);
DebugTools.Assert(!ExpectedEntities.Contains(entMan.GetNetEntity(toinsert)));
DebugTools.Assert(Manager.Containers.ContainsKey(ID));
@@ -293,8 +298,8 @@ namespace Robust.Shared.Containers
IoCManager.Resolve(ref entMan);
DebugTools.AssertNotNull(Manager);
DebugTools.Assert(entMan.EntityExists(toRemove));
DebugTools.AssertOwner(toRemove, xform);
DebugTools.AssertOwner(toRemove, meta);
DebugTools.Assert(xform == null || xform.Owner == toRemove);
DebugTools.Assert(meta == null || meta.Owner == toRemove);
xform ??= entMan.GetComponent<TransformComponent>(toRemove);
meta ??= entMan.GetComponent<MetaDataComponent>(toRemove);
@@ -332,7 +337,7 @@ namespace Robust.Shared.Containers
else if (reparent)
{
// Container ECS when.
sys.AttachParentToContainerOrGrid((toRemove, xform));
sys.AttachParentToContainerOrGrid(xform);
if (localRotation != null)
entMan.EntitySysManager.GetEntitySystem<SharedTransformSystem>().SetLocalRotation(xform, localRotation.Value);
}

View File

@@ -7,6 +7,7 @@ using Robust.Shared.GameStates;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Network;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
@@ -21,6 +22,7 @@ namespace Robust.Shared.Containers
{
[Dependency] private readonly IDynamicTypeFactoryInternal _dynFactory = default!;
[Dependency] private readonly IEntityManager _entMan = default!;
[Dependency] private readonly INetManager _netMan = default!;
[DataField("containers")]
public Dictionary<string, BaseContainer> Containers = new();
@@ -28,37 +30,54 @@ namespace Robust.Shared.Containers
void ISerializationHooks.AfterDeserialization()
{
// TODO custom type serializer
// TODO set owner uid on init.
foreach (var (id, container) in Containers)
{
container.Manager = this;
container.Owner = Owner;
container.ID = id;
}
}
public T MakeContainer<T>(EntityUid uid, string id)
/// <inheritdoc />
protected internal override void OnRemove()
{
base.OnRemove();
foreach (var container in Containers.Values)
{
container.Shutdown(_entMan, _netMan);
}
Containers.Clear();
}
/// <inheritdoc />
public T MakeContainer<T>(string id)
where T : BaseContainer
{
if (HasContainer(id))
throw new ArgumentException($"Container with specified ID already exists: '{id}'");
var container = _dynFactory.CreateInstanceUnchecked<T>(typeof(T), inject: false);
container.Init(id, uid, this);
container.Init(id, Owner, this);
Containers[id] = container;
_entMan.Dirty(this);
return container;
}
/// <inheritdoc />
public BaseContainer GetContainer(string id)
{
return Containers[id];
}
/// <inheritdoc />
public bool HasContainer(string id)
{
return Containers.ContainsKey(id);
}
/// <inheritdoc />
public bool TryGetContainer(string id, [NotNullWhen(true)] out BaseContainer? container)
{
var ret = Containers.TryGetValue(id, out var cont);
@@ -66,6 +85,7 @@ namespace Robust.Shared.Containers
return ret;
}
/// <inheritdoc />
public bool TryGetContainer(EntityUid entity, [NotNullWhen(true)] out BaseContainer? container)
{
foreach (var contain in Containers.Values)
@@ -81,6 +101,7 @@ namespace Robust.Shared.Containers
return false;
}
/// <inheritdoc />
public bool ContainsEntity(EntityUid entity)
{
foreach (var container in Containers.Values)
@@ -91,6 +112,7 @@ namespace Robust.Shared.Containers
return false;
}
/// <inheritdoc />
public bool Remove(EntityUid toremove,
TransformComponent? xform = null,
MetaDataComponent? meta = null,
@@ -205,9 +227,7 @@ namespace Robust.Shared.Containers
object IEnumerator.Current => Current;
public void Dispose()
{
}
public void Dispose() { }
}
}
}

View File

@@ -8,7 +8,6 @@ using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Maths;
using Robust.Shared.Network;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
using Robust.Shared.Utility;
@@ -17,7 +16,6 @@ namespace Robust.Shared.Containers
{
public abstract partial class SharedContainerSystem
{
[Dependency] private readonly INetManager _net = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly EntityLookupSystem _lookup = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
@@ -36,7 +34,6 @@ namespace Robust.Shared.Containers
SubscribeLocalEvent<EntParentChangedMessage>(OnParentChanged);
SubscribeLocalEvent<ContainerManagerComponent, ComponentStartup>(OnStartupValidation);
SubscribeLocalEvent<ContainerManagerComponent, ComponentGetState>(OnContainerGetState);
SubscribeLocalEvent<ContainerManagerComponent, ComponentRemove>(OnContainerManagerRemove);
_gridQuery = GetEntityQuery<MapGridComponent>();
_mapQuery = GetEntityQuery<MapComponent>();
@@ -65,16 +62,6 @@ namespace Robust.Shared.Containers
args.State = new ContainerManagerComponent.ContainerManagerComponentState(containerSet);
}
private void OnContainerManagerRemove(EntityUid uid, ContainerManagerComponent component, ComponentRemove args)
{
foreach (var container in component.Containers.Values)
{
container.Shutdown(EntityManager, _net);
}
component.Containers.Clear();
}
// TODO: Make ContainerManagerComponent ECS and make these proxy methods the real deal.
#region Proxy Methods
@@ -83,16 +70,16 @@ namespace Robust.Shared.Containers
where T : BaseContainer
{
if (!Resolve(uid, ref containerManager, false))
containerManager = AddComp<ContainerManagerComponent>(uid); // Happy Vera.
containerManager = EntityManager.AddComponent<ContainerManagerComponent>(uid); // Happy Vera.
return containerManager.MakeContainer<T>(uid, id);
return containerManager.MakeContainer<T>(id);
}
public T EnsureContainer<T>(EntityUid uid, string id, out bool alreadyExisted, ContainerManagerComponent? containerManager = null)
where T : BaseContainer
{
if (!Resolve(uid, ref containerManager, false))
containerManager = AddComp<ContainerManagerComponent>(uid);
containerManager = EntityManager.AddComponent<ContainerManagerComponent>(uid);
if (TryGetContainer(uid, id, out var container, containerManager))
{
@@ -141,7 +128,7 @@ namespace Robust.Shared.Containers
public bool TryGetContainingContainer(EntityUid uid, EntityUid containedUid, [NotNullWhen(true)] out BaseContainer? container, ContainerManagerComponent? containerManager = null, bool skipExistCheck = false)
{
if (Resolve(uid, ref containerManager, false) && (skipExistCheck || Exists(containedUid)))
if (Resolve(uid, ref containerManager, false) && (skipExistCheck || EntityManager.EntityExists(containedUid)))
return containerManager.TryGetContainer(containedUid, out container);
container = null;
@@ -150,7 +137,7 @@ namespace Robust.Shared.Containers
public bool ContainsEntity(EntityUid uid, EntityUid containedUid, ContainerManagerComponent? containerManager = null)
{
if (!Resolve(uid, ref containerManager, false) || !Exists(containedUid))
if (!Resolve(uid, ref containerManager, false) || !EntityManager.EntityExists(containedUid))
return false;
return containerManager.ContainsEntity(containedUid);
@@ -228,7 +215,7 @@ namespace Robust.Shared.Containers
{
if (meta == null)
{
metas ??= GetEntityQuery<MetaDataComponent>();
metas ??= EntityManager.GetEntityQuery<MetaDataComponent>();
meta = metas.Value.GetComponent(uid);
}
@@ -237,7 +224,7 @@ namespace Robust.Shared.Containers
if (xform == null)
{
xforms ??= GetEntityQuery<TransformComponent>();
xforms ??= EntityManager.GetEntityQuery<TransformComponent>();
xform = xforms.Value.GetComponent(uid);
}
@@ -255,7 +242,7 @@ namespace Robust.Shared.Containers
EntityQuery<T> entityQuery,
[NotNullWhen(true)] ref T? foundComponent,
MetaDataComponent? meta = null,
TransformComponent? xform = null) where T : IComponent
TransformComponent? xform = null) where T : Component
{
if (!MetaQuery.Resolve(uid, ref meta))
return false;
@@ -283,7 +270,7 @@ namespace Robust.Shared.Containers
EntityQuery<T> entityQuery,
List<T> foundComponents,
MetaDataComponent? meta = null,
TransformComponent? xform = null) where T : IComponent
TransformComponent? xform = null) where T : Component
{
if (!MetaQuery.Resolve(uid, ref meta))
return foundComponents.Any();
@@ -297,7 +284,7 @@ namespace Robust.Shared.Containers
if (!xform.ParentUid.Valid)
return foundComponents.Any();
if (TryComp(xform.ParentUid, out T? foundComponent))
if (EntityManager.TryGetComponent(xform.ParentUid, out T? foundComponent))
foundComponents.Add(foundComponent);
return TryFindComponentsOnEntityContainerOrParent(xform.ParentUid, entityQuery, foundComponents);
@@ -394,7 +381,7 @@ namespace Robust.Shared.Containers
/// </summary>
public bool TryGetOuterContainer(EntityUid uid, TransformComponent xform, [NotNullWhen(true)] out BaseContainer? container)
{
var xformQuery = GetEntityQuery<TransformComponent>();
var xformQuery = EntityManager.GetEntityQuery<TransformComponent>();
return TryGetOuterContainer(uid, xform, out container, xformQuery);
}
@@ -406,8 +393,8 @@ namespace Robust.Shared.Containers
if (!uid.IsValid())
return false;
var conQuery = GetEntityQuery<ContainerManagerComponent>();
var metaQuery = GetEntityQuery<MetaDataComponent>();
var conQuery = EntityManager.GetEntityQuery<ContainerManagerComponent>();
var metaQuery = EntityManager.GetEntityQuery<MetaDataComponent>();
var child = uid;
var parent = xform.ParentUid;
@@ -501,26 +488,20 @@ namespace Robust.Shared.Containers
}
}
[Obsolete("Use AttachParentToContainerOrGrid(EntityUid<TransformComponent>) instead")]
public void AttachParentToContainerOrGrid(TransformComponent transform)
{
AttachParentToContainerOrGrid(new Entity<TransformComponent>(transform.Owner, transform));
}
public void AttachParentToContainerOrGrid(Entity<TransformComponent> transform)
{
// TODO make this check upwards for any container, and parent to that.
// Currently this just checks the direct parent, so entities will still teleport through containers.
if (!transform.Comp.ParentUid.IsValid()
|| !TryGetContainingContainer(transform.Comp.ParentUid, out var container)
if (!transform.ParentUid.IsValid()
|| !TryGetContainingContainer(transform.ParentUid, out var container)
|| !TryInsertIntoContainer(transform, container))
transform.Comp.AttachToGridOrMap();
transform.AttachToGridOrMap();
}
private bool TryInsertIntoContainer(Entity<TransformComponent> transform, BaseContainer container)
private bool TryInsertIntoContainer(TransformComponent transform, BaseContainer container)
{
if (container.Insert(transform)) return true;
if (container.Insert(transform.Owner)) return true;
if (Transform(container.Owner).ParentUid.IsValid()
&& TryGetContainingContainer(container.Owner, out var newContainer))

View File

@@ -1,92 +0,0 @@
using System;
using System.IO;
using Robust.Shared.Utility;
using YamlDotNet.RepresentationModel;
namespace Robust.Shared.ContentPack;
internal sealed record ResourceManifestData(
string[] Modules,
string? AssemblyPrefix,
string? DefaultWindowTitle,
string? WindowIconSet,
string? SplashLogo,
bool AutoConnect,
string[]? ClientAssemblies
)
{
public static readonly ResourceManifestData Default =
new ResourceManifestData(Array.Empty<string>(), null, null, null, null, true, null);
public static ResourceManifestData LoadResourceManifest(IResourceManager res)
{
// Parses /manifest.yml for game-specific settings that cannot be exclusively set up by content code.
if (!res.TryContentFileRead("/manifest.yml", out var stream))
return ResourceManifestData.Default;
var yamlStream = new YamlStream();
using (stream)
{
using var streamReader = new StreamReader(stream, EncodingHelpers.UTF8);
yamlStream.Load(streamReader);
}
if (yamlStream.Documents.Count == 0)
return ResourceManifestData.Default;
if (yamlStream.Documents.Count != 1 || yamlStream.Documents[0].RootNode is not YamlMappingNode mapping)
{
throw new InvalidOperationException(
"Expected a single YAML document with root mapping for /manifest.yml");
}
var modules = ReadStringArray(mapping, "modules") ?? Array.Empty<string>();
string? assemblyPrefix = null;
if (mapping.TryGetNode("assemblyPrefix", out var prefixNode))
assemblyPrefix = prefixNode.AsString();
string? defaultWindowTitle = null;
if (mapping.TryGetNode("defaultWindowTitle", out var winTitleNode))
defaultWindowTitle = winTitleNode.AsString();
string? windowIconSet = null;
if (mapping.TryGetNode("windowIconSet", out var iconSetNode))
windowIconSet = iconSetNode.AsString();
string? splashLogo = null;
if (mapping.TryGetNode("splashLogo", out var splashNode))
splashLogo = splashNode.AsString();
bool autoConnect = true;
if (mapping.TryGetNode("autoConnect", out var autoConnectNode))
autoConnect = autoConnectNode.AsBool();
var clientAssemblies = ReadStringArray(mapping, "clientAssemblies");
return new ResourceManifestData(
modules,
assemblyPrefix,
defaultWindowTitle,
windowIconSet,
splashLogo,
autoConnect,
clientAssemblies
);
static string[]? ReadStringArray(YamlMappingNode mapping, string key)
{
if (!mapping.TryGetNode(key, out var node))
return null;
var sequence = (YamlSequenceNode)node;
var array = new string[sequence.Children.Count];
for (var i = 0; i < array.Length; i++)
{
array[i] = sequence[i].AsString();
}
return array;
}
}
}

View File

@@ -1,4 +1,5 @@
using System;
using Robust.Shared.GameStates;
using Robust.Shared.IoC;
using Robust.Shared.Reflection;
using Robust.Shared.Serialization.Manager.Attributes;
@@ -7,7 +8,7 @@ using Robust.Shared.ViewVariables;
namespace Robust.Shared.GameObjects
{
/// <inheritdoc cref="IComponent"/>
/// <inheritdoc />
[Reflect(false)]
[ImplicitDataDefinitionForInheritors]
public abstract partial class Component : IComponent
@@ -16,8 +17,7 @@ namespace Robust.Shared.GameObjects
[ViewVariables(VVAccess.ReadWrite)]
private bool _netSync { get; set; } = true;
[Obsolete("Do not use from content")]
public bool Networked { get; set; } = true;
internal bool Networked = true;
/// <inheritdoc />
public bool NetSyncEnabled
@@ -33,10 +33,19 @@ namespace Robust.Shared.GameObjects
/// <inheritdoc />
[ViewVariables]
public ComponentLifeStage LifeStage { get; [Obsolete("Do not use from content")] set; } = ComponentLifeStage.PreAdd;
public ComponentLifeStage LifeStage { get; internal set; } = ComponentLifeStage.PreAdd;
/// <summary>
/// If true, and if this is a networked component, then component data will only be sent to players if their
/// controlled entity is the owner of this component. This is less performance intensive than <see cref="SessionSpecific"/>.
/// </summary>
public virtual bool SendOnlyToOwner => false;
/// <summary>
/// If true, and if this is a networked component, then this component will cause <see
/// cref="ComponentGetStateAttemptEvent"/> events to be raised to check whether a given player should
/// receive this component's state.
/// </summary>
public virtual bool SessionSpecific => false;
/// <inheritdoc />
@@ -53,11 +62,21 @@ namespace Robust.Shared.GameObjects
/// <inheritdoc />
[ViewVariables]
public GameTick CreationTick { get; [Obsolete("Do not use from content")] set; }
public GameTick CreationTick { get; internal set; }
/// <inheritdoc />
[ViewVariables]
public GameTick LastModifiedTick { get; [Obsolete("Do not use from content")] set; }
public GameTick LastModifiedTick { get; internal set; }
/// <summary>
/// Called when the component is removed from an entity.
/// Shuts down the component.
/// The component has already been marked as deleted in the component manager.
/// </summary>
protected internal virtual void OnRemove()
{
LifeStage = ComponentLifeStage.Deleted;
}
/// <inheritdoc />
[Obsolete]
@@ -69,15 +88,13 @@ namespace Robust.Shared.GameObjects
// these two methods clear the LastModifiedTick/CreationTick to mark it as "not different from prototype load".
// This is used as optimization in the game state system to avoid sending redundant component data.
[Obsolete("Do not use from content")]
public virtual void ClearTicks()
internal virtual void ClearTicks()
{
LastModifiedTick = GameTick.Zero;
ClearCreationTick();
}
[Obsolete("Do not use from content")]
public void ClearCreationTick()
internal void ClearCreationTick()
{
CreationTick = GameTick.Zero;
}

View File

@@ -9,7 +9,7 @@ namespace Robust.Shared.GameObjects
/// <summary>
/// Component that this event relates to.
/// </summary>
public IComponent Component { get; }
public Component Component { get; }
/// <summary>
/// EntityUid of the entity this component belongs to.
@@ -21,7 +21,7 @@ namespace Robust.Shared.GameObjects
/// </summary>
/// <param name="component">The relevant component</param>
/// <param name="owner">EntityUid of the entity this component belongs to.</param>
public ComponentEventArgs(IComponent component, EntityUid owner)
public ComponentEventArgs(Component component, EntityUid owner)
{
Component = component;
Owner = owner;

View File

@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Robust.Shared.GameStates;
using Robust.Shared.IoC;
using Robust.Shared.ViewVariables;
namespace Robust.Shared.GameObjects;
@@ -32,6 +33,14 @@ public sealed partial class AppearanceComponent : Component
[ViewVariables] internal Dictionary<Enum, object> AppearanceData = new();
[Dependency] private readonly IEntitySystemManager _sysMan = default!;
[Obsolete("Use SharedAppearanceSystem instead")]
public void SetData(Enum key, object value)
{
_sysMan.GetEntitySystem<SharedAppearanceSystem>().SetData(Owner, key, value, this);
}
[Obsolete("Use SharedAppearanceSystem instead")]
public bool TryGetData<T>(Enum key, [NotNullWhen(true)] out T data)
{

View File

@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using JetBrains.Annotations;
using Robust.Shared.GameStates;
using Robust.Shared.IoC;
using Robust.Shared.Prototypes;
@@ -8,6 +7,8 @@ using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
using Robust.Shared.ViewVariables;
using System;
using System.Collections.Generic;
namespace Robust.Shared.GameObjects
{
@@ -67,7 +68,7 @@ namespace Robust.Shared.GameObjects
/// The components attached to the entity that are currently networked.
/// </summary>
[ViewVariables]
internal readonly Dictionary<ushort, IComponent> NetComponents = new();
internal readonly Dictionary<ushort, Component> NetComponents = new();
/// <summary>
/// Network identifier for this entity.
@@ -198,8 +199,7 @@ namespace Robust.Shared.GameObjects
public bool EntityInitializing => EntityLifeStage == EntityLifeStage.Initializing;
public bool EntityDeleted => EntityLifeStage >= EntityLifeStage.Deleted;
[Obsolete("Do not use from content")]
public override void ClearTicks()
internal override void ClearTicks()
{
// Do not clear modified ticks.
// MetaDataComponent is used in the game state system to carry initial data like prototype ID.

View File

@@ -1,584 +0,0 @@
using Robust.Shared.Utility;
namespace Robust.Shared.GameObjects;
public record struct Entity<T>
where T : IComponent?
{
public EntityUid Owner;
public T Comp;
public Entity(EntityUid owner, T comp)
{
DebugTools.AssertOwner(owner, comp);
Owner = owner;
Comp = comp;
}
public static implicit operator Entity<T>((EntityUid Owner, T Comp) tuple)
{
return new Entity<T>(tuple.Owner, tuple.Comp);
}
public static implicit operator Entity<T?>(EntityUid owner)
{
return new Entity<T?>(owner, default);
}
public static implicit operator EntityUid(Entity<T> ent)
{
return ent.Owner;
}
public static implicit operator T(Entity<T> ent)
{
return ent.Comp;
}
public readonly void Deconstruct(out EntityUid owner, out T comp)
{
owner = Owner;
comp = Comp;
}
}
public record struct Entity<T1, T2>
where T1 : IComponent? where T2 : IComponent?
{
public EntityUid Owner;
public T1 Comp1;
public T2 Comp2;
public Entity(EntityUid owner, T1 comp1, T2 comp2)
{
DebugTools.AssertOwner(owner, comp1);
DebugTools.AssertOwner(owner, comp2);
Owner = owner;
Comp1 = comp1;
Comp2 = comp2;
}
public static implicit operator Entity<T1, T2>((EntityUid Owner, T1 Comp1, T2 Comp2) tuple)
{
return new Entity<T1, T2>(tuple.Owner, tuple.Comp1, tuple.Comp2);
}
public static implicit operator Entity<T1?, T2?>(EntityUid owner)
{
return new Entity<T1?, T2?>(owner, default, default);
}
public static implicit operator EntityUid(Entity<T1, T2> ent)
{
return ent.Owner;
}
public static implicit operator T1(Entity<T1, T2> ent)
{
return ent.Comp1;
}
public static implicit operator T2(Entity<T1, T2> ent)
{
return ent.Comp2;
}
public readonly void Deconstruct(out EntityUid owner, out T1 comp1, out T2 comp2)
{
owner = Owner;
comp1 = Comp1;
comp2 = Comp2;
}
}
public record struct Entity<T1, T2, T3>
where T1 : IComponent? where T2 : IComponent? where T3 : IComponent?
{
public EntityUid Owner;
public T1 Comp1;
public T2 Comp2;
public T3 Comp3;
public Entity(EntityUid owner, T1 comp1, T2 comp2, T3 comp3)
{
DebugTools.AssertOwner(owner, comp1);
DebugTools.AssertOwner(owner, comp2);
DebugTools.AssertOwner(owner, comp3);
Owner = owner;
Comp1 = comp1;
Comp2 = comp2;
Comp3 = comp3;
}
public static implicit operator Entity<T1, T2, T3>((EntityUid Owner, T1 Comp1, T2 Comp2, T3 Comp3) tuple)
{
return new Entity<T1, T2, T3>(tuple.Owner, tuple.Comp1, tuple.Comp2, tuple.Comp3);
}
public static implicit operator Entity<T1?, T2?, T3?>(EntityUid owner)
{
return new Entity<T1?, T2?, T3?>(owner, default, default, default);
}
public static implicit operator EntityUid(Entity<T1, T2, T3> ent)
{
return ent.Owner;
}
public static implicit operator T1(Entity<T1, T2, T3> ent)
{
return ent.Comp1;
}
public static implicit operator T2(Entity<T1, T2, T3> ent)
{
return ent.Comp2;
}
public static implicit operator T3(Entity<T1, T2, T3> ent)
{
return ent.Comp3;
}
public readonly void Deconstruct(out EntityUid owner, out T1 comp1, out T2 comp2, out T3 comp3)
{
owner = Owner;
comp1 = Comp1;
comp2 = Comp2;
comp3 = Comp3;
}
}
public record struct Entity<T1, T2, T3, T4>
where T1 : IComponent? where T2 : IComponent? where T3 : IComponent? where T4 : IComponent?
{
public EntityUid Owner;
public T1 Comp1;
public T2 Comp2;
public T3 Comp3;
public T4 Comp4;
public Entity(EntityUid owner, T1 comp1, T2 comp2, T3 comp3, T4 comp4)
{
DebugTools.AssertOwner(owner, comp1);
DebugTools.AssertOwner(owner, comp2);
DebugTools.AssertOwner(owner, comp3);
DebugTools.AssertOwner(owner, comp4);
Owner = owner;
Comp1 = comp1;
Comp2 = comp2;
Comp3 = comp3;
Comp4 = comp4;
}
public static implicit operator Entity<T1, T2, T3, T4>((EntityUid Owner, T1 Comp1, T2 Comp2, T3 Comp3, T4 Comp4) tuple)
{
return new Entity<T1, T2, T3, T4>(tuple.Owner, tuple.Comp1, tuple.Comp2, tuple.Comp3, tuple.Comp4);
}
public static implicit operator Entity<T1?, T2?, T3?, T4?>(EntityUid owner)
{
return new Entity<T1?, T2?, T3?, T4?>(owner, default, default, default, default);
}
public static implicit operator EntityUid(Entity<T1, T2, T3, T4> ent)
{
return ent.Owner;
}
public static implicit operator T1(Entity<T1, T2, T3, T4> ent)
{
return ent.Comp1;
}
public static implicit operator T2(Entity<T1, T2, T3, T4> ent)
{
return ent.Comp2;
}
public static implicit operator T3(Entity<T1, T2, T3, T4> ent)
{
return ent.Comp3;
}
public static implicit operator T4(Entity<T1, T2, T3, T4> ent)
{
return ent.Comp4;
}
public readonly void Deconstruct(out EntityUid owner, out T1 comp1, out T2 comp2, out T3 comp3, out T4 comp4)
{
owner = Owner;
comp1 = Comp1;
comp2 = Comp2;
comp3 = Comp3;
comp4 = Comp4;
}
}
public record struct Entity<T1, T2, T3, T4, T5>
where T1 : IComponent? where T2 : IComponent? where T3 : IComponent? where T4 : IComponent? where T5 : IComponent?
{
public EntityUid Owner;
public T1 Comp1;
public T2 Comp2;
public T3 Comp3;
public T4 Comp4;
public T5 Comp5;
public Entity(EntityUid owner, T1 comp1, T2 comp2, T3 comp3, T4 comp4, T5 comp5)
{
DebugTools.AssertOwner(owner, comp1);
DebugTools.AssertOwner(owner, comp2);
DebugTools.AssertOwner(owner, comp3);
DebugTools.AssertOwner(owner, comp4);
DebugTools.AssertOwner(owner, comp5);
Owner = owner;
Comp1 = comp1;
Comp2 = comp2;
Comp3 = comp3;
Comp4 = comp4;
Comp5 = comp5;
}
public static implicit operator Entity<T1, T2, T3, T4, T5>((EntityUid Owner, T1 Comp1, T2 Comp2, T3 Comp3, T4 Comp4, T5 Comp5) tuple)
{
return new Entity<T1, T2, T3, T4, T5>(tuple.Owner, tuple.Comp1, tuple.Comp2, tuple.Comp3, tuple.Comp4, tuple.Comp5);
}
public static implicit operator Entity<T1?, T2?, T3?, T4?, T5?>(EntityUid owner)
{
return new Entity<T1?, T2?, T3?, T4?, T5?>(owner, default, default, default, default, default);
}
public static implicit operator EntityUid(Entity<T1, T2, T3, T4, T5> ent)
{
return ent.Owner;
}
public static implicit operator T1(Entity<T1, T2, T3, T4, T5> ent)
{
return ent.Comp1;
}
public static implicit operator T2(Entity<T1, T2, T3, T4, T5> ent)
{
return ent.Comp2;
}
public static implicit operator T3(Entity<T1, T2, T3, T4, T5> ent)
{
return ent.Comp3;
}
public static implicit operator T4(Entity<T1, T2, T3, T4, T5> ent)
{
return ent.Comp4;
}
public static implicit operator T5(Entity<T1, T2, T3, T4, T5> ent)
{
return ent.Comp5;
}
public readonly void Deconstruct(out EntityUid owner, out T1 comp1, out T2 comp2, out T3 comp3, out T4 comp4, out T5 comp5)
{
owner = Owner;
comp1 = Comp1;
comp2 = Comp2;
comp3 = Comp3;
comp4 = Comp4;
comp5 = Comp5;
}
}
public record struct Entity<T1, T2, T3, T4, T5, T6>
where T1 : IComponent? where T2 : IComponent? where T3 : IComponent? where T4 : IComponent? where T5 : IComponent? where T6 : IComponent?
{
public EntityUid Owner;
public T1 Comp1;
public T2 Comp2;
public T3 Comp3;
public T4 Comp4;
public T5 Comp5;
public T6 Comp6;
public Entity(EntityUid owner, T1 comp1, T2 comp2, T3 comp3, T4 comp4, T5 comp5, T6 comp6)
{
DebugTools.AssertOwner(owner, comp1);
DebugTools.AssertOwner(owner, comp2);
DebugTools.AssertOwner(owner, comp3);
DebugTools.AssertOwner(owner, comp4);
DebugTools.AssertOwner(owner, comp5);
DebugTools.AssertOwner(owner, comp6);
Owner = owner;
Comp1 = comp1;
Comp2 = comp2;
Comp3 = comp3;
Comp4 = comp4;
Comp5 = comp5;
Comp6 = comp6;
}
public static implicit operator Entity<T1, T2, T3, T4, T5, T6>((EntityUid Owner, T1 Comp1, T2 Comp2, T3 Comp3, T4 Comp4, T5 Comp5, T6 Comp6) tuple)
{
return new Entity<T1, T2, T3, T4, T5, T6>(tuple.Owner, tuple.Comp1, tuple.Comp2, tuple.Comp3, tuple.Comp4, tuple.Comp5, tuple.Comp6);
}
public static implicit operator Entity<T1?, T2?, T3?, T4?, T5?, T6?>(EntityUid owner)
{
return new Entity<T1?, T2?, T3?, T4?, T5?, T6?>(owner, default, default, default, default, default, default);
}
public static implicit operator EntityUid(Entity<T1, T2, T3, T4, T5, T6> ent)
{
return ent.Owner;
}
public static implicit operator T1(Entity<T1, T2, T3, T4, T5, T6> ent)
{
return ent.Comp1;
}
public static implicit operator T2(Entity<T1, T2, T3, T4, T5, T6> ent)
{
return ent.Comp2;
}
public static implicit operator T3(Entity<T1, T2, T3, T4, T5, T6> ent)
{
return ent.Comp3;
}
public static implicit operator T4(Entity<T1, T2, T3, T4, T5, T6> ent)
{
return ent.Comp4;
}
public static implicit operator T5(Entity<T1, T2, T3, T4, T5, T6> ent)
{
return ent.Comp5;
}
public static implicit operator T6(Entity<T1, T2, T3, T4, T5, T6> ent)
{
return ent.Comp6;
}
public readonly void Deconstruct(out EntityUid owner, out T1 comp1, out T2 comp2, out T3 comp3, out T4 comp4, out T5 comp5, out T6 comp6)
{
owner = Owner;
comp1 = Comp1;
comp2 = Comp2;
comp3 = Comp3;
comp4 = Comp4;
comp5 = Comp5;
comp6 = Comp6;
}
}
public record struct Entity<T1, T2, T3, T4, T5, T6, T7>
where T1 : IComponent? where T2 : IComponent? where T3 : IComponent? where T4 : IComponent? where T5 : IComponent? where T6 : IComponent? where T7 : IComponent?
{
public EntityUid Owner;
public T1 Comp1;
public T2 Comp2;
public T3 Comp3;
public T4 Comp4;
public T5 Comp5;
public T6 Comp6;
public T7 Comp7;
public Entity(EntityUid owner, T1 comp1, T2 comp2, T3 comp3, T4 comp4, T5 comp5, T6 comp6, T7 comp7)
{
DebugTools.AssertOwner(owner, comp1);
DebugTools.AssertOwner(owner, comp2);
DebugTools.AssertOwner(owner, comp3);
DebugTools.AssertOwner(owner, comp4);
DebugTools.AssertOwner(owner, comp5);
DebugTools.AssertOwner(owner, comp6);
DebugTools.AssertOwner(owner, comp7);
Owner = owner;
Comp1 = comp1;
Comp2 = comp2;
Comp3 = comp3;
Comp4 = comp4;
Comp5 = comp5;
Comp6 = comp6;
Comp7 = comp7;
}
public static implicit operator Entity<T1, T2, T3, T4, T5, T6, T7>((EntityUid Owner, T1 Comp1, T2 Comp2, T3 Comp3, T4 Comp4, T5 Comp5, T6 Comp6, T7 Comp7) tuple)
{
return new Entity<T1, T2, T3, T4, T5, T6, T7>(tuple.Owner, tuple.Comp1, tuple.Comp2, tuple.Comp3, tuple.Comp4, tuple.Comp5, tuple.Comp6, tuple.Comp7);
}
public static implicit operator Entity<T1?, T2?, T3?, T4?, T5?, T6?, T7?>(EntityUid owner)
{
return new Entity<T1?, T2?, T3?, T4?, T5?, T6?, T7?>(owner, default, default, default, default, default, default, default);
}
public static implicit operator EntityUid(Entity<T1, T2, T3, T4, T5, T6, T7> ent)
{
return ent.Owner;
}
public static implicit operator T1(Entity<T1, T2, T3, T4, T5, T6, T7> ent)
{
return ent.Comp1;
}
public static implicit operator T2(Entity<T1, T2, T3, T4, T5, T6, T7> ent)
{
return ent.Comp2;
}
public static implicit operator T3(Entity<T1, T2, T3, T4, T5, T6, T7> ent)
{
return ent.Comp3;
}
public static implicit operator T4(Entity<T1, T2, T3, T4, T5, T6, T7> ent)
{
return ent.Comp4;
}
public static implicit operator T5(Entity<T1, T2, T3, T4, T5, T6, T7> ent)
{
return ent.Comp5;
}
public static implicit operator T6(Entity<T1, T2, T3, T4, T5, T6, T7> ent)
{
return ent.Comp6;
}
public static implicit operator T7(Entity<T1, T2, T3, T4, T5, T6, T7> ent)
{
return ent.Comp7;
}
public readonly void Deconstruct(out EntityUid owner, out T1 comp1, out T2 comp2, out T3 comp3, out T4 comp4, out T5 comp5, out T6 comp6, out T7 comp7)
{
owner = Owner;
comp1 = Comp1;
comp2 = Comp2;
comp3 = Comp3;
comp4 = Comp4;
comp5 = Comp5;
comp6 = Comp6;
comp7 = Comp7;
}
}
public record struct Entity<T1, T2, T3, T4, T5, T6, T7, T8>
where T1 : IComponent? where T2 : IComponent? where T3 : IComponent? where T4 : IComponent? where T5 : IComponent? where T6 : IComponent? where T7 : IComponent? where T8 : IComponent?
{
public EntityUid Owner;
public T1 Comp1;
public T2 Comp2;
public T3 Comp3;
public T4 Comp4;
public T5 Comp5;
public T6 Comp6;
public T7 Comp7;
public T8 Comp8;
public Entity(EntityUid owner, T1 comp1, T2 comp2, T3 comp3, T4 comp4, T5 comp5, T6 comp6, T7 comp7, T8 comp8)
{
DebugTools.AssertOwner(owner, comp1);
DebugTools.AssertOwner(owner, comp2);
DebugTools.AssertOwner(owner, comp3);
DebugTools.AssertOwner(owner, comp4);
DebugTools.AssertOwner(owner, comp5);
DebugTools.AssertOwner(owner, comp6);
DebugTools.AssertOwner(owner, comp7);
DebugTools.AssertOwner(owner, comp8);
Owner = owner;
Comp1 = comp1;
Comp2 = comp2;
Comp3 = comp3;
Comp4 = comp4;
Comp5 = comp5;
Comp6 = comp6;
Comp7 = comp7;
Comp8 = comp8;
}
public static implicit operator Entity<T1, T2, T3, T4, T5, T6, T7, T8>((EntityUid Owner, T1 Comp1, T2 Comp2, T3 Comp3, T4 Comp4, T5 Comp5, T6 Comp6, T7 Comp7, T8 Comp8) tuple)
{
return new Entity<T1, T2, T3, T4, T5, T6, T7, T8>(tuple.Owner, tuple.Comp1, tuple.Comp2, tuple.Comp3, tuple.Comp4, tuple.Comp5, tuple.Comp6, tuple.Comp7, tuple.Comp8);
}
public static implicit operator Entity<T1?, T2?, T3?, T4?, T5?, T6?, T7?, T8?>(EntityUid owner)
{
return new Entity<T1?, T2?, T3?, T4?, T5?, T6?, T7?, T8?>(owner, default, default, default, default, default, default, default, default);
}
public static implicit operator EntityUid(Entity<T1, T2, T3, T4, T5, T6, T7, T8> ent)
{
return ent.Owner;
}
public static implicit operator T1(Entity<T1, T2, T3, T4, T5, T6, T7, T8> ent)
{
return ent.Comp1;
}
public static implicit operator T2(Entity<T1, T2, T3, T4, T5, T6, T7, T8> ent)
{
return ent.Comp2;
}
public static implicit operator T3(Entity<T1, T2, T3, T4, T5, T6, T7, T8> ent)
{
return ent.Comp3;
}
public static implicit operator T4(Entity<T1, T2, T3, T4, T5, T6, T7, T8> ent)
{
return ent.Comp4;
}
public static implicit operator T5(Entity<T1, T2, T3, T4, T5, T6, T7, T8> ent)
{
return ent.Comp5;
}
public static implicit operator T6(Entity<T1, T2, T3, T4, T5, T6, T7, T8> ent)
{
return ent.Comp6;
}
public static implicit operator T7(Entity<T1, T2, T3, T4, T5, T6, T7, T8> ent)
{
return ent.Comp7;
}
public static implicit operator T8(Entity<T1, T2, T3, T4, T5, T6, T7, T8> ent)
{
return ent.Comp8;
}
public readonly void Deconstruct(out EntityUid owner, out T1 comp1, out T2 comp2, out T3 comp3, out T4 comp4, out T5 comp5, out T6 comp6, out T7 comp7, out T8 comp8)
{
owner = Owner;
comp1 = Comp1;
comp2 = Comp2;
comp3 = Comp3;
comp4 = Comp4;
comp5 = Comp5;
comp6 = Comp6;
comp7 = Comp7;
comp8 = Comp8;
}
}

View File

@@ -20,13 +20,9 @@ namespace Robust.Shared.GameObjects
/// <param name="source"></param>
/// <param name="subscriber">Subscriber that owns the handler.</param>
/// <param name="eventHandler">Delegate that handles the event.</param>
/// <seealso cref="SubscribeEvent{T}(EventSource, IEntityEventSubscriber, EntityEventRefHandler{T})"/>
// [Obsolete("Subscribe to the event by ref instead (EntityEventRefHandler)")]
void SubscribeEvent<T>(EventSource source, IEntityEventSubscriber subscriber,
EntityEventHandler<T> eventHandler) where T : notnull;
/// <seealso cref="SubscribeEvent{T}(EventSource, IEntityEventSubscriber, EntityEventRefHandler{T})"/>
// [Obsolete("Subscribe to the event by ref instead (EntityEventRefHandler)")]
void SubscribeEvent<T>(
EventSource source,
IEntityEventSubscriber subscriber,
@@ -137,7 +133,7 @@ namespace Robust.Shared.GameObjects
var type = args.GetType();
ref var unitRef = ref ExtractUnitRef(ref args, type);
ProcessSingleEvent(source, ref unitRef, type);
ProcessSingleEvent(source, ref unitRef, type, false);
}
}
@@ -264,7 +260,7 @@ namespace Robust.Shared.GameObjects
var eventType = toRaise.GetType();
ref var unitRef = ref ExtractUnitRef(ref toRaise, eventType);
ProcessSingleEvent(source, ref unitRef, eventType);
ProcessSingleEvent(source, ref unitRef, eventType, false);
}
public void RaiseEvent<T>(EventSource source, T toRaise) where T : notnull
@@ -272,7 +268,7 @@ namespace Robust.Shared.GameObjects
if (source == EventSource.None)
throw new ArgumentOutOfRangeException(nameof(source));
ProcessSingleEvent(source, ref Unsafe.As<T, Unit>(ref toRaise), typeof(T));
ProcessSingleEvent(source, ref Unsafe.As<T, Unit>(ref toRaise), typeof(T), false);
}
public void RaiseEvent<T>(EventSource source, ref T toRaise) where T : notnull
@@ -280,7 +276,7 @@ namespace Robust.Shared.GameObjects
if (source == EventSource.None)
throw new ArgumentOutOfRangeException(nameof(source));
ProcessSingleEvent(source, ref Unsafe.As<T, Unit>(ref toRaise), typeof(T));
ProcessSingleEvent(source, ref Unsafe.As<T, Unit>(ref toRaise), typeof(T), true);
}
/// <inheritdoc />
@@ -305,7 +301,7 @@ namespace Robust.Shared.GameObjects
inverse.Remove(eventType);
}
private void ProcessSingleEvent(EventSource source, ref Unit unitRef, Type eventType)
private void ProcessSingleEvent(EventSource source, ref Unit unitRef, Type eventType, bool byRef)
{
if (!_eventData.TryGetValue(eventType, out var subs))
return;
@@ -318,16 +314,20 @@ namespace Robust.Shared.GameObjects
// This means ordered broadcast events have no overhead over non-ordered ones.
}
ProcessSingleEventCore(source, ref unitRef, subs);
ProcessSingleEventCore(source, ref unitRef, subs, byRef);
}
private static void ProcessSingleEventCore(
EventSource source,
ref Unit unitRef,
EventData subs)
EventData subs,
bool byRef)
{
foreach (var handler in subs.BroadcastRegistrations)
{
if (handler.ReferenceEvent != byRef)
ThrowByRefMisMatch();
if ((handler.Mask & source) != 0)
handler.Handler(ref unitRef);
}

View File

@@ -39,6 +39,10 @@ internal sealed partial class EntityEventBus : IEventBus
public bool IgnoreUnregisteredComponents;
[MethodImpl(MethodImplOptions.NoInlining)]
private static void ThrowByRefMisMatch() =>
throw new InvalidOperationException("Mismatching by-ref ness on event!");
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static ref Unit ExtractUnitRef(ref object obj, Type objType)
{

View File

@@ -46,12 +46,6 @@ namespace Robust.Shared.GameObjects
where TComp : IComponent
where TEvent : notnull;
void SubscribeLocalEvent<TComp, TEvent>(
EntityEventRefHandler<TComp, TEvent> handler,
Type orderType, Type[]? before = null, Type[]? after = null)
where TComp : IComponent
where TEvent : notnull;
#endregion
void UnsubscribeLocalEvent<TComp, TEvent>()
@@ -143,7 +137,8 @@ namespace Robust.Shared.GameObjects
component.Owner,
component,
CompIdx.Index(component.GetType()),
ref unitRef);
ref unitRef,
false);
}
void IDirectedEventBus.RaiseComponentEvent<TEvent>(IComponent component, CompIdx type, TEvent args)
@@ -154,7 +149,8 @@ namespace Robust.Shared.GameObjects
component.Owner,
component,
type,
ref unitRef);
ref unitRef,
false);
}
/// <inheritdoc />
@@ -166,7 +162,8 @@ namespace Robust.Shared.GameObjects
component.Owner,
component,
CompIdx.Index(component.GetType()),
ref unitRef);
ref unitRef,
true);
}
public void OnlyCallOnRobustUnitTestISwearToGodPleaseSomebodyKillThisNightmare()
@@ -181,7 +178,7 @@ namespace Robust.Shared.GameObjects
var type = typeof(TEvent);
ref var unitRef = ref Unsafe.As<TEvent, Unit>(ref args);
RaiseLocalEventCore(uid, ref unitRef, type, broadcast);
RaiseLocalEventCore(uid, ref unitRef, type, broadcast, false);
}
/// <inheritdoc />
@@ -190,7 +187,7 @@ namespace Robust.Shared.GameObjects
var type = args.GetType();
ref var unitRef = ref Unsafe.As<object, Unit>(ref args);
RaiseLocalEventCore(uid, ref unitRef, type, broadcast);
RaiseLocalEventCore(uid, ref unitRef, type, broadcast, false);
}
public void RaiseLocalEvent<TEvent>(EntityUid uid, ref TEvent args, bool broadcast = false)
@@ -199,7 +196,7 @@ namespace Robust.Shared.GameObjects
var type = typeof(TEvent);
ref var unitRef = ref Unsafe.As<TEvent, Unit>(ref args);
RaiseLocalEventCore(uid, ref unitRef, type, broadcast);
RaiseLocalEventCore(uid, ref unitRef, type, broadcast, true);
}
public void RaiseLocalEvent(EntityUid uid, ref object args, bool broadcast = false)
@@ -207,25 +204,25 @@ namespace Robust.Shared.GameObjects
var type = args.GetType();
ref var unitRef = ref Unsafe.As<object, Unit>(ref args);
RaiseLocalEventCore(uid, ref unitRef, type, broadcast);
RaiseLocalEventCore(uid, ref unitRef, type, broadcast, true);
}
private void RaiseLocalEventCore(EntityUid uid, ref Unit unitRef, Type type, bool broadcast)
private void RaiseLocalEventCore(EntityUid uid, ref Unit unitRef, Type type, bool broadcast, bool byRef)
{
if (!_eventData.TryGetValue(type, out var subs))
return;
if (subs.IsOrdered)
{
RaiseLocalOrdered(uid, type, subs, ref unitRef, broadcast);
RaiseLocalOrdered(uid, type, subs, ref unitRef, broadcast, byRef);
return;
}
EntDispatch(uid, type, ref unitRef);
EntDispatch(uid, type, ref unitRef, byRef);
// we also broadcast it so the call site does not have to.
if (broadcast)
ProcessSingleEventCore(EventSource.Local, ref unitRef, subs);
ProcessSingleEventCore(EventSource.Local, ref unitRef, subs, byRef);
}
/// <inheritdoc />
@@ -241,7 +238,8 @@ namespace Robust.Shared.GameObjects
typeof(TComp),
typeof(TEvent),
EventHandler,
null);
null,
false);
}
public void SubscribeLocalEvent<TComp, TEvent>(
@@ -262,7 +260,8 @@ namespace Robust.Shared.GameObjects
typeof(TComp),
typeof(TEvent),
EventHandler,
orderData);
orderData,
false);
RegisterCommon(typeof(TEvent), orderData, out _);
}
@@ -278,7 +277,8 @@ namespace Robust.Shared.GameObjects
typeof(TComp),
typeof(TEvent),
EventHandler,
null);
null,
true);
}
public void SubscribeLocalEvent<TComp, TEvent>(ComponentEventRefHandler<TComp, TEvent> handler, Type orderType,
@@ -295,26 +295,8 @@ namespace Robust.Shared.GameObjects
typeof(TComp),
typeof(TEvent),
EventHandler,
orderData);
RegisterCommon(typeof(TEvent), orderData, out _);
}
public void SubscribeLocalEvent<TComp, TEvent>(EntityEventRefHandler<TComp, TEvent> handler, Type orderType,
Type[]? before = null,
Type[]? after = null) where TComp : IComponent where TEvent : notnull
{
void EventHandler(EntityUid uid, IComponent comp, ref TEvent args)
=> handler(new Entity<TComp>(uid, (TComp) comp), ref args);
var orderData = new OrderingData(orderType, before ?? Array.Empty<Type>(), after ?? Array.Empty<Type>());
EntSubscribe<TEvent>(
CompIdx.Index<TComp>(),
typeof(TComp),
typeof(TEvent),
EventHandler,
orderData);
orderData,
true);
RegisterCommon(typeof(TEvent), orderData, out _);
}
@@ -363,6 +345,12 @@ namespace Robust.Shared.GameObjects
if (_subscriptionLock)
throw new InvalidOperationException("Subscription locked.");
var referenceEvent = eventType.HasCustomAttribute<ByRefEventAttribute>();
if (referenceEvent != registration.ReferenceEvent)
throw new InvalidOperationException(
$"Attempted to subscribe by-ref and by-value to the same directed event! comp={compTypeObj.Name}, event={eventType.Name} eventIsByRef={referenceEvent} subscriptionIsByRef={registration.ReferenceEvent}");
if (compType.Value >= _entSubscriptions.Length || _entSubscriptions[compType.Value] is not { } compSubs)
{
if (IgnoreUnregisteredComponents)
@@ -389,7 +377,7 @@ namespace Robust.Shared.GameObjects
Type compTypeObj,
Type eventType,
DirectedEventHandler<TEvent> handler,
OrderingData? order)
OrderingData? order, bool byReference)
where TEvent : notnull
{
EntAddSubscription(compType, compTypeObj, eventType, new DirectedRegistration(handler, order,
@@ -397,7 +385,7 @@ namespace Robust.Shared.GameObjects
{
ref var tev = ref Unsafe.As<Unit, TEvent>(ref ev);
handler(uid, comp, ref tev);
}));
}, byReference));
}
private void EntUnsubscribe(CompIdx compType, Type eventType)
@@ -537,7 +525,7 @@ namespace Robust.Shared.GameObjects
}
}
private void EntDispatch(EntityUid euid, Type eventType, ref Unit args)
private void EntDispatch(EntityUid euid, Type eventType, ref Unit args, bool dispatchByReference)
{
if (!EntTryGetSubscriptions(eventType, euid, out var enumerator))
return;
@@ -547,6 +535,9 @@ namespace Robust.Shared.GameObjects
if (component.Deleted)
continue;
if (reg.ReferenceEvent != dispatchByReference)
ThrowByRefMisMatch();
reg.Handler(euid, component, ref args);
}
}
@@ -554,18 +545,22 @@ namespace Robust.Shared.GameObjects
private void EntCollectOrdered(
EntityUid euid,
Type eventType,
ref ValueList<OrderedEventDispatch> found)
ref ValueList<OrderedEventDispatch> found,
bool byRef)
{
if (!EntTryGetSubscriptions(eventType, euid, out var enumerator))
return;
while (enumerator.MoveNext(out var component, out var reg))
{
if (reg.ReferenceEvent != byRef)
ThrowByRefMisMatch();
found.Add(new OrderedEventDispatch((ref Unit ev) =>
{
if (!component.Deleted)
reg.Handler(euid, component, ref ev);
}, reg.Order));
}, reg.Order));
}
}
@@ -573,7 +568,8 @@ namespace Robust.Shared.GameObjects
EntityUid euid,
IComponent component,
CompIdx baseType,
ref Unit args)
ref Unit args,
bool dispatchByReference)
where TEvent : notnull
{
var compSubs = _entSubscriptions[baseType.Value]!;
@@ -581,6 +577,9 @@ namespace Robust.Shared.GameObjects
if (!compSubs.TryGetValue(typeof(TEvent), out var reg))
return;
if (reg.ReferenceEvent != dispatchByReference)
ThrowByRefMisMatch();
reg.Handler(euid, component, ref args);
}
@@ -691,14 +690,17 @@ namespace Robust.Shared.GameObjects
{
public readonly Delegate Original;
public readonly DirectedEventHandler Handler;
public readonly bool ReferenceEvent;
public DirectedRegistration(
Delegate original,
OrderingData? ordering,
DirectedEventHandler handler) : base(ordering)
DirectedEventHandler handler,
bool referenceEvent) : base(ordering)
{
Original = original;
Handler = handler;
ReferenceEvent = referenceEvent;
}
public void SetOrder(int order)
@@ -734,8 +736,6 @@ namespace Robust.Shared.GameObjects
}
}
/// <seealso cref="ComponentEventRefHandler{TComp, TEvent}"/>
// [Obsolete("Use ComponentEventRefHandler instead")]
public delegate void ComponentEventHandler<in TComp, in TEvent>(EntityUid uid, TComp component, TEvent args)
where TComp : IComponent
where TEvent : notnull;
@@ -743,8 +743,4 @@ namespace Robust.Shared.GameObjects
public delegate void ComponentEventRefHandler<in TComp, TEvent>(EntityUid uid, TComp component, ref TEvent args)
where TComp : IComponent
where TEvent : notnull;
public delegate void EntityEventRefHandler<TComp, TEvent>(Entity<TComp> ent, ref TEvent args)
where TComp : IComponent
where TEvent : notnull;
}

View File

@@ -11,10 +11,14 @@ namespace Robust.Shared.GameObjects
private static void CollectBroadcastOrdered(
EventSource source,
EventData sub,
ref ValueList<OrderedEventDispatch> found)
ref ValueList<OrderedEventDispatch> found,
bool byRef)
{
foreach (var handler in sub.BroadcastRegistrations)
{
if (handler.ReferenceEvent != byRef)
ThrowByRefMisMatch();
if ((handler.Mask & source) != 0)
found.Add(new OrderedEventDispatch(handler.Handler, handler.Order));
}
@@ -25,7 +29,8 @@ namespace Robust.Shared.GameObjects
Type eventType,
EventData subs,
ref Unit unitRef,
bool broadcast)
bool broadcast,
bool byRef)
{
if (!subs.OrderingUpToDate)
UpdateOrderSeq(eventType, subs);
@@ -33,9 +38,9 @@ namespace Robust.Shared.GameObjects
var found = new ValueList<OrderedEventDispatch>();
if (broadcast)
CollectBroadcastOrdered(EventSource.Local, subs, ref found);
CollectBroadcastOrdered(EventSource.Local, subs, ref found, byRef);
EntCollectOrdered(uid, eventType, ref found);
EntCollectOrdered(uid, eventType, ref found, byRef);
DispatchOrderedEvents(ref unitRef, ref found);
}

View File

@@ -36,15 +36,15 @@ namespace Robust.Shared.GameObjects
private static readonly ComponentState DefaultComponentState = new();
private readonly Dictionary<Type, Dictionary<EntityUid, IComponent>> _entTraitDict
private readonly Dictionary<Type, Dictionary<EntityUid, Component>> _entTraitDict
= new();
private Dictionary<EntityUid, IComponent>[] _entTraitArray
= Array.Empty<Dictionary<EntityUid, IComponent>>();
private Dictionary<EntityUid, Component>[] _entTraitArray
= Array.Empty<Dictionary<EntityUid, Component>>();
private readonly HashSet<IComponent> _deleteSet = new(TypeCapacity);
private readonly HashSet<Component> _deleteSet = new(TypeCapacity);
private UniqueIndexHkm<EntityUid, IComponent> _entCompIndex =
private UniqueIndexHkm<EntityUid, Component> _entCompIndex =
new(ComponentCollectionCapacity);
/// <inheritdoc />
@@ -78,7 +78,7 @@ namespace Robust.Shared.GameObjects
private void AddComponentRefType(CompIdx type)
{
var dict = new Dictionary<EntityUid, IComponent>();
var dict = new Dictionary<EntityUid, Component>();
_entTraitDict.Add(_componentFactory.IdxToType(type), dict);
CompIdx.AssignArray(ref _entTraitArray, type, dict);
}
@@ -91,7 +91,7 @@ namespace Robust.Shared.GameObjects
#region Component Management
/// <inheritdoc />
public int Count<T>() where T : IComponent
public int Count<T>() where T : Component
{
var dict = _entTraitDict[typeof(T)];
return dict.Count;
@@ -106,13 +106,15 @@ namespace Robust.Shared.GameObjects
public void InitializeComponents(EntityUid uid, MetaDataComponent? metadata = null)
{
DebugTools.AssertOwner(uid, metadata);
#pragma warning disable CS0618 // Type or member is obsolete
DebugTools.Assert(metadata == null || metadata.Owner == uid);
#pragma warning restore CS0618 // Type or member is obsolete
metadata ??= GetComponent<MetaDataComponent>(uid);
DebugTools.Assert(metadata.EntityLifeStage == EntityLifeStage.PreInit);
metadata.EntityLifeStage = EntityLifeStage.Initializing;
// Initialize() can modify the collection of components. Copy them.
FixedArray32<IComponent?> compsFixed = default;
FixedArray32<Component?> compsFixed = default;
var comps = compsFixed.AsSpan;
CopyComponentsInto(ref comps, uid);
@@ -143,7 +145,7 @@ namespace Robust.Shared.GameObjects
{
// Startup() can modify _components
// This code can only handle additions to the list. Is there a better way? Probably not.
FixedArray32<IComponent?> compsFixed = default;
FixedArray32<Component?> compsFixed = default;
var comps = compsFixed.AsSpan;
CopyComponentsInto(ref comps, uid);
@@ -170,22 +172,28 @@ namespace Robust.Shared.GameObjects
}
}
public IComponent AddComponent(EntityUid uid, ushort netId, MetaDataComponent? meta = null)
public Component AddComponent(EntityUid uid, ushort netId, MetaDataComponent? meta = null)
{
var newComponent = _componentFactory.GetComponent(netId);
var newComponent = (Component)_componentFactory.GetComponent(netId);
#pragma warning disable CS0618 // Type or member is obsolete
newComponent.Owner = uid;
#pragma warning restore CS0618 // Type or member is obsolete
AddComponent(uid, newComponent, metadata: meta);
return newComponent;
}
public T AddComponent<T>(EntityUid uid) where T : IComponent, new()
public T AddComponent<T>(EntityUid uid) where T : Component, new()
{
var newComponent = _componentFactory.GetComponent<T>();
#pragma warning disable CS0618 // Type or member is obsolete
newComponent.Owner = uid;
#pragma warning restore CS0618 // Type or member is obsolete
AddComponent(uid, newComponent);
return newComponent;
}
public readonly struct CompInitializeHandle<T> : IDisposable
where T : IComponent
where T : Component
{
private readonly IEntityManager _entMan;
private readonly EntityUid _owner;
@@ -222,7 +230,7 @@ namespace Robust.Shared.GameObjects
/// <inheritdoc />
[Obsolete]
public CompInitializeHandle<T> AddComponentUninitialized<T>(EntityUid uid) where T : IComponent, new()
public CompInitializeHandle<T> AddComponentUninitialized<T>(EntityUid uid) where T : Component, new()
{
var reg = _componentFactory.GetRegistration<T>();
var newComponent = (T)_componentFactory.GetComponent(reg);
@@ -239,7 +247,7 @@ namespace Robust.Shared.GameObjects
}
/// <inheritdoc />
public void AddComponent<T>(EntityUid uid, T component, bool overwrite = false, MetaDataComponent? metadata = null) where T : IComponent
public void AddComponent<T>(EntityUid uid, T component, bool overwrite = false, MetaDataComponent? metadata = null) where T : Component
{
if (!uid.IsValid() || !EntityExists(uid))
throw new ArgumentException($"Entity {uid} is not valid.", nameof(uid));
@@ -260,14 +268,14 @@ namespace Robust.Shared.GameObjects
AddComponentInternal(uid, component, overwrite, false, metadata);
}
private void AddComponentInternal<T>(EntityUid uid, T component, bool overwrite, bool skipInit, MetaDataComponent? metadata = null) where T : IComponent
private void AddComponentInternal<T>(EntityUid uid, T component, bool overwrite, bool skipInit, MetaDataComponent? metadata = null) where T : Component
{
// get interface aliases for mapping
var reg = _componentFactory.GetRegistration(component);
AddComponentInternal(uid, component, reg, overwrite, skipInit, metadata);
}
private void AddComponentInternal<T>(EntityUid uid, T component, ComponentRegistration reg, bool overwrite, bool skipInit, MetaDataComponent? metadata = null) where T : IComponent
private void AddComponentInternal<T>(EntityUid uid, T component, ComponentRegistration reg, bool overwrite, bool skipInit, MetaDataComponent? metadata = null) where T : Component
{
// We can't use typeof(T) here in case T is just Component
DebugTools.Assert(component is MetaDataComponent ||
@@ -357,7 +365,7 @@ namespace Robust.Shared.GameObjects
if (!TryGetComponent(uid, type, out var comp))
return false;
RemoveComponentImmediate(comp, uid, false, meta);
RemoveComponentImmediate((Component)comp, uid, false, meta);
return true;
}
@@ -371,13 +379,20 @@ namespace Robust.Shared.GameObjects
if (!TryGetComponent(uid, netId, out var comp, meta))
return false;
RemoveComponentImmediate(comp, uid, false, meta);
RemoveComponentImmediate((Component)comp, uid, false, meta);
return true;
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void RemoveComponent(EntityUid uid, IComponent component, MetaDataComponent? meta = null)
{
RemoveComponent(uid, (Component)component, meta);
}
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void RemoveComponent(EntityUid uid, Component component, MetaDataComponent? meta = null)
{
RemoveComponentImmediate(component, uid, false, meta);
}
@@ -395,7 +410,7 @@ namespace Robust.Shared.GameObjects
if (!TryGetComponent(uid, type, out var comp))
return false;
RemoveComponentDeferred(comp, uid, false);
RemoveComponentDeferred((Component)comp, uid, false);
return true;
}
@@ -409,14 +424,14 @@ namespace Robust.Shared.GameObjects
if (!TryGetComponent(uid, netId, out var comp, meta))
return false;
RemoveComponentDeferred(comp, uid, false);
RemoveComponentDeferred((Component)comp, uid, false);
return true;
}
/// <inheritdoc />
public void RemoveComponentDeferred(EntityUid owner, IComponent component)
{
RemoveComponentDeferred(component, owner, false);
RemoveComponentDeferred((Component)component, owner, false);
}
/// <inheritdoc />
@@ -425,7 +440,7 @@ namespace Robust.Shared.GameObjects
RemoveComponentDeferred(component, owner, false);
}
private static IEnumerable<IComponent> InSafeOrder(IEnumerable<IComponent> comps, bool forCreation = false)
private static IEnumerable<Component> InSafeOrder(IEnumerable<Component> comps, bool forCreation = false)
{
static int Sequence(IComponent x)
=> x switch
@@ -474,13 +489,11 @@ namespace Robust.Shared.GameObjects
_entCompIndex.Remove(uid);
}
private void RemoveComponentDeferred(IComponent component, EntityUid uid, bool terminating)
private void RemoveComponentDeferred(Component component, EntityUid uid, bool terminating)
{
if (component == null) throw new ArgumentNullException(nameof(component));
#pragma warning disable CS0618 // Type or member is obsolete
if (component.Owner != uid)
#pragma warning restore CS0618 // Type or member is obsolete
throw new InvalidOperationException("Component is not owned by entity.");
if (component.Deleted) return;
@@ -514,7 +527,7 @@ namespace Robust.Shared.GameObjects
#endif
}
private void RemoveComponentImmediate(IComponent component, EntityUid uid, bool terminating,
private void RemoveComponentImmediate(Component component, EntityUid uid, bool terminating,
MetaDataComponent? meta)
{
if (component.Deleted)
@@ -589,7 +602,7 @@ namespace Robust.Shared.GameObjects
_deleteSet.Clear();
}
private void DeleteComponent(EntityUid entityUid, IComponent component, bool terminating, MetaDataComponent? metadata = null)
private void DeleteComponent(EntityUid entityUid, Component component, bool terminating, MetaDataComponent? metadata = null)
{
if (!MetaQuery.ResolveInternal(entityUid, ref metadata))
return;
@@ -630,7 +643,7 @@ namespace Robust.Shared.GameObjects
{
var dict = _entTraitArray[CompIdx.ArrayIndex<T>()];
DebugTools.Assert(dict != null, $"Unknown component: {typeof(T).Name}");
return dict.TryGetValue(uid, out var comp) && !comp.Deleted;
return dict!.TryGetValue(uid, out var comp) && !comp.Deleted;
}
/// <inheritdoc />
@@ -686,14 +699,15 @@ namespace Robust.Shared.GameObjects
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public T EnsureComponent<T>(EntityUid uid) where T : IComponent, new()
public T EnsureComponent<T>(EntityUid uid) where T : Component, new()
{
if (TryGetComponent<T>(uid, out var component))
{
// Check for deferred component removal.
if (component.LifeStage <= ComponentLifeStage.Running)
return component;
RemoveComponent(uid, component);
else
RemoveComponent(uid, component);
}
return AddComponent<T>(uid);
@@ -701,7 +715,7 @@ namespace Robust.Shared.GameObjects
/// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool EnsureComponent<T>(EntityUid entity, out T component) where T : IComponent, new()
public bool EnsureComponent<T>(EntityUid entity, out T component) where T : Component, new()
{
if (TryGetComponent<T>(entity, out var comp))
{
@@ -711,8 +725,8 @@ namespace Robust.Shared.GameObjects
component = comp;
return true;
}
RemoveComponent(entity, comp);
else
RemoveComponent(entity, comp);
}
component = AddComponent<T>(entity);
@@ -725,11 +739,11 @@ namespace Robust.Shared.GameObjects
{
var dict = _entTraitArray[CompIdx.ArrayIndex<T>()];
DebugTools.Assert(dict != null, $"Unknown component: {typeof(T).Name}");
if (dict.TryGetValue(uid, out var comp))
if (dict!.TryGetValue(uid, out var comp))
{
if (!comp.Deleted)
if (!comp!.Deleted)
{
return (T)comp;
return (T)(IComponent) comp;
}
}
@@ -788,11 +802,11 @@ namespace Robust.Shared.GameObjects
{
var dict = _entTraitArray[CompIdx.ArrayIndex<T>()];
DebugTools.Assert(dict != null, $"Unknown component: {typeof(T).Name}");
if (dict.TryGetValue(uid, out var comp))
if (dict!.TryGetValue(uid, out var comp))
{
if (!comp.Deleted)
{
component = (T)comp;
component = (T)(IComponent)comp;
return true;
}
}
@@ -908,25 +922,25 @@ namespace Robust.Shared.GameObjects
return TryGetComponent(uid.Value, netId, out component, meta);
}
public EntityQuery<TComp1> GetEntityQuery<TComp1>() where TComp1 : IComponent
public EntityQuery<TComp1> GetEntityQuery<TComp1>() where TComp1 : Component
{
var comps = _entTraitArray[CompIdx.ArrayIndex<TComp1>()];
DebugTools.Assert(comps != null, $"Unknown component: {typeof(TComp1).Name}");
return new EntityQuery<TComp1>(comps, _resolveSawmill);
return new EntityQuery<TComp1>(comps!, _resolveSawmill);
}
public EntityQuery<IComponent> GetEntityQuery(Type type)
public EntityQuery<Component> GetEntityQuery(Type type)
{
var comps = _entTraitArray[CompIdx.ArrayIndex(type)];
DebugTools.Assert(comps != null, $"Unknown component: {type.Name}");
return new EntityQuery<IComponent>(comps, _resolveSawmill);
return new EntityQuery<Component>(comps!, _resolveSawmill);
}
/// <inheritdoc />
public IEnumerable<IComponent> GetComponents(EntityUid uid)
{
// ReSharper disable once LoopCanBeConvertedToQuery
foreach (var comp in _entCompIndex[uid].ToArray())
foreach (Component comp in _entCompIndex[uid].ToArray())
{
if (comp.Deleted) continue;
@@ -943,14 +957,14 @@ namespace Robust.Shared.GameObjects
/// <summary>
/// Copy the components for an entity into the given span,
/// or re-allocate the span as an array if there's not enough space.º
/// or re-allocate the span as an array if there's not enough space.
/// </summary>
private void CopyComponentsInto(ref Span<IComponent?> comps, EntityUid uid)
private void CopyComponentsInto(ref Span<Component?> comps, EntityUid uid)
{
var set = _entCompIndex[uid];
if (set.Count > comps.Length)
{
comps = new IComponent[set.Count];
comps = new Component[set.Count];
}
var i = 0;
@@ -989,7 +1003,7 @@ namespace Robust.Shared.GameObjects
#region Join Functions
public (EntityUid Uid, T Component)[] AllComponents<T>() where T : IComponent
public (EntityUid Uid, T Component)[] AllComponents<T>() where T : Component
{
var query = AllEntityQueryEnumerator<T>();
var comps = new (EntityUid Uid, T Component)[Count<T>()];
@@ -1004,7 +1018,7 @@ namespace Robust.Shared.GameObjects
return comps;
}
public List<(EntityUid Uid, T Component)> AllComponentsList<T>() where T : IComponent
public List<(EntityUid Uid, T Component)> AllComponentsList<T>() where T : Component
{
var query = AllEntityQueryEnumerator<T>();
var comps = new List<(EntityUid Uid, T Component)>(Count<T>());
@@ -1018,15 +1032,15 @@ namespace Robust.Shared.GameObjects
}
public AllEntityQueryEnumerator<TComp1> AllEntityQueryEnumerator<TComp1>()
where TComp1 : IComponent
where TComp1 : Component
{
var trait1 = _entTraitArray[CompIdx.ArrayIndex<TComp1>()];
return new AllEntityQueryEnumerator<TComp1>(trait1);
}
public AllEntityQueryEnumerator<TComp1, TComp2> AllEntityQueryEnumerator<TComp1, TComp2>()
where TComp1 : IComponent
where TComp2 : IComponent
where TComp1 : Component
where TComp2 : Component
{
var trait1 = _entTraitArray[CompIdx.ArrayIndex<TComp1>()];
var trait2 = _entTraitArray[CompIdx.ArrayIndex<TComp2>()];
@@ -1034,9 +1048,9 @@ namespace Robust.Shared.GameObjects
}
public AllEntityQueryEnumerator<TComp1, TComp2, TComp3> AllEntityQueryEnumerator<TComp1, TComp2, TComp3>()
where TComp1 : IComponent
where TComp2 : IComponent
where TComp3 : IComponent
where TComp1 : Component
where TComp2 : Component
where TComp3 : Component
{
var trait1 = _entTraitArray[CompIdx.ArrayIndex<TComp1>()];
var trait2 = _entTraitArray[CompIdx.ArrayIndex<TComp2>()];
@@ -1045,10 +1059,10 @@ namespace Robust.Shared.GameObjects
}
public AllEntityQueryEnumerator<TComp1, TComp2, TComp3, TComp4> AllEntityQueryEnumerator<TComp1, TComp2, TComp3, TComp4>()
where TComp1 : IComponent
where TComp2 : IComponent
where TComp3 : IComponent
where TComp4 : IComponent
where TComp1 : Component
where TComp2 : Component
where TComp3 : Component
where TComp4 : Component
{
var trait1 = _entTraitArray[CompIdx.ArrayIndex<TComp1>()];
var trait2 = _entTraitArray[CompIdx.ArrayIndex<TComp2>()];
@@ -1058,15 +1072,15 @@ namespace Robust.Shared.GameObjects
}
public EntityQueryEnumerator<TComp1> EntityQueryEnumerator<TComp1>()
where TComp1 : IComponent
where TComp1 : Component
{
var trait1 = _entTraitArray[CompIdx.ArrayIndex<TComp1>()];
return new EntityQueryEnumerator<TComp1>(trait1, MetaQuery);
}
public EntityQueryEnumerator<TComp1, TComp2> EntityQueryEnumerator<TComp1, TComp2>()
where TComp1 : IComponent
where TComp2 : IComponent
where TComp1 : Component
where TComp2 : Component
{
var trait1 = _entTraitArray[CompIdx.ArrayIndex<TComp1>()];
var trait2 = _entTraitArray[CompIdx.ArrayIndex<TComp2>()];
@@ -1074,9 +1088,9 @@ namespace Robust.Shared.GameObjects
}
public EntityQueryEnumerator<TComp1, TComp2, TComp3> EntityQueryEnumerator<TComp1, TComp2, TComp3>()
where TComp1 : IComponent
where TComp2 : IComponent
where TComp3 : IComponent
where TComp1 : Component
where TComp2 : Component
where TComp3 : Component
{
var trait1 = _entTraitArray[CompIdx.ArrayIndex<TComp1>()];
var trait2 = _entTraitArray[CompIdx.ArrayIndex<TComp2>()];
@@ -1085,10 +1099,10 @@ namespace Robust.Shared.GameObjects
}
public EntityQueryEnumerator<TComp1, TComp2, TComp3, TComp4> EntityQueryEnumerator<TComp1, TComp2, TComp3, TComp4>()
where TComp1 : IComponent
where TComp2 : IComponent
where TComp3 : IComponent
where TComp4 : IComponent
where TComp1 : Component
where TComp2 : Component
where TComp3 : Component
where TComp4 : Component
{
var trait1 = _entTraitArray[CompIdx.ArrayIndex<TComp1>()];
var trait2 = _entTraitArray[CompIdx.ArrayIndex<TComp2>()];
@@ -1106,22 +1120,22 @@ namespace Robust.Shared.GameObjects
if (includePaused)
{
foreach (var t1Comp in comps.Values)
foreach (var t1Comp in comps!.Values)
{
if (t1Comp.Deleted) continue;
yield return (T)t1Comp;
yield return (T)(object)t1Comp;
}
}
else
{
foreach (var (uid, t1Comp) in comps)
foreach (var t1Comp in comps.Values)
{
if (t1Comp.Deleted || !MetaQuery.TryGetComponentInternal(uid, out var metaComp)) continue;
if (t1Comp.Deleted || !MetaQuery.TryGetComponentInternal(t1Comp.Owner, out var metaComp)) continue;
if (metaComp.EntityPaused) continue;
yield return (T)t1Comp;
yield return (T)(object)t1Comp;
}
}
}
@@ -1144,8 +1158,8 @@ namespace Robust.Shared.GameObjects
continue;
yield return (
(TComp1) t1Comp,
(TComp2) t2Comp);
(TComp1)(object)t1Comp,
(TComp2)(object)t2Comp);
}
}
else
@@ -1158,15 +1172,15 @@ namespace Robust.Shared.GameObjects
if (!trait2.TryGetValue(uid, out var t2Comp) || t2Comp.Deleted)
continue;
if (t1Comp.Deleted || !metaComps.TryGetValue(uid, out var metaComp)) continue;
if (t1Comp.Deleted || !metaComps.TryGetValue(t1Comp.Owner, out var metaComp)) continue;
var meta = (MetaDataComponent)metaComp;
if (meta.EntityPaused) continue;
yield return (
(TComp1) t1Comp,
(TComp2) t2Comp);
(TComp1)(object)t1Comp,
(TComp2)(object)t2Comp);
}
}
}
@@ -1192,9 +1206,9 @@ namespace Robust.Shared.GameObjects
continue;
yield return (
(TComp1) t1Comp,
(TComp2) t2Comp,
(TComp3) t3Comp);
(TComp1)(object)t1Comp,
(TComp2)(object)t2Comp,
(TComp3)(object)t3Comp);
}
}
else
@@ -1210,16 +1224,16 @@ namespace Robust.Shared.GameObjects
if (!trait3.TryGetValue(uid, out var t3Comp) || t3Comp.Deleted)
continue;
if (t1Comp.Deleted || !metaComps.TryGetValue(uid, out var metaComp)) continue;
if (t1Comp.Deleted || !metaComps.TryGetValue(t1Comp.Owner, out var metaComp)) continue;
var meta = (MetaDataComponent)metaComp;
if (meta.EntityPaused) continue;
yield return (
(TComp1) t1Comp,
(TComp2) t2Comp,
(TComp3) t3Comp);
(TComp1)(object)t1Comp,
(TComp2)(object)t2Comp,
(TComp3)(object)t3Comp);
}
}
}
@@ -1251,10 +1265,10 @@ namespace Robust.Shared.GameObjects
continue;
yield return (
(TComp1) t1Comp,
(TComp2) t2Comp,
(TComp3) t3Comp,
(TComp4) t4Comp);
(TComp1)(object)t1Comp,
(TComp2)(object)t2Comp,
(TComp3)(object)t3Comp,
(TComp4)(object)t4Comp);
}
}
else
@@ -1273,17 +1287,17 @@ namespace Robust.Shared.GameObjects
if (!trait4.TryGetValue(uid, out var t4Comp) || t4Comp.Deleted)
continue;
if (t1Comp.Deleted || !metaComps.TryGetValue(uid, out var metaComp)) continue;
if (t1Comp.Deleted || !metaComps.TryGetValue(t1Comp.Owner, out var metaComp)) continue;
var meta = (MetaDataComponent)metaComp;
if (meta.EntityPaused) continue;
yield return (
(TComp1) t1Comp,
(TComp2) t2Comp,
(TComp3) t3Comp,
(TComp4) t4Comp);
(TComp1)(object)t1Comp,
(TComp2)(object)t2Comp,
(TComp3)(object)t3Comp,
(TComp4)(object)t4Comp);
}
}
}
@@ -1291,7 +1305,7 @@ namespace Robust.Shared.GameObjects
#endregion
/// <inheritdoc />
public IEnumerable<(EntityUid Uid, IComponent Component)> GetAllComponents(Type type, bool includePaused = false)
public IEnumerable<(EntityUid Uid, Component Component)> GetAllComponents(Type type, bool includePaused = false)
{
var comps = _entTraitDict[type];
@@ -1349,23 +1363,23 @@ namespace Robust.Shared.GameObjects
public readonly struct NetComponentEnumerable
{
private readonly Dictionary<ushort, IComponent> _dictionary;
private readonly Dictionary<ushort, Component> _dictionary;
public NetComponentEnumerable(Dictionary<ushort, IComponent> dictionary) => _dictionary = dictionary;
public NetComponentEnumerable(Dictionary<ushort, Component> dictionary) => _dictionary = dictionary;
public NetComponentEnumerator GetEnumerator() => new(_dictionary);
}
public struct NetComponentEnumerator
{
// DO NOT MAKE THIS READONLY
private Dictionary<ushort, IComponent>.Enumerator _dictEnum;
private Dictionary<ushort, Component>.Enumerator _dictEnum;
public NetComponentEnumerator(Dictionary<ushort, IComponent> dictionary) =>
public NetComponentEnumerator(Dictionary<ushort, Component> dictionary) =>
_dictEnum = dictionary.GetEnumerator();
public bool MoveNext() => _dictEnum.MoveNext();
public (ushort netId, IComponent component) Current
public (ushort netId, Component component) Current
{
get
{
@@ -1375,12 +1389,12 @@ namespace Robust.Shared.GameObjects
}
}
public readonly struct EntityQuery<TComp1> where TComp1 : IComponent
public readonly struct EntityQuery<TComp1> where TComp1 : Component
{
private readonly Dictionary<EntityUid, IComponent> _traitDict;
private readonly Dictionary<EntityUid, Component> _traitDict;
private readonly ISawmill _sawmill;
public EntityQuery(Dictionary<EntityUid, IComponent> traitDict, ISawmill sawmill)
public EntityQuery(Dictionary<EntityUid, Component> traitDict, ISawmill sawmill)
{
_traitDict = traitDict;
_sawmill = sawmill;
@@ -1443,7 +1457,9 @@ namespace Robust.Shared.GameObjects
{
if (component != null)
{
DebugTools.AssertOwner(uid, component);
#pragma warning disable CS0618 // Type or member is obsolete
DebugTools.Assert(uid == component.Owner, "Specified Entity is not the component's Owner!");
#pragma warning restore CS0618 // Type or member is obsolete
return true;
}
@@ -1466,7 +1482,7 @@ namespace Robust.Shared.GameObjects
if (TryGetComponent(uid, out var comp))
return comp;
return default;
return null;
}
#region Internal
@@ -1518,7 +1534,7 @@ namespace Robust.Shared.GameObjects
}
/// <summary>
/// Elides the component.Deleted check of <see cref="HasComponent(EntityUid)"/>
/// Elides the component.Deleted check of <see cref="HasComponent"/>
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Pure]
@@ -1536,7 +1552,9 @@ namespace Robust.Shared.GameObjects
{
if (component != null)
{
DebugTools.AssertOwner(uid, component);
#pragma warning disable CS0618 // Type or member is obsolete
DebugTools.Assert(uid == component.Owner, "Specified Entity is not the component's Owner!");
#pragma warning restore CS0618 // Type or member is obsolete
return true;
}
@@ -1561,7 +1579,7 @@ namespace Robust.Shared.GameObjects
if (TryGetComponent(uid, out var comp))
return comp;
return default;
return null;
}
#endregion
@@ -1573,13 +1591,13 @@ namespace Robust.Shared.GameObjects
/// Returns all matching unpaused components.
/// </summary>
public struct EntityQueryEnumerator<TComp1> : IDisposable
where TComp1 : IComponent
where TComp1 : Component
{
private Dictionary<EntityUid, IComponent>.Enumerator _traitDict;
private Dictionary<EntityUid, Component>.Enumerator _traitDict;
private readonly EntityQuery<MetaDataComponent> _metaQuery;
public EntityQueryEnumerator(
Dictionary<EntityUid, IComponent> traitDict,
Dictionary<EntityUid, Component> traitDict,
EntityQuery<MetaDataComponent> metaQuery)
{
_traitDict = traitDict.GetEnumerator();
@@ -1593,7 +1611,7 @@ namespace Robust.Shared.GameObjects
if (!_traitDict.MoveNext())
{
uid = default;
comp1 = default;
comp1 = null;
return false;
}
@@ -1631,16 +1649,16 @@ namespace Robust.Shared.GameObjects
/// Returns all matching unpaused components.
/// </summary>
public struct EntityQueryEnumerator<TComp1, TComp2> : IDisposable
where TComp1 : IComponent
where TComp2 : IComponent
where TComp1 : Component
where TComp2 : Component
{
private Dictionary<EntityUid, IComponent>.Enumerator _traitDict;
private readonly Dictionary<EntityUid, IComponent> _traitDict2;
private Dictionary<EntityUid, Component>.Enumerator _traitDict;
private readonly Dictionary<EntityUid, Component> _traitDict2;
private readonly EntityQuery<MetaDataComponent> _metaQuery;
public EntityQueryEnumerator(
Dictionary<EntityUid, IComponent> traitDict,
Dictionary<EntityUid, IComponent> traitDict2,
Dictionary<EntityUid, Component> traitDict,
Dictionary<EntityUid, Component> traitDict2,
EntityQuery<MetaDataComponent> metaQuery)
{
_traitDict = traitDict.GetEnumerator();
@@ -1655,8 +1673,8 @@ namespace Robust.Shared.GameObjects
if (!_traitDict.MoveNext())
{
uid = default;
comp1 = default;
comp2 = default;
comp1 = null;
comp2 = null;
return false;
}
@@ -1700,19 +1718,19 @@ namespace Robust.Shared.GameObjects
/// Returns all matching unpaused components.
/// </summary>
public struct EntityQueryEnumerator<TComp1, TComp2, TComp3> : IDisposable
where TComp1 : IComponent
where TComp2 : IComponent
where TComp3 : IComponent
where TComp1 : Component
where TComp2 : Component
where TComp3 : Component
{
private Dictionary<EntityUid, IComponent>.Enumerator _traitDict;
private readonly Dictionary<EntityUid, IComponent> _traitDict2;
private readonly Dictionary<EntityUid, IComponent> _traitDict3;
private Dictionary<EntityUid, Component>.Enumerator _traitDict;
private readonly Dictionary<EntityUid, Component> _traitDict2;
private readonly Dictionary<EntityUid, Component> _traitDict3;
private readonly EntityQuery<MetaDataComponent> _metaQuery;
public EntityQueryEnumerator(
Dictionary<EntityUid, IComponent> traitDict,
Dictionary<EntityUid, IComponent> traitDict2,
Dictionary<EntityUid, IComponent> traitDict3,
Dictionary<EntityUid, Component> traitDict,
Dictionary<EntityUid, Component> traitDict2,
Dictionary<EntityUid, Component> traitDict3,
EntityQuery<MetaDataComponent> metaQuery)
{
_traitDict = traitDict.GetEnumerator();
@@ -1728,9 +1746,9 @@ namespace Robust.Shared.GameObjects
if (!_traitDict.MoveNext())
{
uid = default;
comp1 = default;
comp2 = default;
comp3 = default;
comp1 = null;
comp2 = null;
comp3 = null;
return false;
}
@@ -1783,22 +1801,22 @@ namespace Robust.Shared.GameObjects
/// Returns all matching unpaused components.
/// </summary>
public struct EntityQueryEnumerator<TComp1, TComp2, TComp3, TComp4> : IDisposable
where TComp1 : IComponent
where TComp2 : IComponent
where TComp3 : IComponent
where TComp4 : IComponent
where TComp1 : Component
where TComp2 : Component
where TComp3 : Component
where TComp4 : Component
{
private Dictionary<EntityUid, IComponent>.Enumerator _traitDict;
private readonly Dictionary<EntityUid, IComponent> _traitDict2;
private readonly Dictionary<EntityUid, IComponent> _traitDict3;
private readonly Dictionary<EntityUid, IComponent> _traitDict4;
private Dictionary<EntityUid, Component>.Enumerator _traitDict;
private readonly Dictionary<EntityUid, Component> _traitDict2;
private readonly Dictionary<EntityUid, Component> _traitDict3;
private readonly Dictionary<EntityUid, Component> _traitDict4;
private readonly EntityQuery<MetaDataComponent> _metaQuery;
public EntityQueryEnumerator(
Dictionary<EntityUid, IComponent> traitDict,
Dictionary<EntityUid, IComponent> traitDict2,
Dictionary<EntityUid, IComponent> traitDict3,
Dictionary<EntityUid, IComponent> traitDict4,
Dictionary<EntityUid, Component> traitDict,
Dictionary<EntityUid, Component> traitDict2,
Dictionary<EntityUid, Component> traitDict3,
Dictionary<EntityUid, Component> traitDict4,
EntityQuery<MetaDataComponent> metaQuery)
{
_traitDict = traitDict.GetEnumerator();
@@ -1815,10 +1833,10 @@ namespace Robust.Shared.GameObjects
if (!_traitDict.MoveNext())
{
uid = default;
comp1 = default;
comp2 = default;
comp3 = default;
comp4 = default;
comp1 = null;
comp2 = null;
comp3 = null;
comp4 = null;
return false;
}
@@ -1882,12 +1900,12 @@ namespace Robust.Shared.GameObjects
/// Returns all matching components, paused or not.
/// </summary>
public struct AllEntityQueryEnumerator<TComp1> : IDisposable
where TComp1 : IComponent
where TComp1 : Component
{
private Dictionary<EntityUid, IComponent>.Enumerator _traitDict;
private Dictionary<EntityUid, Component>.Enumerator _traitDict;
public AllEntityQueryEnumerator(
Dictionary<EntityUid, IComponent> traitDict)
Dictionary<EntityUid, Component> traitDict)
{
_traitDict = traitDict.GetEnumerator();
}
@@ -1899,7 +1917,7 @@ namespace Robust.Shared.GameObjects
if (!_traitDict.MoveNext())
{
uid = default;
comp1 = default;
comp1 = null;
return false;
}
@@ -1932,15 +1950,15 @@ namespace Robust.Shared.GameObjects
/// Returns all matching components, paused or not.
/// </summary>
public struct AllEntityQueryEnumerator<TComp1, TComp2> : IDisposable
where TComp1 : IComponent
where TComp2 : IComponent
where TComp1 : Component
where TComp2 : Component
{
private Dictionary<EntityUid, IComponent>.Enumerator _traitDict;
private readonly Dictionary<EntityUid, IComponent> _traitDict2;
private Dictionary<EntityUid, Component>.Enumerator _traitDict;
private readonly Dictionary<EntityUid, Component> _traitDict2;
public AllEntityQueryEnumerator(
Dictionary<EntityUid, IComponent> traitDict,
Dictionary<EntityUid, IComponent> traitDict2)
Dictionary<EntityUid, Component> traitDict,
Dictionary<EntityUid, Component> traitDict2)
{
_traitDict = traitDict.GetEnumerator();
_traitDict2 = traitDict2;
@@ -1953,8 +1971,8 @@ namespace Robust.Shared.GameObjects
if (!_traitDict.MoveNext())
{
uid = default;
comp1 = default;
comp2 = default;
comp1 = null;
comp2 = null;
return false;
}
@@ -1993,18 +2011,18 @@ namespace Robust.Shared.GameObjects
/// Returns all matching components, paused or not.
/// </summary>
public struct AllEntityQueryEnumerator<TComp1, TComp2, TComp3> : IDisposable
where TComp1 : IComponent
where TComp2 : IComponent
where TComp3 : IComponent
where TComp1 : Component
where TComp2 : Component
where TComp3 : Component
{
private Dictionary<EntityUid, IComponent>.Enumerator _traitDict;
private readonly Dictionary<EntityUid, IComponent> _traitDict2;
private readonly Dictionary<EntityUid, IComponent> _traitDict3;
private Dictionary<EntityUid, Component>.Enumerator _traitDict;
private readonly Dictionary<EntityUid, Component> _traitDict2;
private readonly Dictionary<EntityUid, Component> _traitDict3;
public AllEntityQueryEnumerator(
Dictionary<EntityUid, IComponent> traitDict,
Dictionary<EntityUid, IComponent> traitDict2,
Dictionary<EntityUid, IComponent> traitDict3)
Dictionary<EntityUid, Component> traitDict,
Dictionary<EntityUid, Component> traitDict2,
Dictionary<EntityUid, Component> traitDict3)
{
_traitDict = traitDict.GetEnumerator();
_traitDict2 = traitDict2;
@@ -2018,9 +2036,9 @@ namespace Robust.Shared.GameObjects
if (!_traitDict.MoveNext())
{
uid = default;
comp1 = default;
comp2 = default;
comp3 = default;
comp1 = null;
comp2 = null;
comp3 = null;
return false;
}
@@ -2068,21 +2086,21 @@ namespace Robust.Shared.GameObjects
/// Returns all matching components, paused or not.
/// </summary>
public struct AllEntityQueryEnumerator<TComp1, TComp2, TComp3, TComp4> : IDisposable
where TComp1 : IComponent
where TComp2 : IComponent
where TComp3 : IComponent
where TComp4 : IComponent
where TComp1 : Component
where TComp2 : Component
where TComp3 : Component
where TComp4 : Component
{
private Dictionary<EntityUid, IComponent>.Enumerator _traitDict;
private readonly Dictionary<EntityUid, IComponent> _traitDict2;
private readonly Dictionary<EntityUid, IComponent> _traitDict3;
private readonly Dictionary<EntityUid, IComponent> _traitDict4;
private Dictionary<EntityUid, Component>.Enumerator _traitDict;
private readonly Dictionary<EntityUid, Component> _traitDict2;
private readonly Dictionary<EntityUid, Component> _traitDict3;
private readonly Dictionary<EntityUid, Component> _traitDict4;
public AllEntityQueryEnumerator(
Dictionary<EntityUid, IComponent> traitDict,
Dictionary<EntityUid, IComponent> traitDict2,
Dictionary<EntityUid, IComponent> traitDict3,
Dictionary<EntityUid, IComponent> traitDict4)
Dictionary<EntityUid, Component> traitDict,
Dictionary<EntityUid, Component> traitDict2,
Dictionary<EntityUid, Component> traitDict3,
Dictionary<EntityUid, Component> traitDict4)
{
_traitDict = traitDict.GetEnumerator();
_traitDict2 = traitDict2;
@@ -2097,10 +2115,10 @@ namespace Robust.Shared.GameObjects
if (!_traitDict.MoveNext())
{
uid = default;
comp1 = default;
comp2 = default;
comp3 = default;
comp4 = default;
comp1 = null;
comp2 = null;
comp3 = null;
comp4 = null;
return false;
}

View File

@@ -14,7 +14,7 @@ public partial class EntityManager
/// Increases the life stage from <see cref="ComponentLifeStage.PreAdd" /> to <see cref="ComponentLifeStage.Added" />,
/// after raising a <see cref="ComponentAdd"/> event.
/// </summary>
internal void LifeAddToEntity(IComponent component, CompIdx type)
internal void LifeAddToEntity(Component component, CompIdx type)
{
DebugTools.Assert(component.LifeStage == ComponentLifeStage.PreAdd);
@@ -30,7 +30,7 @@ public partial class EntityManager
/// Increases the life stage from <see cref="ComponentLifeStage.Added" /> to <see cref="ComponentLifeStage.Initialized" />,
/// calling <see cref="Initialize" />.
/// </summary>
internal void LifeInitialize(IComponent component, CompIdx type)
internal void LifeInitialize(Component component, CompIdx type)
{
DebugTools.Assert(component.LifeStage == ComponentLifeStage.Added);
@@ -43,7 +43,7 @@ public partial class EntityManager
/// Increases the life stage from <see cref="ComponentLifeStage.Initialized" /> to
/// <see cref="ComponentLifeStage.Running" />, calling <see cref="Startup" />.
/// </summary>
internal void LifeStartup(IComponent component)
internal void LifeStartup(Component component)
{
DebugTools.Assert(component.LifeStage == ComponentLifeStage.Initialized);
@@ -59,7 +59,7 @@ public partial class EntityManager
/// <remarks>
/// Components are allowed to remove themselves in their own Startup function.
/// </remarks>
internal void LifeShutdown(IComponent component)
internal void LifeShutdown(Component component)
{
DebugTools.Assert(component.LifeStage is >= ComponentLifeStage.Initializing and < ComponentLifeStage.Stopping);
@@ -79,13 +79,21 @@ public partial class EntityManager
/// Increases the life stage from <see cref="ComponentLifeStage.Stopped" /> to <see cref="ComponentLifeStage.Deleted" />,
/// calling <see cref="Component.OnRemove" />.
/// </summary>
internal void LifeRemoveFromEntity(IComponent component)
internal void LifeRemoveFromEntity(Component component)
{
// can be called at any time after PreAdd, including inside other life stage events.
DebugTools.Assert(component.LifeStage != ComponentLifeStage.PreAdd);
component.LifeStage = ComponentLifeStage.Removing;
EventBus.RaiseComponentEvent(component, CompRemoveInstance);
component.LifeStage = ComponentLifeStage.Deleted;
component.OnRemove();
#if DEBUG
if (component.LifeStage != ComponentLifeStage.Deleted)
{
DebugTools.Assert($"Component {component.GetType().Name} did not call base {nameof(component.OnRemove)} in derived method.");
}
#endif
}
}

View File

@@ -18,7 +18,7 @@ namespace Robust.Shared.GameObjects
{
public delegate void EntityUidQueryCallback(EntityUid uid);
public delegate void ComponentQueryCallback<T>(EntityUid uid, T component) where T : IComponent;
public delegate void ComponentQueryCallback<T>(EntityUid uid, T component) where T : Component;
/// <inheritdoc />
[Virtual]
@@ -387,27 +387,20 @@ namespace Robust.Shared.GameObjects
/// <inheritdoc />
[Obsolete("use override with an EntityUid")]
public void Dirty(IComponent component, MetaDataComponent? meta = null)
public void Dirty(Component component, MetaDataComponent? meta = null)
{
Dirty(component.Owner, component, meta);
}
/// <inheritdoc />
public virtual void Dirty(EntityUid uid, IComponent component, MetaDataComponent? meta = null)
public virtual void Dirty(EntityUid uid, Component component, MetaDataComponent? meta = null)
{
Dirty(new Entity<IComponent>(uid, component), meta);
}
public virtual void Dirty(Entity<IComponent> ent, MetaDataComponent? meta = null)
{
if (ent.Comp.LifeStage >= ComponentLifeStage.Removing || !ent.Comp.NetSyncEnabled)
if (component.LifeStage >= ComponentLifeStage.Removing || !component.NetSyncEnabled)
return;
DebugTools.AssertOwner(ent, ent.Comp);
DirtyEntity(ent, meta);
#pragma warning disable CS0618 // Type or member is obsolete
ent.Comp.LastModifiedTick = CurrentTick;
#pragma warning restore CS0618 // Type or member is obsolete
DebugTools.AssertOwner(uid, component);
DirtyEntity(uid, meta);
component.LastModifiedTick = CurrentTick;
}
/// <summary>
@@ -666,9 +659,7 @@ namespace Robust.Shared.GameObjects
// allocate the required TransformComponent
var xformComp = Unsafe.As<TransformComponent>(_componentFactory.GetComponent(_xformReg));
#pragma warning disable CS0618 // Type or member is obsolete
xformComp.Owner = uid;
#pragma warning restore CS0618 // Type or member is obsolete
AddComponentInternal(uid, xformComp, false, true, metadata);
return uid;

View File

@@ -3,21 +3,21 @@
public static class EntityManagerExt
{
public static T? GetComponentOrNull<T>(this IEntityManager entityManager, EntityUid entityUid)
where T : IComponent
where T : class, IComponent
{
if (entityManager.TryGetComponent(entityUid, out T? component))
return component;
return default;
return null;
}
public static T? GetComponentOrNull<T>(this IEntityManager entityManager, EntityUid? entityUid)
where T : IComponent
where T : class, IComponent
{
if (entityUid.HasValue && entityManager.TryGetComponent(entityUid.Value, out T? component))
return component;
return default;
return null;
}
}
}

View File

@@ -206,7 +206,7 @@ public partial class EntitySystem
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Obsolete("Use Dirty(EntityUid, Component, MetaDataComponent?")]
protected void Dirty(IComponent component, MetaDataComponent? meta = null)
protected void Dirty(Component component, MetaDataComponent? meta = null)
{
EntityManager.Dirty(component, meta);
}
@@ -215,20 +215,11 @@ public partial class EntitySystem
/// Marks a component as dirty. This also implicitly dirties the entity this component belongs to.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected void Dirty(EntityUid uid, IComponent component, MetaDataComponent? meta = null)
protected void Dirty(EntityUid uid, Component component, MetaDataComponent? meta = null)
{
EntityManager.Dirty(uid, component, meta);
}
/// <summary>
/// Marks a component as dirty. This also implicitly dirties the entity this component belongs to.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected void Dirty<T>(Entity<T> ent, MetaDataComponent? meta = null) where T : IComponent
{
EntityManager.Dirty(ent.Owner, ent.Comp, meta);
}
/// <summary>
/// Retrieves the name of an entity.
/// </summary>
@@ -405,7 +396,7 @@ public partial class EntitySystem
return true;
}
/// <inheritdoc cref="IEntityManager.ToPrettyString(EntityUid, MetaDataComponent?)"/>
/// <inheritdoc cref="IEntityManager.ToPrettyString"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[return: NotNullIfNotNull("uid")]
protected EntityStringRepresentation? ToPrettyString(EntityUid? uid, MetaDataComponent? metadata = null)
@@ -413,7 +404,7 @@ public partial class EntitySystem
return EntityManager.ToPrettyString(uid, metadata);
}
/// <inheritdoc cref="IEntityManager.ToPrettyString(EntityUid, MetaDataComponent?)"/>
/// <inheritdoc cref="IEntityManager.ToPrettyString"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[return: NotNullIfNotNull("netEntity")]
protected EntityStringRepresentation? ToPrettyString(NetEntity? netEntity)
@@ -421,17 +412,17 @@ public partial class EntitySystem
return EntityManager.ToPrettyString(netEntity);
}
/// <inheritdoc cref="IEntityManager.ToPrettyString(EntityUid, MetaDataComponent?)"/>
/// <inheritdoc cref="IEntityManager.ToPrettyString"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected EntityStringRepresentation ToPrettyString(EntityUid uid, MetaDataComponent? metadata)
=> EntityManager.ToPrettyString(uid, metadata);
/// <inheritdoc cref="IEntityManager.ToPrettyString(EntityUid, MetaDataComponent?)"/>
/// <inheritdoc cref="IEntityManager.ToPrettyString"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected EntityStringRepresentation ToPrettyString(EntityUid uid)
=> EntityManager.ToPrettyString(uid);
/// <inheritdoc cref="IEntityManager.ToPrettyString(EntityUid, MetaDataComponent?)"/>
/// <inheritdoc cref="IEntityManager.ToPrettyString"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected EntityStringRepresentation ToPrettyString(NetEntity netEntity)
=> EntityManager.ToPrettyString(netEntity);
@@ -442,7 +433,7 @@ public partial class EntitySystem
/// <inheritdoc cref="IEntityManager.GetComponent&lt;T&gt;"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected T Comp<T>(EntityUid uid) where T : IComponent
protected T Comp<T>(EntityUid uid) where T : Component
{
return EntityManager.GetComponent<T>(uid);
}
@@ -451,7 +442,7 @@ public partial class EntitySystem
/// Returns the component of a specific type, or null when it's missing or the entity does not exist.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected T? CompOrNull<T>(EntityUid uid) where T : IComponent
protected T? CompOrNull<T>(EntityUid uid) where T : class, IComponent
{
return EntityManager.GetComponentOrNull<T>(uid);
}
@@ -460,14 +451,14 @@ public partial class EntitySystem
/// Returns the component of a specific type, or null when it's missing or the entity does not exist.
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected T? CompOrNull<T>(EntityUid? uid) where T : IComponent
protected T? CompOrNull<T>(EntityUid? uid) where T : class, IComponent
{
return uid.HasValue ? EntityManager.GetComponentOrNull<T>(uid.Value) : default;
return uid.HasValue ? EntityManager.GetComponentOrNull<T>(uid.Value) : null;
}
/// <inheritdoc cref="IEntityManager.TryGetComponent&lt;T&gt;(EntityUid, out T)"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected bool TryComp<T>(EntityUid uid, [NotNullWhen(true)] out T? comp) where T : IComponent
protected bool TryComp<T>(EntityUid uid, [NotNullWhen(true)] out T? comp)
{
return EntityManager.TryGetComponent(uid, out comp);
}
@@ -488,7 +479,7 @@ public partial class EntitySystem
/// <inheritdoc cref="IEntityManager.TryGetComponent&lt;T&gt;(EntityUid?, out T)"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected bool TryComp<T>([NotNullWhen(true)] EntityUid? uid, [NotNullWhen(true)] out T? comp) where T : IComponent
protected bool TryComp<T>([NotNullWhen(true)] EntityUid? uid, [NotNullWhen(true)] out T? comp)
{
if (!uid.HasValue)
{
@@ -623,14 +614,14 @@ public partial class EntitySystem
/// <inheritdoc cref="IEntityManager.AddComponent&lt;T&gt;(EntityUid, T, bool)"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected void AddComp<T>(EntityUid uid, T component, bool overwrite = false) where T : IComponent
protected void AddComp<T>(EntityUid uid, T component, bool overwrite = false) where T : Component
{
EntityManager.AddComponent(uid, component, overwrite);
}
/// <inheritdoc cref="IEntityManager.EnsureComponent&lt;T&gt;(EntityUid)"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected T EnsureComp<T>(EntityUid uid) where T : IComponent, new()
protected T EnsureComp<T>(EntityUid uid) where T : Component, new()
{
return EntityManager.EnsureComponent<T>(uid);
}
@@ -641,7 +632,7 @@ public partial class EntitySystem
/// <inheritdoc cref="IEntityManager.RemoveComponentDeferred&lt;T&gt;(EntityUid)"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected bool RemCompDeferred<T>(EntityUid uid) where T : IComponent
protected bool RemCompDeferred<T>(EntityUid uid) where T : class, IComponent
{
return EntityManager.RemoveComponentDeferred<T>(uid);
}
@@ -672,7 +663,7 @@ public partial class EntitySystem
/// <inheritdoc cref="IEntityManager.Count" />
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected int Count<T>() where T : IComponent
protected int Count<T>() where T : Component
{
return EntityManager.Count<T>();
}
@@ -690,7 +681,7 @@ public partial class EntitySystem
/// <inheritdoc cref="IEntityManager.RemoveComponent&lt;T&gt;(EntityUid)"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected bool RemComp<T>(EntityUid uid) where T : IComponent
protected bool RemComp<T>(EntityUid uid) where T : class, IComponent
{
return EntityManager.RemoveComponent<T>(uid);
}
@@ -828,34 +819,34 @@ public partial class EntitySystem
#region All Entity Query
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected AllEntityQueryEnumerator<TComp1> AllEntityQuery<TComp1>() where TComp1 : IComponent
protected AllEntityQueryEnumerator<TComp1> AllEntityQuery<TComp1>() where TComp1 : Component
{
return EntityManager.AllEntityQueryEnumerator<TComp1>();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected AllEntityQueryEnumerator<TComp1, TComp2> AllEntityQuery<TComp1, TComp2>()
where TComp1 : IComponent
where TComp2 : IComponent
where TComp1 : Component
where TComp2 : Component
{
return EntityManager.AllEntityQueryEnumerator<TComp1, TComp2>();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected AllEntityQueryEnumerator<TComp1, TComp2, TComp3> AllEntityQuery<TComp1, TComp2, TComp3>()
where TComp1 : IComponent
where TComp2 : IComponent
where TComp3 : IComponent
where TComp1 : Component
where TComp2 : Component
where TComp3 : Component
{
return EntityManager.AllEntityQueryEnumerator<TComp1, TComp2, TComp3>();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected AllEntityQueryEnumerator<TComp1, TComp2, TComp3, TComp4> AllEntityQuery<TComp1, TComp2, TComp3, TComp4>()
where TComp1 : IComponent
where TComp2 : IComponent
where TComp3 : IComponent
where TComp4 : IComponent
where TComp1 : Component
where TComp2 : Component
where TComp3 : Component
where TComp4 : Component
{
return EntityManager.AllEntityQueryEnumerator<TComp1, TComp2, TComp3, TComp4>();
}
@@ -865,34 +856,34 @@ public partial class EntitySystem
#region Get Entity Query
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected EntityQueryEnumerator<TComp1> EntityQueryEnumerator<TComp1>() where TComp1 : IComponent
protected EntityQueryEnumerator<TComp1> EntityQueryEnumerator<TComp1>() where TComp1 : Component
{
return EntityManager.EntityQueryEnumerator<TComp1>();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected EntityQueryEnumerator<TComp1, TComp2> EntityQueryEnumerator<TComp1, TComp2>()
where TComp1 : IComponent
where TComp2 : IComponent
where TComp1 : Component
where TComp2 : Component
{
return EntityManager.EntityQueryEnumerator<TComp1, TComp2>();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected EntityQueryEnumerator<TComp1, TComp2, TComp3> EntityQueryEnumerator<TComp1, TComp2, TComp3>()
where TComp1 : IComponent
where TComp2 : IComponent
where TComp3 : IComponent
where TComp1 : Component
where TComp2 : Component
where TComp3 : Component
{
return EntityManager.EntityQueryEnumerator<TComp1, TComp2, TComp3>();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected EntityQueryEnumerator<TComp1, TComp2, TComp3, TComp4> EntityQueryEnumerator<TComp1, TComp2, TComp3, TComp4>()
where TComp1 : IComponent
where TComp2 : IComponent
where TComp3 : IComponent
where TComp4 : IComponent
where TComp1 : Component
where TComp2 : Component
where TComp3 : Component
where TComp4 : Component
{
return EntityManager.EntityQueryEnumerator<TComp1, TComp2, TComp3, TComp4>();
}
@@ -906,7 +897,7 @@ public partial class EntitySystem
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Pure]
protected EntityQuery<T> GetEntityQuery<T>() where T : IComponent
protected EntityQuery<T> GetEntityQuery<T>() where T : Component
{
return EntityManager.GetEntityQuery<T>();
}
@@ -915,7 +906,7 @@ public partial class EntitySystem
/// If you need the EntityUid, use <see cref="EntityQueryEnumerator{TComp1}"/>
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected IEnumerable<TComp1> EntityQuery<TComp1>(bool includePaused = false) where TComp1 : IComponent
protected IEnumerable<TComp1> EntityQuery<TComp1>(bool includePaused = false) where TComp1 : Component
{
return EntityManager.EntityQuery<TComp1>(includePaused);
}
@@ -925,8 +916,8 @@ public partial class EntitySystem
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected IEnumerable<(TComp1, TComp2)> EntityQuery<TComp1, TComp2>(bool includePaused = false)
where TComp1 : IComponent
where TComp2 : IComponent
where TComp1 : Component
where TComp2 : Component
{
return EntityManager.EntityQuery<TComp1, TComp2>(includePaused);
}
@@ -936,9 +927,9 @@ public partial class EntitySystem
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected IEnumerable<(TComp1, TComp2, TComp3)> EntityQuery<TComp1, TComp2, TComp3>(bool includePaused = false)
where TComp1 : IComponent
where TComp2 : IComponent
where TComp3 : IComponent
where TComp1 : Component
where TComp2 : Component
where TComp3 : Component
{
return EntityManager.EntityQuery<TComp1, TComp2, TComp3>(includePaused);
}
@@ -948,10 +939,10 @@ public partial class EntitySystem
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected IEnumerable<(TComp1, TComp2, TComp3, TComp4)> EntityQuery<TComp1, TComp2, TComp3, TComp4>(bool includePaused = false)
where TComp1 : IComponent
where TComp2 : IComponent
where TComp3 : IComponent
where TComp4 : IComponent
where TComp1 : Component
where TComp2 : Component
where TComp3 : Component
where TComp4 : Component
{
return EntityManager.EntityQuery<TComp1, TComp2, TComp3, TComp4>(includePaused);
}

View File

@@ -19,7 +19,7 @@ namespace Robust.Shared.GameObjects
protected bool Resolve<TComp>(EntityUid uid, [NotNullWhen(true)] ref TComp? component, bool logMissing = true)
where TComp : IComponent
{
DebugTools.AssertOwner(uid, component);
DebugTools.Assert(component == null || uid == component.Owner, "Specified Entity is not the component's Owner!");
if (component != null && !component.Deleted)
return true;

View File

@@ -24,8 +24,6 @@ namespace Robust.Shared.GameObjects
SubEvent(EventSource.Network, handler, before, after);
}
/// <seealso cref="SubscribeLocalEvent{T}(EntityEventRefHandler{T}, Type[], Type[])"/>
// [Obsolete("Subscribe to the event by ref instead (EntityEventRefHandler)")]
protected void SubscribeLocalEvent<T>(
EntityEventHandler<T> handler,
Type[]? before = null, Type[]? after = null)
@@ -74,8 +72,6 @@ namespace Robust.Shared.GameObjects
SubSessionEvent(EventSource.All, handler, before, after);
}
/// <seealso cref="SubEvent{T}(EventSource, EntityEventRefHandler{T}, Type[], Type[])"/>
// [Obsolete("Subscribe to the event by ref instead (EntityEventRefHandler)")]
private void SubEvent<T>(
EventSource src,
EntityEventHandler<T> handler,
@@ -112,8 +108,6 @@ namespace Robust.Shared.GameObjects
_subscriptions.Add(new SubBroadcast<EntitySessionMessage<T>>(src));
}
/// <seealso cref="SubscribeLocalEvent{TComp, TEvent}(ComponentEventRefHandler{TComp, TEvent}, Type[], Type[])"/>
// [Obsolete("Subscribe to the event by ref instead (ComponentEventRefHandler)")]
protected void SubscribeLocalEvent<TComp, TEvent>(
ComponentEventHandler<TComp, TEvent> handler,
Type[]? before = null, Type[]? after = null)
@@ -138,18 +132,6 @@ namespace Robust.Shared.GameObjects
_subscriptions.Add(new SubLocal<TComp, TEvent>());
}
protected void SubscribeLocalEvent<TComp, TEvent>(
EntityEventRefHandler<TComp, TEvent> handler,
Type[]? before = null, Type[]? after = null)
where TComp : IComponent
where TEvent : notnull
{
EntityManager.EventBus.SubscribeLocalEvent(handler, GetType(), before, after);
_subscriptions ??= new();
_subscriptions.Add(new SubLocal<TComp, TEvent>());
}
private void ShutdownSubscriptions()
{
if (_subscriptions == null)

View File

@@ -4,6 +4,7 @@ using Robust.Shared.IoC;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
using Robust.Shared.ViewVariables;
namespace Robust.Shared.GameObjects
@@ -152,7 +153,7 @@ namespace Robust.Shared.GameObjects
set
{
if (MetaData is {} metaData)
IoCManager.Resolve<IEntityManager>().System<MetaDataSystem>().SetEntityName(this, value, metaData);
metaData.EntityName = value;
}
}
@@ -162,11 +163,8 @@ namespace Robust.Shared.GameObjects
get => MetaData?.EntityDescription ?? string.Empty;
set
{
if (MetaData is { } metaData)
{
var entManager = IoCManager.Resolve<IEntityManager>();
entManager.System<MetaDataSystem>().SetEntityDescription(this, value, metaData);
}
if (MetaData is {} metaData)
metaData.EntityDescription = value;
}
}

View File

@@ -1,5 +1,5 @@
using System;
using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Timing;
@@ -7,6 +7,7 @@ namespace Robust.Shared.GameObjects
{
/// <remarks>
/// Base component for the ECS system.
/// All discoverable implementations of IComponent must override the <see cref="Name" />.
/// Instances are dynamically instantiated by a <c>ComponentFactory</c>, and will have their IoC Dependencies resolved.
/// </remarks>
[ImplicitDataDefinitionForInheritors]
@@ -16,10 +17,7 @@ namespace Robust.Shared.GameObjects
/// The current lifetime stage of this component. You can use this to check
/// if the component is initialized or being deleted.
/// </summary>
ComponentLifeStage LifeStage { get; [Obsolete("Do not use from content")] set; }
[Obsolete("Do not use from content")]
bool Networked { get; set; }
ComponentLifeStage LifeStage { get; }
/// <summary>
/// Whether this component should be synchronized with clients when modified.
@@ -30,25 +28,11 @@ namespace Robust.Shared.GameObjects
/// </summary>
bool NetSyncEnabled { get; set; }
/// <summary>
/// If true, and if this is a networked component, then component data will only be sent to players if their
/// controlled entity is the owner of this component. This is less performance intensive than <see cref="SessionSpecific"/>.
/// </summary>
bool SendOnlyToOwner { get; }
/// <summary>
/// If true, and if this is a networked component, then this component will cause <see
/// cref="ComponentGetStateAttemptEvent"/> events to be raised to check whether a given player should
/// receive this component's state.
/// </summary>
bool SessionSpecific { get; }
/// <summary>
/// Entity that this component is attached to.
/// </summary>
/// <seealso cref="EntityQueryEnumerator{TComp1}"/>
[Obsolete("Update your API to allow accessing Owner through other means")]
EntityUid Owner { get; set; }
EntityUid Owner { get; }
/// <summary>
/// Component has been (or is currently being) initialized.
@@ -73,17 +57,11 @@ namespace Robust.Shared.GameObjects
/// <summary>
/// This is the tick the component was created.
/// </summary>
GameTick CreationTick { get; [Obsolete("Do not use from content")] set; }
GameTick CreationTick { get; }
/// <summary>
/// This is the last game tick Dirty() was called.
/// </summary>
GameTick LastModifiedTick { get; [Obsolete("Do not use from content")] set; }
[Obsolete("Do not use from content")]
void ClearTicks();
[Obsolete("Do not use from content")]
void ClearCreationTick();
GameTick LastModifiedTick { get; }
}
}

View File

@@ -31,7 +31,7 @@ namespace Robust.Shared.GameObjects
/// <summary>
/// Gets the number of a specific component.
/// </summary>
public int Count<T>() where T : IComponent;
public int Count<T>() where T : Component;
/// <summary>
/// Gets the number of a specific component.
@@ -44,12 +44,12 @@ namespace Robust.Shared.GameObjects
/// </summary>
/// <typeparam name="T">Concrete component type to add.</typeparam>
/// <returns>The newly added component.</returns>
T AddComponent<T>(EntityUid uid) where T : IComponent, new();
T AddComponent<T>(EntityUid uid) where T : Component, new();
/// <summary>
/// Adds a Component with a given network id to an entity.
/// </summary>
IComponent AddComponent(EntityUid uid, ushort netId, MetaDataComponent? meta = null);
Component AddComponent(EntityUid uid, ushort netId, MetaDataComponent? meta = null);
/// <summary>
/// Adds an uninitialized Component type to an entity.
@@ -62,7 +62,7 @@ namespace Robust.Shared.GameObjects
/// <param name="uid">Entity being modified.</param>
/// <returns>Component initialization handle. When you are done setting up the component, make sure to dispose this.</returns>
[Obsolete]
EntityManager.CompInitializeHandle<T> AddComponentUninitialized<T>(EntityUid uid) where T : IComponent, new();
EntityManager.CompInitializeHandle<T> AddComponentUninitialized<T>(EntityUid uid) where T : Component, new();
/// <summary>
/// Adds a Component to an entity. If the entity is already Initialized, the component will
@@ -71,7 +71,7 @@ namespace Robust.Shared.GameObjects
/// <param name="uid">Entity being modified.</param>
/// <param name="component">Component to add.</param>
/// <param name="overwrite">Should it overwrite existing components?</param>
void AddComponent<T>(EntityUid uid, T component, bool overwrite = false, MetaDataComponent? metadata = null) where T : IComponent;
void AddComponent<T>(EntityUid uid, T component, bool overwrite = false, MetaDataComponent? metadata = null) where T : Component;
/// <summary>
/// Removes the component with the specified reference type,
@@ -214,7 +214,7 @@ namespace Robust.Shared.GameObjects
/// <param name="uid">Entity to modify.</param>
/// <typeparam name="T">Component to add.</typeparam>
/// <returns>The component in question</returns>
T EnsureComponent<T>(EntityUid uid) where T : IComponent, new();
T EnsureComponent<T>(EntityUid uid) where T : Component, new();
/// <summary>
/// This method will always return a component for a certain entity, adding it if it's not there already.
@@ -223,7 +223,7 @@ namespace Robust.Shared.GameObjects
/// <param name="component">The output component after being ensured.</param>
/// <typeparam name="T">Component to add.</typeparam>
/// <returns>True if the component already existed</returns>
bool EnsureComponent<T>(EntityUid uid, out T component) where T : IComponent, new();
bool EnsureComponent<T>(EntityUid uid, out T component) where T : Component, new();
/// <summary>
/// Returns the component of a specific type.
@@ -334,9 +334,9 @@ namespace Robust.Shared.GameObjects
/// <summary>
/// Returns a cached struct enumerator with the specified component.
/// </summary>
EntityQuery<TComp1> GetEntityQuery<TComp1>() where TComp1 : IComponent;
EntityQuery<TComp1> GetEntityQuery<TComp1>() where TComp1 : Component;
EntityQuery<IComponent> GetEntityQuery(Type type);
EntityQuery<Component> GetEntityQuery(Type type);
/// <summary>
/// Returns ALL component type instances on an entity. A single component instance
@@ -398,49 +398,49 @@ namespace Robust.Shared.GameObjects
/// Returns all instances of a component in an array.
/// Use sparingly.
/// </summary>
(EntityUid Uid, T Component)[] AllComponents<T>() where T : IComponent;
(EntityUid Uid, T Component)[] AllComponents<T>() where T : Component;
/// <summary>
/// Returns all instances of a component in a List.
/// Use sparingly.
/// </summary>
List<(EntityUid Uid, T Component)> AllComponentsList<T>() where T : IComponent;
List<(EntityUid Uid, T Component)> AllComponentsList<T>() where T : Component;
AllEntityQueryEnumerator<TComp1> AllEntityQueryEnumerator<TComp1>()
where TComp1 : IComponent;
where TComp1 : Component;
AllEntityQueryEnumerator<TComp1, TComp2> AllEntityQueryEnumerator<TComp1, TComp2>()
where TComp1 : IComponent
where TComp2 : IComponent;
where TComp1 : Component
where TComp2 : Component;
AllEntityQueryEnumerator<TComp1, TComp2, TComp3> AllEntityQueryEnumerator<TComp1, TComp2, TComp3>()
where TComp1 : IComponent
where TComp2 : IComponent
where TComp3 : IComponent;
where TComp1 : Component
where TComp2 : Component
where TComp3 : Component;
AllEntityQueryEnumerator<TComp1, TComp2, TComp3, TComp4> AllEntityQueryEnumerator<TComp1, TComp2, TComp3, TComp4>()
where TComp1 : IComponent
where TComp2 : IComponent
where TComp3 : IComponent
where TComp4 : IComponent;
where TComp1 : Component
where TComp2 : Component
where TComp3 : Component
where TComp4 : Component;
EntityQueryEnumerator<TComp1> EntityQueryEnumerator<TComp1>()
where TComp1 : IComponent;
where TComp1 : Component;
EntityQueryEnumerator<TComp1, TComp2> EntityQueryEnumerator<TComp1, TComp2>()
where TComp1 : IComponent
where TComp2 : IComponent;
where TComp1 : Component
where TComp2 : Component;
EntityQueryEnumerator<TComp1, TComp2, TComp3> EntityQueryEnumerator<TComp1, TComp2, TComp3>()
where TComp1 : IComponent
where TComp2 : IComponent
where TComp3 : IComponent;
where TComp1 : Component
where TComp2 : Component
where TComp3 : Component;
EntityQueryEnumerator<TComp1, TComp2, TComp3, TComp4> EntityQueryEnumerator<TComp1, TComp2, TComp3, TComp4>()
where TComp1 : IComponent
where TComp2 : IComponent
where TComp3 : IComponent
where TComp4 : IComponent;
where TComp1 : Component
where TComp2 : Component
where TComp3 : Component
where TComp4 : Component;
/// <summary>
/// Returns ALL component instances of a specified type.
@@ -491,7 +491,7 @@ namespace Robust.Shared.GameObjects
/// <param name="type">A trait or component type to check for.</param>
/// <param name="includePaused"></param>
/// <returns>All components that are the specified type.</returns>
IEnumerable<(EntityUid Uid, IComponent Component)> GetAllComponents(Type type, bool includePaused = false);
IEnumerable<(EntityUid Uid, Component Component)> GetAllComponents(Type type, bool includePaused = false);
/// <summary>
/// Culls all components from the collection that are marked as deleted. This needs to be called often.

View File

@@ -83,11 +83,9 @@ namespace Robust.Shared.GameObjects
public void DirtyEntity(EntityUid uid, MetaDataComponent? metadata = null);
public void Dirty(IComponent component, MetaDataComponent? metadata = null);
public void Dirty(Component component, MetaDataComponent? metadata = null);
public void Dirty(EntityUid uid, IComponent component, MetaDataComponent? meta = null);
public void Dirty(Entity<IComponent> ent, MetaDataComponent? meta = null);
public void Dirty(EntityUid uid, Component component, MetaDataComponent? meta = null);
public void QueueDeleteEntity(EntityUid? uid);

View File

@@ -184,11 +184,8 @@ public readonly struct NetEntity : IEquatable<NetEntity>, IComparable<NetEntity>
get => MetaData?.EntityName ?? string.Empty;
set
{
if (MetaData is { } metaData)
{
var entManager = IoCManager.Resolve<IEntityManager>();
entManager.System<MetaDataSystem>().SetEntityName(entManager.GetEntity(this), value, metaData);
}
if (MetaData is {} metaData)
metaData.EntityName = value;
}
}
@@ -198,11 +195,8 @@ public readonly struct NetEntity : IEquatable<NetEntity>, IComparable<NetEntity>
get => MetaData?.EntityDescription ?? string.Empty;
set
{
if (MetaData is { } metaData)
{
var entManager = IoCManager.Resolve<IEntityManager>();
entManager.System<MetaDataSystem>().SetEntityDescription(entManager.GetEntity(this), value, metaData);
}
if (MetaData is {} metaData)
metaData.EntityDescription = value;
}
}

View File

@@ -2,6 +2,7 @@ using System.Collections.Generic;
using System.Numerics;
using System.Runtime.CompilerServices;
using Robust.Shared.Collections;
using Robust.Shared.Containers;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Maths;
@@ -272,14 +273,9 @@ public sealed partial class EntityLookupSystem
public HashSet<EntityUid> GetEntitiesIntersecting(MapId mapId, Box2 worldAABB, LookupFlags flags = DefaultFlags)
{
var intersecting = new HashSet<EntityUid>();
GetEntitiesIntersecting(mapId, worldAABB, intersecting, flags);
return intersecting;
}
if (mapId == MapId.Nullspace) return new HashSet<EntityUid>();
public void GetEntitiesIntersecting(MapId mapId, Box2 worldAABB, HashSet<EntityUid> intersecting, LookupFlags flags = DefaultFlags)
{
if (mapId == MapId.Nullspace) return;
var intersecting = new HashSet<EntityUid>();
// Get grid entities
var state = (this, _map, intersecting, worldAABB, _transform, flags);
@@ -313,6 +309,8 @@ public sealed partial class EntityLookupSystem
var localAABB = _transform.GetInvWorldMatrix(mapUid).TransformBox(worldAABB);
AddEntitiesIntersecting(mapUid, intersecting, localAABB, flags);
AddContained(intersecting, flags);
return intersecting;
}
#endregion
@@ -548,23 +546,16 @@ public sealed partial class EntityLookupSystem
public HashSet<EntityUid> GetEntitiesInRange(MapId mapId, Vector2 worldPos, float range,
LookupFlags flags = DefaultFlags)
{
var entities = new HashSet<EntityUid>();
GetEntitiesInRange(mapId, worldPos, range, entities, flags);
return entities;
}
public void GetEntitiesInRange(MapId mapId, Vector2 worldPos, float range, HashSet<EntityUid> entities, LookupFlags flags = DefaultFlags)
{
DebugTools.Assert(range > 0, "Range must be a positive float");
if (mapId == MapId.Nullspace)
return;
return new HashSet<EntityUid>();
// TODO: Actual circles
var rangeVec = new Vector2(range, range);
var worldAABB = new Box2(worldPos - rangeVec, worldPos + rangeVec);
GetEntitiesIntersecting(mapId, worldAABB, entities, flags);
return GetEntitiesIntersecting(mapId, worldAABB, flags);
}
#endregion

View File

@@ -1,11 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Robust.Shared.Collections;
using Robust.Shared.Containers;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Dynamics;
using Robust.Shared.Utility;
@@ -20,19 +21,7 @@ public sealed partial class EntityLookupSystem
HashSet<T> intersecting,
Box2 worldAABB,
LookupFlags flags,
EntityQuery<T> query) where T : IComponent
{
var intersectingEntities = new HashSet<Entity<T>>();
AddEntitiesIntersecting(lookupUid, intersectingEntities, worldAABB, flags, query);
intersecting.UnionWith(intersectingEntities.Select(e => e.Comp));
}
private void AddEntitiesIntersecting<T>(
EntityUid lookupUid,
HashSet<Entity<T>> intersecting,
Box2 worldAABB,
LookupFlags flags,
EntityQuery<T> query) where T : IComponent
EntityQuery<T> query) where T : Component
{
var lookup = _broadQuery.GetComponent(lookupUid);
var invMatrix = _transform.GetInvWorldMatrix(lookupUid);
@@ -41,48 +30,48 @@ public sealed partial class EntityLookupSystem
if ((flags & LookupFlags.Dynamic) != 0x0)
{
lookup.DynamicTree.QueryAabb(ref state, static (ref (HashSet<Entity<T>> intersecting, EntityQuery<T> query) tuple, in FixtureProxy value) =>
lookup.DynamicTree.QueryAabb(ref state, static (ref (HashSet<T> intersecting, EntityQuery<T> query) tuple, in FixtureProxy value) =>
{
if (!tuple.query.TryGetComponent(value.Entity, out var comp))
return true;
tuple.intersecting.Add((value.Entity, comp));
tuple.intersecting.Add(comp);
return true;
}, localAABB, (flags & LookupFlags.Approximate) != 0x0);
}
if ((flags & (LookupFlags.Static)) != 0x0)
{
lookup.StaticTree.QueryAabb(ref state, static (ref (HashSet<Entity<T>> intersecting, EntityQuery<T> query) tuple, in FixtureProxy value) =>
lookup.StaticTree.QueryAabb(ref state, static (ref (HashSet<T> intersecting, EntityQuery<T> query) tuple, in FixtureProxy value) =>
{
if (!tuple.query.TryGetComponent(value.Entity, out var comp))
return true;
tuple.intersecting.Add((value.Entity, comp));
tuple.intersecting.Add(comp);
return true;
}, localAABB, (flags & LookupFlags.Approximate) != 0x0);
}
if ((flags & LookupFlags.StaticSundries) == LookupFlags.StaticSundries)
{
lookup.StaticSundriesTree.QueryAabb(ref state, static (ref (HashSet<Entity<T>> intersecting, EntityQuery<T> query) tuple, in EntityUid value) =>
lookup.StaticSundriesTree.QueryAabb(ref state, static (ref (HashSet<T> intersecting, EntityQuery<T> query) tuple, in EntityUid value) =>
{
if (!tuple.query.TryGetComponent(value, out var comp))
return true;
tuple.intersecting.Add((value, comp));
tuple.intersecting.Add(comp);
return true;
}, localAABB, (flags & LookupFlags.Approximate) != 0x0);
}
if ((flags & LookupFlags.Sundries) != 0x0)
{
lookup.SundriesTree.QueryAabb(ref state, static (ref (HashSet<Entity<T>> intersecting, EntityQuery<T> query) tuple, in EntityUid value) =>
lookup.SundriesTree.QueryAabb(ref state, static (ref (HashSet<T> intersecting, EntityQuery<T> query) tuple, in EntityUid value) =>
{
if (!tuple.query.TryGetComponent(value, out var comp))
return true;
tuple.intersecting.Add((value, comp));
tuple.intersecting.Add(comp);
return true;
}, localAABB, (flags & LookupFlags.Approximate) != 0x0);
}
@@ -93,7 +82,7 @@ public sealed partial class EntityLookupSystem
Box2 worldAABB,
LookupFlags flags,
EntityQuery<T> query,
EntityUid? ignored = null) where T : IComponent
EntityUid? ignored = null) where T : Component
{
var lookup = _broadQuery.GetComponent(lookupUid);
var invMatrix = _transform.GetInvWorldMatrix(lookupUid);
@@ -164,7 +153,7 @@ public sealed partial class EntityLookupSystem
return state.found;
}
private void RecursiveAdd<T>(EntityUid uid, ref ValueList<T> toAdd, EntityQuery<T> query) where T : IComponent
private void RecursiveAdd<T>(EntityUid uid, ref ValueList<T> toAdd, EntityQuery<T> query) where T : Component
{
var childEnumerator = _xformQuery.GetComponent(uid).ChildEnumerator;
@@ -179,38 +168,15 @@ public sealed partial class EntityLookupSystem
}
}
private void RecursiveAdd<T>(EntityUid uid, ref ValueList<Entity<T>> toAdd, EntityQuery<T> query) where T : IComponent
{
var childEnumerator = _xformQuery.GetComponent(uid).ChildEnumerator;
while (childEnumerator.MoveNext(out var child))
{
if (query.TryGetComponent(child.Value, out var compies))
{
toAdd.Add((child.Value, compies));
}
RecursiveAdd(child.Value, ref toAdd, query);
}
}
[Obsolete]
private void AddContained<T>(HashSet<T> intersecting, LookupFlags flags, EntityQuery<T> query) where T : IComponent
{
var intersectingEntities = new HashSet<Entity<T>>();
AddContained(intersectingEntities, flags, query);
intersecting.UnionWith(intersectingEntities.Select(e => e.Comp));
}
private void AddContained<T>(HashSet<Entity<T>> intersecting, LookupFlags flags, EntityQuery<T> query) where T : IComponent
private void AddContained<T>(HashSet<T> intersecting, LookupFlags flags, EntityQuery<T> query) where T : Component
{
if ((flags & LookupFlags.Contained) == 0x0) return;
var toAdd = new ValueList<Entity<T>>();
var toAdd = new ValueList<T>();
foreach (var comp in intersecting)
{
if (!_containerQuery.TryGetComponent(comp, out var conManager)) continue;
if (!_containerQuery.TryGetComponent(comp.Owner, out var conManager)) continue;
foreach (var con in conManager.GetAllContainers())
{
@@ -218,7 +184,7 @@ public sealed partial class EntityLookupSystem
{
if (query.TryGetComponent(contained, out var compies))
{
toAdd.Add((contained, compies));
toAdd.Add(compies);
}
RecursiveAdd(contained, ref toAdd, query);
@@ -243,7 +209,7 @@ public sealed partial class EntityLookupSystem
/// <summary>
/// Should we just iterate every component and check position or do bounds checks.
/// </summary>
private bool UseBoundsQuery<T>(float area) where T : IComponent
private bool UseBoundsQuery<T>(float area) where T : Component
{
// If the component has a low count we'll just do an estimate if it's faster to iterate every comp directly
// Might be useful to have some way to expose this to content?
@@ -258,7 +224,7 @@ public sealed partial class EntityLookupSystem
public bool AnyComponentsIntersecting(Type type, MapId mapId, Box2 worldAABB, EntityUid? ignored = null, LookupFlags flags = DefaultFlags)
{
DebugTools.Assert(typeof(IComponent).IsAssignableFrom(type));
DebugTools.Assert(typeof(Component).IsAssignableFrom(type));
if (mapId == MapId.Nullspace) return false;
if (!UseBoundsQuery(type, worldAABB.Height * worldAABB.Width))
@@ -290,7 +256,7 @@ public sealed partial class EntityLookupSystem
(EntityLookupSystem system,
Box2 worldAABB,
LookupFlags flags,
EntityQuery<IComponent> query,
EntityQuery<Component> query,
EntityUid? ignored,
bool found) tuple) =>
{
@@ -308,20 +274,13 @@ public sealed partial class EntityLookupSystem
return false;
}
[Obsolete]
public HashSet<IComponent> GetComponentsIntersecting(Type type, MapId mapId, Box2 worldAABB, LookupFlags flags = DefaultFlags)
public HashSet<Component> GetComponentsIntersecting(Type type, MapId mapId, Box2 worldAABB, LookupFlags flags = DefaultFlags)
{
var intersectingEntities = new HashSet<Entity<IComponent>>();
GetEntitiesIntersecting(type, mapId, worldAABB, intersectingEntities, flags);
var intersecting = new HashSet<IComponent>(intersectingEntities.Select(e => e.Comp));
return intersecting;
}
public void GetEntitiesIntersecting(Type type, MapId mapId, Box2 worldAABB, HashSet<Entity<IComponent>> intersecting, LookupFlags flags = DefaultFlags)
{
DebugTools.Assert(typeof(IComponent).IsAssignableFrom(type));
DebugTools.Assert(typeof(Component).IsAssignableFrom(type));
if (mapId == MapId.Nullspace)
return;
return new HashSet<Component>();
var intersecting = new HashSet<Component>();
if (!UseBoundsQuery(type, worldAABB.Height * worldAABB.Width))
{
@@ -337,7 +296,7 @@ public sealed partial class EntityLookupSystem
continue;
}
intersecting.Add((uid, comp));
intersecting.Add(comp);
}
}
else
@@ -352,40 +311,36 @@ public sealed partial class EntityLookupSystem
ref (EntityLookupSystem system,
Box2 worldAABB,
LookupFlags flags,
EntityQuery<IComponent> query,
HashSet<Entity<IComponent>> intersecting) tuple) =>
EntityQuery<Component> query,
HashSet<Component> intersecting) tuple) =>
{
tuple.system.AddEntitiesIntersecting(uid, tuple.intersecting, tuple.worldAABB, tuple.flags, tuple.query);
tuple.system.AddComponentsIntersecting(uid, tuple.intersecting, tuple.worldAABB, tuple.flags, tuple.query);
return true;
}, (flags & LookupFlags.Approximate) != 0x0);
// Get map entities
var mapUid = _mapManager.GetMapEntityId(mapId);
AddEntitiesIntersecting(mapUid, intersecting, worldAABB, flags, query);
AddComponentsIntersecting(mapUid, intersecting, worldAABB, flags, query);
AddContained(intersecting, flags, query);
}
return intersecting;
}
[Obsolete]
public HashSet<T> GetComponentsIntersecting<T>(MapId mapId, Box2 worldAABB, LookupFlags flags = DefaultFlags) where T : IComponent
public HashSet<T> GetComponentsIntersecting<T>(MapId mapId, Box2 worldAABB, LookupFlags flags = DefaultFlags) where T : Component
{
var intersectingEntities = new HashSet<Entity<T>>();
GetEntitiesIntersecting(mapId, worldAABB, intersectingEntities, flags);
return new HashSet<T>(intersectingEntities.Select(e => e.Comp));
}
if (mapId == MapId.Nullspace) return new HashSet<T>();
public void GetEntitiesIntersecting<T>(MapId mapId, Box2 worldAABB, HashSet<Entity<T>> entities, LookupFlags flags = DefaultFlags) where T : IComponent
{
if (mapId == MapId.Nullspace) return;
var intersecting = new HashSet<T>();
if (!UseBoundsQuery<T>(worldAABB.Height * worldAABB.Width))
{
var query = AllEntityQuery<T, TransformComponent>();
while (query.MoveNext(out var uid, out var comp, out var xform))
while (query.MoveNext(out var comp, out var xform))
{
if (xform.MapID != mapId || !worldAABB.Contains(_transform.GetWorldPosition(xform))) continue;
entities.Add((uid, comp));
intersecting.Add(comp);
}
}
else
@@ -393,93 +348,60 @@ public sealed partial class EntityLookupSystem
var query = GetEntityQuery<T>();
// Get grid entities
var state = (this, worldAABB, flags, query, entities);
var state = (this, worldAABB, flags, query, intersecting);
_mapManager.FindGridsIntersecting(mapId, worldAABB, ref state,
static (EntityUid uid, MapGridComponent grid,
ref (EntityLookupSystem system,
Box2 worldAABB,
LookupFlags flags,
EntityQuery<T> query,
HashSet<Entity<T>> intersecting) tuple) =>
{
tuple.system.AddEntitiesIntersecting(uid, tuple.intersecting, tuple.worldAABB, tuple.flags, tuple.query);
return true;
}, (flags & LookupFlags.Approximate) != 0x0);
ref (EntityLookupSystem system,
Box2 worldAABB,
LookupFlags flags,
EntityQuery<T> query,
HashSet<T> intersecting) tuple) =>
{
tuple.system.AddComponentsIntersecting(uid, tuple.intersecting, tuple.worldAABB, tuple.flags, tuple.query);
return true;
}, (flags & LookupFlags.Approximate) != 0x0);
// Get map entities
var mapUid = _mapManager.GetMapEntityId(mapId);
AddEntitiesIntersecting(mapUid, entities, worldAABB, flags, query);
AddContained(entities, flags, query);
AddComponentsIntersecting(mapUid, intersecting, worldAABB, flags, query);
AddContained(intersecting, flags, query);
}
return intersecting;
}
#endregion
#region EntityCoordinates
public HashSet<T> GetComponentsInRange<T>(EntityCoordinates coordinates, float range) where T : IComponent
public HashSet<T> GetComponentsInRange<T>(EntityCoordinates coordinates, float range) where T : Component
{
var mapPos = coordinates.ToMap(EntityManager, _transform);
return GetComponentsInRange<T>(mapPos, range);
}
public void GetEntitiesInRange<T>(EntityCoordinates coordinates, float range, HashSet<Entity<T>> entities) where T : IComponent
{
var mapPos = coordinates.ToMap(EntityManager, _transform);
GetEntitiesInRange(mapPos, range, entities);
}
public HashSet<Entity<T>> GetEntitiesInRange<T>(EntityCoordinates coordinates, float range) where T : IComponent
{
var entities = new HashSet<Entity<T>>();
GetEntitiesInRange(coordinates, range, entities);
return entities;
}
#endregion
#region MapCoordinates
[Obsolete]
public HashSet<IComponent> GetComponentsInRange(Type type, MapCoordinates coordinates, float range)
public HashSet<Component> GetComponentsInRange(Type type, MapCoordinates coordinates, float range)
{
DebugTools.Assert(typeof(IComponent).IsAssignableFrom(type));
DebugTools.Assert(typeof(Component).IsAssignableFrom(type));
return GetComponentsInRange(type, coordinates.MapId, coordinates.Position, range);
}
public HashSet<Entity<IComponent>> GetEntitiesInRange(Type type, MapCoordinates coordinates, float range)
{
DebugTools.Assert(typeof(IComponent).IsAssignableFrom(type));
var entities = new HashSet<Entity<IComponent>>();
GetEntitiesInRange(type, coordinates.MapId, coordinates.Position, range, entities);
return entities;
}
public HashSet<T> GetComponentsInRange<T>(MapCoordinates coordinates, float range) where T : IComponent
public HashSet<T> GetComponentsInRange<T>(MapCoordinates coordinates, float range) where T : Component
{
return GetComponentsInRange<T>(coordinates.MapId, coordinates.Position, range);
}
public void GetEntitiesInRange<T>(MapCoordinates coordinates, float range, HashSet<Entity<T>> entities) where T : IComponent
{
GetEntitiesInRange(coordinates.MapId, coordinates.Position, range, entities);
}
public HashSet<Entity<T>> GetEntitiesInRange<T>(MapCoordinates coordinates, float range) where T : IComponent
{
var entities = new HashSet<Entity<T>>();
GetEntitiesInRange(coordinates.MapId, coordinates.Position, range, entities);
return entities;
}
#endregion
#region MapId
public bool AnyComponentsInRange(Type type, MapId mapId, Vector2 worldPos, float range)
{
DebugTools.Assert(typeof(IComponent).IsAssignableFrom(type));
DebugTools.Assert(typeof(Component).IsAssignableFrom(type));
DebugTools.Assert(range > 0, "Range must be a positive float");
if (mapId == MapId.Nullspace) return false;
@@ -491,47 +413,31 @@ public sealed partial class EntityLookupSystem
return AnyComponentsIntersecting(type, mapId, worldAABB);
}
[Obsolete]
public HashSet<IComponent> GetComponentsInRange(Type type, MapId mapId, Vector2 worldPos, float range)
public HashSet<Component> GetComponentsInRange(Type type, MapId mapId, Vector2 worldPos, float range)
{
var entities = new HashSet<Entity<IComponent>>();
GetEntitiesInRange(type, mapId, worldPos, range, entities);
return new HashSet<IComponent>(entities.Select(e => e.Comp));
}
public void GetEntitiesInRange(Type type, MapId mapId, Vector2 worldPos, float range, HashSet<Entity<IComponent>> entities)
{
DebugTools.Assert(typeof(IComponent).IsAssignableFrom(type));
DebugTools.Assert(typeof(Component).IsAssignableFrom(type));
DebugTools.Assert(range > 0, "Range must be a positive float");
if (mapId == MapId.Nullspace) return;
if (mapId == MapId.Nullspace) return new HashSet<Component>();
// TODO: Actual circles
var rangeVec = new Vector2(range, range);
var worldAABB = new Box2(worldPos - rangeVec, worldPos + rangeVec);
GetEntitiesIntersecting(type, mapId, worldAABB, entities);
return GetComponentsIntersecting(type, mapId, worldAABB);
}
[Obsolete]
public HashSet<T> GetComponentsInRange<T>(MapId mapId, Vector2 worldPos, float range) where T : IComponent
{
var entities = new HashSet<Entity<T>>();
GetEntitiesInRange(mapId, worldPos, range, entities);
return new HashSet<T>(entities.Select(e => e.Comp));
}
public void GetEntitiesInRange<T>(MapId mapId, Vector2 worldPos, float range, HashSet<Entity<T>> entities) where T : IComponent
public HashSet<T> GetComponentsInRange<T>(MapId mapId, Vector2 worldPos, float range) where T : Component
{
DebugTools.Assert(range > 0, "Range must be a positive float");
if (mapId == MapId.Nullspace) return;
if (mapId == MapId.Nullspace) return new HashSet<T>();
// TODO: Actual circles
var rangeVec = new Vector2(range, range);
var worldAABB = new Box2(worldPos - rangeVec, worldPos + rangeVec);
GetEntitiesIntersecting(mapId, worldAABB, entities);
return GetComponentsIntersecting<T>(mapId, worldAABB);
}
#endregion

View File

@@ -31,15 +31,14 @@ internal sealed class PrototypeReloadSystem : EntitySystem
if (!eventArgs.ByType.TryGetValue(typeof(EntityPrototype), out var set))
return;
var query = EntityQueryEnumerator<MetaDataComponent>();
while (query.MoveNext(out var uid, out var metadata))
foreach (var metadata in EntityQuery<MetaDataComponent>())
{
var id = metadata.EntityPrototype?.ID;
if (id == null || !set.Modified.ContainsKey(id))
continue;
var proto = _prototypes.Index<EntityPrototype>(id);
UpdateEntity(uid, metadata, proto);
UpdateEntity(metadata.Owner, metadata, proto);
}
}
@@ -78,7 +77,8 @@ internal sealed class PrototypeReloadSystem : EntitySystem
.Except(oldPrototypeComponents))
{
var data = newPrototype.Components[name];
var component = _componentFactory.GetComponent(name);
var component = (Component)_componentFactory.GetComponent(name);
component.Owner = entity;
EntityManager.AddComponent(entity, component);
}

View File

@@ -6,12 +6,12 @@ using System.Numerics;
using System.Runtime.CompilerServices;
using Robust.Shared.GameStates;
using Robust.Shared.Map;
using Robust.Shared.Physics.Components;
using Robust.Shared.Map.Components;
using Robust.Shared.Map.Enumerators;
using Robust.Shared.Map.Events;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
@@ -296,7 +296,7 @@ public abstract partial class SharedMapSystem
MapManager.SuppressOnTileChanged = false;
if (modified.Count != 0)
RaiseLocalEvent(uid, new GridModifiedEvent(uid, component, modified), true);
RaiseLocalEvent(uid, new GridModifiedEvent(component, modified), true);
}
private void OnGridGetState(EntityUid uid, MapGridComponent component, ref ComponentGetState args)

View File

@@ -1,9 +1,11 @@
using System.Collections.Generic;
using Robust.Shared.GameStates;
using JetBrains.Annotations;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Maths;
using System.Collections.Generic;
using Robust.Shared.GameStates;
using Robust.Shared.Map.Components;
using System.Linq;
using Robust.Shared.Network;
using Robust.Shared.Physics.Systems;
using Robust.Shared.Timing;
@@ -154,11 +156,6 @@ namespace Robust.Shared.GameObjects
/// </summary>
public sealed class GridModifiedEvent : EntityEventArgs
{
/// <summary>
/// The id of the grid being changed.
/// </summary>
public EntityUid GridEnt { get; }
/// <summary>
/// Grid being changed.
/// </summary>
@@ -172,9 +169,8 @@ namespace Robust.Shared.GameObjects
/// <summary>
/// Creates a new instance of this class.
/// </summary>
public GridModifiedEvent(EntityUid gridEnt, MapGridComponent grid, IReadOnlyCollection<(Vector2i position, Tile tile)> modified)
public GridModifiedEvent(MapGridComponent grid, IReadOnlyCollection<(Vector2i position, Tile tile)> modified)
{
GridEnt = gridEnt;
Grid = grid;
Modified = modified;
}

View File

@@ -25,7 +25,7 @@ namespace Robust.Shared.Map.Components
// This field is used for deserialization internally in the map loader.
// If you want to remove this, you would have to restructure the map save file.
[DataField("index")] internal int GridIndex;
[DataField("index")] internal int GridIndex = 0;
// the grid section now writes the grid's EntityUID. as long as existing maps get updated (just a load+save),
// this can be removed
@@ -75,83 +75,70 @@ namespace Robust.Shared.Map.Components
#region TileAccess
[Obsolete("Use the MapSystem method")]
public TileRef GetTileRef(MapCoordinates coords)
{
return MapSystem.GetTileRef(Owner, this, coords);
}
[Obsolete("Use the MapSystem method")]
public TileRef GetTileRef(EntityCoordinates coords)
{
return MapSystem.GetTileRef(Owner, this, coords);
}
[Obsolete("Use the MapSystem method")]
public TileRef GetTileRef(Vector2i tileCoordinates)
{
return MapSystem.GetTileRef(Owner, this, tileCoordinates);
}
[Obsolete("Use the MapSystem method")]
public IEnumerable<TileRef> GetAllTiles(bool ignoreEmpty = true)
{
return MapSystem.GetAllTiles(Owner, this, ignoreEmpty);
}
[Obsolete("Use the MapSystem method")]
public GridTileEnumerator GetAllTilesEnumerator(bool ignoreEmpty = true)
{
return MapSystem.GetAllTilesEnumerator(Owner, this, ignoreEmpty);
}
[Obsolete("Use the MapSystem method")]
public void SetTile(EntityCoordinates coords, Tile tile)
{
MapSystem.SetTile(Owner, this, coords, tile);
}
[Obsolete("Use the MapSystem method")]
public void SetTile(Vector2i gridIndices, Tile tile)
{
MapSystem.SetTile(Owner, this, gridIndices, tile);
}
[Obsolete("Use the MapSystem method")]
public void SetTiles(List<(Vector2i GridIndices, Tile Tile)> tiles)
{
MapSystem.SetTiles(Owner, this, tiles);
}
[Obsolete("Use the MapSystem method")]
public IEnumerable<TileRef> GetLocalTilesIntersecting(Box2Rotated localArea, bool ignoreEmpty = true,
Predicate<TileRef>? predicate = null)
{
return MapSystem.GetLocalTilesIntersecting(Owner, this, localArea, ignoreEmpty, predicate);
}
[Obsolete("Use the MapSystem method")]
public IEnumerable<TileRef> GetTilesIntersecting(Box2Rotated worldArea, bool ignoreEmpty = true,
Predicate<TileRef>? predicate = null)
{
return MapSystem.GetTilesIntersecting(Owner, this, worldArea, ignoreEmpty, predicate);
}
[Obsolete("Use the MapSystem method")]
public IEnumerable<TileRef> GetTilesIntersecting(Box2 worldArea, bool ignoreEmpty = true,
Predicate<TileRef>? predicate = null)
{
return MapSystem.GetTilesIntersecting(Owner, this, worldArea, ignoreEmpty, predicate);
}
[Obsolete("Use the MapSystem method")]
public IEnumerable<TileRef> GetLocalTilesIntersecting(Box2 localArea, bool ignoreEmpty = true,
Predicate<TileRef>? predicate = null)
{
return MapSystem.GetLocalTilesIntersecting(Owner, this, localArea, ignoreEmpty, predicate);
}
[Obsolete("Use the MapSystem method")]
public IEnumerable<TileRef> GetTilesIntersecting(Circle worldArea, bool ignoreEmpty = true,
Predicate<TileRef>? predicate = null)
{
@@ -162,19 +149,16 @@ namespace Robust.Shared.Map.Components
#region ChunkAccess
[Obsolete("Use the MapSystem method")]
internal bool TryGetChunk(Vector2i chunkIndices, [NotNullWhen(true)] out MapChunk? chunk)
{
return MapSystem.TryGetChunk(Owner, this, chunkIndices, out chunk);
}
[Obsolete("Use the MapSystem method")]
internal IReadOnlyDictionary<Vector2i, MapChunk> GetMapChunks()
{
return MapSystem.GetMapChunks(Owner, this);
}
[Obsolete("Use the MapSystem method")]
internal ChunkEnumerator GetMapChunks(Box2Rotated worldArea)
{
return MapSystem.GetMapChunks(Owner, this, worldArea);
@@ -184,67 +168,56 @@ namespace Robust.Shared.Map.Components
#region SnapGridAccess
[Obsolete("Use the MapSystem method")]
public IEnumerable<EntityUid> GetAnchoredEntities(MapCoordinates coords)
{
return MapSystem.GetAnchoredEntities(Owner, this, coords);
}
[Obsolete("Use the MapSystem method")]
public IEnumerable<EntityUid> GetAnchoredEntities(Vector2i pos)
{
return MapSystem.GetAnchoredEntities(Owner, this, pos);
}
[Obsolete("Use the MapSystem method")]
public AnchoredEntitiesEnumerator GetAnchoredEntitiesEnumerator(Vector2i pos)
{
return MapSystem.GetAnchoredEntitiesEnumerator(Owner, this, pos);
}
[Obsolete("Use the MapSystem method")]
public IEnumerable<EntityUid> GetLocalAnchoredEntities(Box2 localAABB)
{
return MapSystem.GetLocalAnchoredEntities(Owner, this, localAABB);
}
[Obsolete("Use the MapSystem method")]
public IEnumerable<EntityUid> GetAnchoredEntities(Box2 worldAABB)
{
return MapSystem.GetAnchoredEntities(Owner, this, worldAABB);
}
[Obsolete("Use the MapSystem method")]
public Vector2i TileIndicesFor(EntityCoordinates coords)
{
return MapSystem.TileIndicesFor(Owner, this, coords);
}
[Obsolete("Use the MapSystem method")]
public Vector2i TileIndicesFor(MapCoordinates worldPos)
{
return MapSystem.TileIndicesFor(Owner, this, worldPos);
}
[Obsolete("Use the MapSystem method")]
public IEnumerable<EntityUid> GetInDir(EntityCoordinates position, Direction dir)
{
return MapSystem.GetInDir(Owner, this, position, dir);
}
[Obsolete("Use the MapSystem method")]
public IEnumerable<EntityUid> GetLocal(EntityCoordinates coords)
{
return MapSystem.GetLocal(Owner, this, coords);
}
[Obsolete("Use the MapSystem method")]
public IEnumerable<EntityUid> GetCardinalNeighborCells(EntityCoordinates coords)
{
return MapSystem.GetCardinalNeighborCells(Owner, this, coords);
}
[Obsolete("Use the MapSystem method")]
public IEnumerable<EntityUid> GetCellsInSquareArea(EntityCoordinates coords, int n)
{
return MapSystem.GetCellsInSquareArea(Owner, this, coords, n);
@@ -252,79 +225,66 @@ namespace Robust.Shared.Map.Components
#endregion
[Obsolete("Use the MapSystem method")]
public Vector2 WorldToLocal(Vector2 posWorld)
{
return MapSystem.WorldToLocal(Owner, this, posWorld);
}
[Obsolete("Use the MapSystem method")]
public EntityCoordinates MapToGrid(MapCoordinates posWorld)
{
return MapSystem.MapToGrid(Owner, posWorld);
}
[Obsolete("Use the MapSystem method")]
public Vector2 LocalToWorld(Vector2 posLocal)
{
return MapSystem.LocalToWorld(Owner, this, posLocal);
}
[Obsolete("Use the MapSystem method")]
public Vector2i WorldToTile(Vector2 posWorld)
{
return MapSystem.WorldToTile(Owner, this, posWorld);
}
[Obsolete("Use the MapSystem method")]
public Vector2i LocalToTile(EntityCoordinates coordinates)
{
return MapSystem.LocalToTile(Owner, this, coordinates);
}
[Obsolete("Use the MapSystem method")]
public Vector2i CoordinatesToTile(EntityCoordinates coords)
{
return MapSystem.CoordinatesToTile(Owner, this, coords);
}
[Obsolete("Use the MapSystem method")]
public bool CollidesWithGrid(Vector2i indices)
{
return MapSystem.CollidesWithGrid(Owner, this, indices);
}
[Obsolete("Use the MapSystem method")]
public Vector2i GridTileToChunkIndices(Vector2i gridTile)
{
return MapSystem.GridTileToChunkIndices(Owner, this, gridTile);
}
[Obsolete("Use the MapSystem method")]
public EntityCoordinates GridTileToLocal(Vector2i gridTile)
{
return MapSystem.GridTileToLocal(Owner, this, gridTile);
}
[Obsolete("Use the MapSystem method")]
public Vector2 GridTileToWorldPos(Vector2i gridTile)
{
return MapSystem.GridTileToWorldPos(Owner, this, gridTile);
}
[Obsolete("Use the MapSystem method")]
public MapCoordinates GridTileToWorld(Vector2i gridTile)
{
return MapSystem.GridTileToWorld(Owner, this, gridTile);
}
[Obsolete("Use the MapSystem method")]
public bool TryGetTileRef(Vector2i indices, out TileRef tile)
{
return MapSystem.TryGetTileRef(Owner, this, indices, out tile);
}
[Obsolete("Use the MapSystem method")]
public bool TryGetTileRef(EntityCoordinates coords, out TileRef tile)
{
return MapSystem.TryGetTileRef(Owner, this, coords, out tile);

View File

@@ -87,21 +87,11 @@ namespace Robust.Shared.Map
MapGridComponent CreateGrid(MapId currentMapId, ushort chunkSize = 16);
MapGridComponent CreateGrid(MapId currentMapId, in GridCreateOptions options);
MapGridComponent CreateGrid(MapId currentMapId);
Entity<MapGridComponent> CreateGridEntity(MapId currentMapId, GridCreateOptions? options = null);
[Obsolete("Use GetComponent<MapGridComponent>(uid)")]
MapGridComponent GetGrid(EntityUid gridId);
[Obsolete("Use TryGetComponent(uid, out MapGridComponent? grid)")]
bool TryGetGrid([NotNullWhen(true)] EntityUid? euid, [NotNullWhen(true)] out MapGridComponent? grid);
[Obsolete("Use HasComponent<MapGridComponent>(uid)")]
bool GridExists([NotNullWhen(true)] EntityUid? euid);
IEnumerable<MapGridComponent> GetAllMapGrids(MapId mapId);
IEnumerable<Entity<MapGridComponent>> GetAllGrids(MapId mapId);
/// <summary>
/// Attempts to find the map grid under the map location.
/// </summary>
@@ -141,13 +131,10 @@ namespace Robust.Shared.Map
void FindGridsIntersecting<TState>(MapId mapId, Box2 worldAABB, ref TState state, GridCallback<TState> callback, bool approx = false, bool includeMap = true);
void FindGridsIntersecting(MapId mapId, Box2 worldAABB, ref List<Entity<MapGridComponent>> state, bool approx = false, bool includeMap = true);
void FindGridsIntersecting(MapId mapId, Box2Rotated worldBounds, GridCallback callback, bool approx = false, bool includeMap = true);
void FindGridsIntersecting<TState>(MapId mapId, Box2Rotated worldBounds, ref TState state, GridCallback<TState> callback, bool approx = false, bool includeMap = true);
void FindGridsIntersecting(MapId mapId, Box2Rotated worldBounds, ref List<Entity<MapGridComponent>> state, bool approx = false, bool includeMap = true);
/// <summary>
/// Returns the grids intersecting this AABB.

View File

@@ -1,8 +1,11 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Robust.Shared.GameObjects;
using Robust.Shared.Log;
using Robust.Shared.Map.Components;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
// All the obsolete warnings about GridId are probably useless here.
@@ -44,12 +47,6 @@ internal partial class MapManager
return CreateGrid(currentMapId, GridCreateOptions.Default);
}
public Entity<MapGridComponent> CreateGridEntity(MapId currentMapId, GridCreateOptions? options = null)
{
options ??= GridCreateOptions.Default;
return CreateGrid(currentMapId, options.Value.ChunkSize, default);
}
[Obsolete("Use GetComponent<MapGridComponent>(uid)")]
public MapGridComponent GetGrid(EntityUid gridId)
{
@@ -64,7 +61,6 @@ internal partial class MapManager
return EntityManager.HasComponent<MapGridComponent>(uid);
}
[Obsolete("Use TryGetComponent(uid, out MapGridComponent? grid)")]
public bool TryGetGrid([NotNullWhen(true)] EntityUid? euid, [MaybeNullWhen(false)] out MapGridComponent grid)
{
if (EntityManager.TryGetComponent(euid, out MapGridComponent? comp))
@@ -85,24 +81,11 @@ internal partial class MapManager
public IEnumerable<MapGridComponent> GetAllMapGrids(MapId mapId)
{
var query = EntityManager.AllEntityQueryEnumerator<MapGridComponent, TransformComponent>();
while (query.MoveNext(out var grid, out var xform))
{
if (xform.MapID != mapId)
yield return grid;
}
}
var xformQuery = EntityManager.GetEntityQuery<TransformComponent>();
public IEnumerable<Entity<MapGridComponent>> GetAllGrids(MapId mapId)
{
var query = EntityManager.AllEntityQueryEnumerator<MapGridComponent, TransformComponent>();
while (query.MoveNext(out var uid, out var grid, out var xform))
{
if (xform.MapID != mapId)
continue;
yield return (uid, grid);
}
return EntityManager.EntityQuery<MapGridComponent>(true)
.Where(c => xformQuery.GetComponent(c.Owner).MapID == mapId)
.Select(c => c);
}
public virtual void DeleteGrid(EntityUid euid)
@@ -152,7 +135,7 @@ internal partial class MapManager
EntityManager.EventBus.RaiseLocalEvent(euid, ref ev, true);
}
protected Entity<MapGridComponent> CreateGrid(MapId currentMapId, ushort chunkSize, EntityUid forcedGridEuid)
protected MapGridComponent CreateGrid(MapId currentMapId, ushort chunkSize, EntityUid forcedGridEuid)
{
var gridEnt = EntityManager.CreateEntityUninitialized(null, forcedGridEuid);
@@ -172,6 +155,6 @@ internal partial class MapManager
EntityManager.System<MetaDataSystem>().SetEntityName(gridEnt, $"grid", meta);
EntityManager.InitializeComponents(gridEnt, meta);
EntityManager.StartComponents(gridEnt);
return (gridEnt, grid);
return grid;
}
}

View File

@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Robust.Shared.GameObjects;
using Robust.Shared.Log;
using Robust.Shared.Map.Components;
using Robust.Shared.Utility;
@@ -209,21 +211,22 @@ internal partial class MapManager
if (actualId != MapId.Nullspace) // nullspace isn't bound to an entity
{
Entity<MapComponent> result = default;
var query = EntityManager.AllEntityQueryEnumerator<MapComponent>();
while (query.MoveNext(out var uid, out var map))
var mapComps = EntityManager.EntityQuery<MapComponent>(true);
MapComponent? result = null;
foreach (var mapComp in mapComps)
{
if (map.MapId != actualId)
if (mapComp.MapId != actualId)
continue;
result = (uid, map);
result = mapComp;
break;
}
if (result != default)
if (result != null)
{
DebugTools.Assert(mapId != null);
_mapEntities.Add(actualId, result);
_mapEntities.Add(actualId, result.Owner);
_sawmill.Debug($"Rebinding map {actualId} to entity {result.Owner}");
}
else

View File

@@ -96,17 +96,6 @@ internal partial class MapManager
state = state2.state;
}
public void FindGridsIntersecting(MapId mapId, Box2 worldAABB, ref List<Entity<MapGridComponent>> state,
bool approx = false, bool includeMap = true)
{
FindGridsIntersecting(mapId, worldAABB, ref state, static (EntityUid uid, MapGridComponent grid,
ref List<Entity<MapGridComponent>> list) =>
{
list.Add((uid, grid));
return true;
}, approx, includeMap);
}
public void FindGridsIntersecting(MapId mapId, Box2Rotated worldBounds, GridCallback callback, bool approx = false,
bool includeMap = true)
{
@@ -119,17 +108,6 @@ internal partial class MapManager
FindGridsIntersecting(mapId, worldBounds.CalcBoundingBox(), ref state, callback, approx, includeMap);
}
public void FindGridsIntersecting(MapId mapId, Box2Rotated worldBounds, ref List<Entity<MapGridComponent>> state,
bool approx = false, bool includeMap = true)
{
FindGridsIntersecting(mapId, worldBounds, ref state, static (EntityUid uid, MapGridComponent grid,
ref List<Entity<MapGridComponent>> list) =>
{
list.Add((uid, grid));
return true;
}, approx, includeMap);
}
private bool IsIntersecting(
Box2 aabb,
EntityUid gridUid,

View File

@@ -1,5 +1,5 @@
using System;
using Robust.Shared.GameObjects;
using System;
namespace Robust.Shared.Physics;
@@ -9,7 +9,7 @@ namespace Robust.Shared.Physics;
/// overriden, such that we can remove entries without needing to fetch the transform component of a possible
/// deleted entity.
/// </summary>
public readonly struct ComponentTreeEntry<T> : IEquatable<ComponentTreeEntry<T>>, IComparable<ComponentTreeEntry<T>> where T : IComponent
public readonly struct ComponentTreeEntry<T> : IEquatable<ComponentTreeEntry<T>>, IComparable<ComponentTreeEntry<T>> where T : Component
{
public T Component { get; init; }
public TransformComponent Transform { get; init; }

View File

@@ -9,9 +9,9 @@ namespace Robust.Shared.Physics.Events
[ByRefEvent]
public readonly struct CollisionLayerChangeEvent
{
public readonly Entity<PhysicsComponent> Body;
public readonly PhysicsComponent Body;
public CollisionLayerChangeEvent(Entity<PhysicsComponent> body)
public CollisionLayerChangeEvent(PhysicsComponent body)
{
Body = body;
}

View File

@@ -5,6 +5,7 @@ using Robust.Shared.Collections;
using Robust.Shared.GameObjects;
using Robust.Shared.GameStates;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Physics.Collision.Shapes;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Dynamics;
@@ -353,7 +354,7 @@ namespace Robust.Shared.Physics.Systems
if (oldLayer != layer)
{
var ev = new CollisionLayerChangeEvent((uid, body));
var ev = new CollisionLayerChangeEvent(body);
RaiseLocalEvent(ref ev);
}

View File

@@ -26,7 +26,7 @@ public abstract partial class SharedJointSystem : EntitySystem
// To avoid issues with component states we'll queue up all dirty joints and check it every tick to see if
// we can delete the component.
private readonly HashSet<Entity<JointComponent>> _dirtyJoints = new();
private readonly HashSet<JointComponent> _dirtyJoints = new();
protected readonly HashSet<Joint> AddedJoints = new();
protected readonly List<Joint> ToRemove = new();
@@ -115,8 +115,8 @@ public abstract partial class SharedJointSystem : EntitySystem
foreach (var joint in _dirtyJoints)
{
if (joint.Comp.Deleted || joint.Comp.JointCount != 0) continue;
EntityManager.RemoveComponent<JointComponent>(joint);
if (joint.Deleted || joint.JointCount != 0) continue;
EntityManager.RemoveComponent<JointComponent>(joint.Owner);
}
_dirtyJoints.Clear();
@@ -139,8 +139,7 @@ public abstract partial class SharedJointSystem : EntitySystem
jointComponentA ??= EnsureComp<JointComponent>(aUid);
jointComponentB ??= EnsureComp<JointComponent>(bUid);
DebugTools.AssertOwner(aUid, jointComponentA);
DebugTools.AssertOwner(bUid, jointComponentB);
DebugTools.Assert(jointComponentA.Owner == aUid && jointComponentB.Owner == bUid);
DebugTools.AssertNotEqual(jointComponentA.Relay, bUid);
DebugTools.AssertNotEqual(jointComponentB.Relay, aUid);
@@ -199,8 +198,8 @@ public abstract partial class SharedJointSystem : EntitySystem
Dirty(bUid, jointComponentB);
// Also flag these for checking juusssttt in case.
_dirtyJoints.Add((aUid, jointComponentA));
_dirtyJoints.Add((bUid, jointComponentB));
_dirtyJoints.Add(jointComponentA);
_dirtyJoints.Add(jointComponentB);
// Note: creating a joint doesn't wake the bodies.
// Raise broadcast last so we can do both sides of directed first.
@@ -523,12 +522,12 @@ public abstract partial class SharedJointSystem : EntitySystem
// Originally I logged these but because of prediction the client can just nuke them multiple times in a row
// because each body has its own JointComponent, bleh.
if (!TryComp<JointComponent>(bodyAUid, out var jointComponentA))
if (!EntityManager.TryGetComponent<JointComponent>(bodyAUid, out var jointComponentA))
{
return;
}
if (!TryComp<JointComponent>(bodyBUid, out var jointComponentB))
if (!EntityManager.TryGetComponent<JointComponent>(bodyBUid, out var jointComponentB))
{
return;
}
@@ -560,12 +559,12 @@ public abstract partial class SharedJointSystem : EntitySystem
if (!jointComponentA.Deleted)
{
Dirty(bodyAUid, jointComponentA);
Dirty(jointComponentA);
}
if (!jointComponentB.Deleted)
{
Dirty(bodyBUid, jointComponentB);
Dirty(jointComponentB);
}
if (jointComponentA.Deleted && jointComponentB.Deleted)
@@ -600,8 +599,8 @@ public abstract partial class SharedJointSystem : EntitySystem
}
// We can't just check up front due to how prediction works.
_dirtyJoints.Add((bodyAUid, jointComponentA));
_dirtyJoints.Add((bodyBUid, jointComponentB));
_dirtyJoints.Add(jointComponentA);
_dirtyJoints.Add(jointComponentB);
}
#endregion

View File

@@ -22,7 +22,6 @@
* PhysicsComponent is heavily modified from Box2D.
*/
using System;
using System.Numerics;
using Robust.Shared.GameObjects;
using Robust.Shared.GameStates;
@@ -372,16 +371,8 @@ public partial class SharedPhysicsSystem
Dirty(body);
}
[Obsolete("Use SetAwake with EntityUid<PhysicsComponent>")]
public void SetAwake(EntityUid uid, PhysicsComponent body, bool value, bool updateSleepTime = true)
{
SetAwake(new Entity<PhysicsComponent>(uid, body), value, updateSleepTime);
}
public void SetAwake(Entity<PhysicsComponent> ent, bool value, bool updateSleepTime = true)
{
var uid = ent.Owner;
var body = ent.Comp;
if (body.Awake == value)
return;
@@ -405,7 +396,7 @@ public partial class SharedPhysicsSystem
if (updateSleepTime)
SetSleepTime(body, 0);
Dirty(ent);
Dirty(body);
}
public void TrySetBodyType(EntityUid uid, BodyType value, FixturesComponent? manager = null, PhysicsComponent? body = null, TransformComponent? xform = null)

View File

@@ -150,12 +150,11 @@ namespace Robust.Shared.Physics.Systems
/// <summary>
/// Get all entities colliding with a certain body.
/// </summary>
public IEnumerable<Entity<PhysicsComponent>> GetCollidingEntities(MapId mapId, in Box2Rotated worldBounds)
public IEnumerable<PhysicsComponent> GetCollidingEntities(MapId mapId, in Box2Rotated worldBounds)
{
if (mapId == MapId.Nullspace)
return Array.Empty<Entity<PhysicsComponent>>();
if (mapId == MapId.Nullspace) return Array.Empty<PhysicsComponent>();
var bodies = new HashSet<Entity<PhysicsComponent>>();
var bodies = new HashSet<PhysicsComponent>();
foreach (var (uid, broadphase) in _broadphase.GetBroadphases(mapId, worldBounds.CalcBoundingBox()))
{
@@ -163,12 +162,12 @@ namespace Robust.Shared.Physics.Systems
foreach (var proxy in broadphase.StaticTree.QueryAabb(gridAABB, false))
{
bodies.Add(new Entity<PhysicsComponent>(proxy.Entity, proxy.Body));
bodies.Add(proxy.Body);
}
foreach (var proxy in broadphase.DynamicTree.QueryAabb(gridAABB, false))
{
bodies.Add(new Entity<PhysicsComponent>(proxy.Entity, proxy.Body));
bodies.Add(proxy.Body);
}
}

View File

@@ -11,6 +11,7 @@ using Robust.Shared.Serialization.Manager;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Serialization.Markdown.Mapping;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Array;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype.Set;
using Robust.Shared.ViewVariables;
namespace Robust.Shared.Prototypes
@@ -249,7 +250,8 @@ namespace Robust.Shared.Prototypes
if (!entityManager.TryGetComponent(entity, compReg.Idx, out var component))
{
var newComponent = factory.GetComponent(compName);
var newComponent = (Component) factory.GetComponent(compName);
newComponent.Owner = entity;
entityManager.AddComponent(entity, newComponent);
component = newComponent;
}

View File

@@ -19,7 +19,7 @@
<PackageReference Include="Linguini.Bundle" Version="0.1.3" />
<PackageReference Include="SharpZstd.Interop" Version="1.5.2-beta2" PrivateAssets="compile" />
<PackageReference Include="SpaceWizards.Sodium" Version="0.2.1" PrivateAssets="compile" />
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.3" />
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.7" />
<PackageReference Include="TerraFX.Interop.Windows" Version="10.0.20348-rc2" PrivateAssets="compile" />
</ItemGroup>
<ItemGroup>

View File

@@ -28,7 +28,7 @@ internal sealed class CompCommand : ToolshedCommand
[CommandImplementation("add")]
public EntityUid Add<T>([PipedArgument] EntityUid input)
where T: IComponent, new()
where T: Component, new()
{
AddComp<T>(input);
return input;
@@ -36,13 +36,13 @@ internal sealed class CompCommand : ToolshedCommand
[CommandImplementation("add")]
public IEnumerable<EntityUid> Add<T>([PipedArgument] IEnumerable<EntityUid> input)
where T : IComponent, new()
where T : Component, new()
=> input.Select(Add<T>);
[CommandImplementation("rm")]
public EntityUid Rm<T>([PipedArgument] EntityUid input)
where T: IComponent, new()
where T: Component, new()
{
RemComp<T>(input);
return input;
@@ -50,12 +50,12 @@ internal sealed class CompCommand : ToolshedCommand
[CommandImplementation("rm")]
public IEnumerable<EntityUid> Rm<T>([PipedArgument] IEnumerable<EntityUid> input)
where T : IComponent, new()
where T : Component, new()
=> input.Select(Rm<T>);
[CommandImplementation("ensure")]
public EntityUid Ensure<T>([PipedArgument] EntityUid input)
where T: IComponent, new()
where T: Component, new()
{
EnsureComp<T>(input);
return input;
@@ -63,7 +63,7 @@ internal sealed class CompCommand : ToolshedCommand
[CommandImplementation("ensure")]
public IEnumerable<EntityUid> Ensure<T>([PipedArgument] IEnumerable<EntityUid> input)
where T : IComponent, new()
where T : Component, new()
=> input.Select(Ensure<T>);
[CommandImplementation("has")]

View File

@@ -126,7 +126,7 @@ public abstract partial class ToolshedCommand
/// </summary>
[PublicAPI, MethodImpl(MethodImplOptions.AggressiveInlining)]
protected T AddComp<T>(EntityUid entity)
where T : IComponent, new()
where T : Component, new()
=> EntityManager.AddComponent<T>(entity);
/// <summary>
@@ -142,7 +142,7 @@ public abstract partial class ToolshedCommand
/// </summary>
[PublicAPI, MethodImpl(MethodImplOptions.AggressiveInlining)]
protected T EnsureComp<T>(EntityUid entity)
where T: IComponent, new()
where T: Component, new()
=> EntityManager.EnsureComponent<T>(entity);
/// <summary>
@@ -159,6 +159,6 @@ public abstract partial class ToolshedCommand
/// </summary>
[PublicAPI, MethodImpl(MethodImplOptions.AggressiveInlining)]
protected EntityQuery<T> GetEntityQuery<T>()
where T : IComponent
where T : Component
=> EntityManager.GetEntityQuery<T>();
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Data;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
@@ -97,9 +98,7 @@ namespace Robust.Shared.Utility
// Whenever .owner is removed this will need to be replaced by something.
// As long as components are just reference types, we could just get the component and check if the references are equal?
#pragma warning disable CS0618 // Type or member is obsolete
if (component.Owner != uid)
#pragma warning restore CS0618 // Type or member is obsolete
throw new DebugAssertException($"Entity {uid} is not the owner of the component. Component: {component.GetType().Name}");
}

View File

@@ -34,7 +34,7 @@ internal abstract partial class ViewVariablesManager
|| !_entMan.TryGetComponent(uid, registration.Idx, out var component))
return null;
return new ViewVariablesComponentPath(component, uid);
return new ViewVariablesComponentPath((Component) component, uid);
}
private IEnumerable<string> EntityComponentList(EntityUid uid)

View File

@@ -263,11 +263,11 @@ public sealed class ViewVariablesInstancePath : ViewVariablesPath
public sealed class ViewVariablesComponentPath : ViewVariablesPath
{
public readonly IComponent Component;
public readonly Component Component;
public readonly EntityUid Owner;
public override Type Type => Component?.GetType() ?? typeof(void);
public ViewVariablesComponentPath(IComponent component, EntityUid owner)
public ViewVariablesComponentPath(Component component, EntityUid owner)
{
Component = component;
Owner = owner;

View File

@@ -26,10 +26,10 @@ namespace Robust.UnitTesting.Client.GameObjects.Components
mapManager.CreateMap(TestMapId);
// Adds two grids to use in tests.
var gridA = mapManager.CreateGridEntity(TestMapId);
var gridB = mapManager.CreateGridEntity(TestMapId);
var gridA = mapManager.CreateGrid(TestMapId);
var gridB = mapManager.CreateGrid(TestMapId);
return (sim, gridA, gridB);
return (sim, gridA.Owner, gridB.Owner);
}
/// <summary>
@@ -47,18 +47,18 @@ namespace Robust.UnitTesting.Client.GameObjects.Components
var gridB = mapMan.GetGrid(gridIdB);
// Arrange
var initialPos = new EntityCoordinates(gridIdA, new Vector2(0, 0));
var initialPos = new EntityCoordinates(gridA.Owner, new Vector2(0, 0));
var parent = entMan.SpawnEntity(null, initialPos);
var child = entMan.SpawnEntity(null, initialPos);
var parentTrans = entMan.GetComponent<TransformComponent>(parent);
var childTrans = entMan.GetComponent<TransformComponent>(child);
ComponentHandleState handleState;
var compState = new TransformComponentState(new Vector2(5, 5), new Angle(0), entMan.GetNetEntity(gridIdB), false, false);
var compState = new TransformComponentState(new Vector2(5, 5), new Angle(0), entMan.GetNetEntity(gridB.Owner), false, false);
handleState = new ComponentHandleState(compState, null);
xformSystem.OnHandleState(parent, parentTrans, ref handleState);
compState = new TransformComponentState(new Vector2(6, 6), new Angle(0), entMan.GetNetEntity(gridIdB), false, false);
compState = new TransformComponentState(new Vector2(6, 6), new Angle(0), entMan.GetNetEntity(gridB.Owner), false, false);
handleState = new ComponentHandleState(compState, null);
xformSystem.OnHandleState(child, childTrans, ref handleState);
// World pos should be 6, 6 now.
@@ -90,7 +90,7 @@ namespace Robust.UnitTesting.Client.GameObjects.Components
var gridB = mapMan.GetGrid(gridIdB);
// Arrange
var initalPos = new EntityCoordinates(gridIdA, new Vector2(0, 0));
var initalPos = new EntityCoordinates(gridA.Owner, new Vector2(0, 0));
var node1 = entMan.SpawnEntity(null, initalPos);
var node2 = entMan.SpawnEntity(null, initalPos);
var node3 = entMan.SpawnEntity(null, initalPos);
@@ -103,7 +103,7 @@ namespace Robust.UnitTesting.Client.GameObjects.Components
var node2Trans = entMan.GetComponent<TransformComponent>(node2);
var node3Trans = entMan.GetComponent<TransformComponent>(node3);
var compState = new TransformComponentState(new Vector2(6, 6), Angle.FromDegrees(135), entMan.GetNetEntity(gridIdB), false, false);
var compState = new TransformComponentState(new Vector2(6, 6), Angle.FromDegrees(135), entMan.GetNetEntity(gridB.Owner), false, false);
var handleState = new ComponentHandleState(compState, null);
xformSystem.OnHandleState(node1, node1Trans, ref handleState);

View File

@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using JetBrains.Annotations;
using NUnit.Framework;
using Robust.Server.Containers;
using Robust.Shared.Containers;
@@ -193,7 +195,7 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
var sim = SimulationFactory();
var containerSys = sim.Resolve<IEntitySystemManager>().GetEntitySystem<ContainerSystem>();
var grid = sim.Resolve<IMapManager>().CreateGridEntity(new MapId(1)).Owner;
var grid = sim.Resolve<IMapManager>().CreateGrid(new MapId(1)).Owner;
var entity = sim.SpawnEntity(null, new EntityCoordinates(new EntityUid(1), new Vector2(0, 0)));
var container = containerSys.MakeContainer<Container>(entity, "dummy");

View File

@@ -1,12 +1,17 @@
using System.IO;
using System.Numerics;
using System.Reflection;
using Moq;
using NUnit.Framework;
using Robust.Server.Containers;
using Robust.Server.GameObjects;
using Robust.Server.Physics;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
using Robust.Shared.Prototypes;
using Robust.Shared.Serialization.Manager;
using Robust.Shared.Timing;
@@ -35,9 +40,9 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
";
private MapId MapA;
private Entity<MapGridComponent> GridA = default!;
private MapGridComponent GridA = default!;
private MapId MapB;
private Entity<MapGridComponent> GridB = default!;
private MapGridComponent GridB = default!;
private static readonly EntityCoordinates InitialPos = new(new EntityUid(1), new Vector2(0, 0));
@@ -58,10 +63,10 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
// build the net dream
MapA = MapManager.CreateMap();
GridA = MapManager.CreateGridEntity(MapA);
GridA = MapManager.CreateGrid(MapA);
MapB = MapManager.CreateMap();
GridB = MapManager.CreateGridEntity(MapB);
GridB = MapManager.CreateGrid(MapB);
//NOTE: The grids have not moved, so we can assert worldpos == localpos for the test
}
@@ -84,8 +89,8 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
var childTrans = EntityManager.GetComponent<TransformComponent>(child);
// that are not on the same map
parentTrans.Coordinates = new EntityCoordinates(GridA, new Vector2(5, 5));
childTrans.Coordinates = new EntityCoordinates(GridB, new Vector2(4, 4));
parentTrans.Coordinates = new EntityCoordinates(GridA.Owner, new Vector2(5, 5));
childTrans.Coordinates = new EntityCoordinates(GridB.Owner, new Vector2(4, 4));
// if they are parented, the child keeps its world position, but moves to the parents map
childTrans.AttachParent(parentTrans);
@@ -95,7 +100,7 @@ namespace Robust.UnitTesting.Server.GameObjects.Components
{
Assert.That(childTrans.MapID, Is.EqualTo(parentTrans.MapID));
Assert.That(childTrans.GridUid, Is.EqualTo(parentTrans.GridUid));
Assert.That(childTrans.Coordinates, Is.EqualTo(new EntityCoordinates(parent, new Vector2(-1, -1))));
Assert.That(childTrans.Coordinates, Is.EqualTo(new EntityCoordinates(parentTrans.Owner, new Vector2(-1, -1))));
Assert.That(childTrans.WorldPosition, Is.EqualTo(new Vector2(4, 4)));
});

View File

@@ -54,8 +54,8 @@ public sealed class PvsSystemTests : RobustIntegrationTest
{
var mapId = mapMan.CreateMap();
map = mapMan.GetMapEntityId(mapId);
var gridComp = mapMan.CreateGridEntity(mapId);
gridComp.Comp.SetTile(Vector2i.Zero, new Tile(1));
var gridComp = mapMan.CreateGrid(mapId);
gridComp.SetTile(Vector2i.Zero, new Tile(1));
grid = gridComp.Owner;
});

View File

@@ -44,10 +44,10 @@ namespace Robust.UnitTesting.Shared
var mapManager = server.Resolve<IMapManager>();
var mapId = mapManager.CreateMap();
var grid = mapManager.CreateGridEntity(mapId);
var grid = mapManager.CreateGrid(mapId);
var theMapSpotBeingUsed = new Box2(Vector2.Zero, Vector2.One);
grid.Comp.SetTile(new Vector2i(), new Tile(1));
grid.SetTile(new Vector2i(), new Tile(1));
Assert.That(lookup.GetEntitiesIntersecting(mapId, theMapSpotBeingUsed).ToList().Count, Is.EqualTo(0));
@@ -66,7 +66,7 @@ namespace Robust.UnitTesting.Shared
Assert.That(lookup.GetEntitiesIntersecting(mapId, theMapSpotBeingUsed).ToList().Count, Is.EqualTo(1));
entManager.DeleteEntity(dummy);
mapManager.DeleteGrid(grid);
mapManager.DeleteGrid(grid.Owner);
mapManager.DeleteMap(mapId);
}
}

View File

@@ -8,6 +8,7 @@ using Robust.Server.GameObjects;
using Robust.Server.Player;
using Robust.Shared.Containers;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Network;
using Robust.Shared.Timing;
@@ -41,6 +42,7 @@ namespace Robust.UnitTesting.Shared.GameObjects
Assert.DoesNotThrow(() => client.SetConnectTarget(server));
client.Post(() =>
{
clientNetManager.ClientConnect(null!, 0, null!);
});
@@ -56,18 +58,16 @@ namespace Robust.UnitTesting.Shared.GameObjects
EntityUid entityUid = default!;
var cContainerSys = cEntManager.System<ContainerSystem>();
var sContainerSys = sEntManager.System<SharedContainerSystem>();
var sMetadataSys = sEntManager.System<MetaDataSystem>();
await server.WaitAssertion(() =>
{
var containerSys = sEntManager.System<SharedContainerSystem>();
mapId = sMapManager.CreateMap();
mapPos = new MapCoordinates(new Vector2(0, 0), mapId);
entityUid = sEntManager.SpawnEntity(null, mapPos);
sMetadataSys.SetEntityName(entityUid, "Container");
sContainerSys.EnsureContainer<Container>(entityUid, "dummy");
sEntManager.GetComponent<MetaDataComponent>(entityUid).EntityName = "Container";
containerSys.EnsureContainer<Container>(entityUid, "dummy");
// Setup PVS
sEntManager.AddComponent<EyeComponent>(entityUid);
@@ -85,9 +85,11 @@ namespace Robust.UnitTesting.Shared.GameObjects
EntityUid itemUid = default!;
await server.WaitAssertion(() =>
{
var containerSys = sEntManager.System<SharedContainerSystem>();
itemUid = sEntManager.SpawnEntity(null, mapPos);
sMetadataSys.SetEntityName(itemUid, "Item");
var container = sContainerSys.EnsureContainer<Container>(entityUid, "dummy");
sEntManager.GetComponent<MetaDataComponent>(itemUid).EntityName = "Item";
var container = containerSys.EnsureContainer<Container>(entityUid, "dummy");
Assert.That(container.Insert(itemUid));
// Move item out of PVS so that it doesn't get sent to the client
@@ -112,8 +114,9 @@ namespace Robust.UnitTesting.Shared.GameObjects
Assert.That(container.ContainedEntities.Count, Is.EqualTo(0));
Assert.That(container.ExpectedEntities.Count, Is.EqualTo(1));
Assert.That(cContainerSys.ExpectedEntities.ContainsKey(sEntManager.GetNetEntity(itemUid)));
Assert.That(cContainerSys.ExpectedEntities.Count, Is.EqualTo(1));
var containerSystem = cEntManager.System<ContainerSystem>();
Assert.That(containerSystem.ExpectedEntities.ContainsKey(sEntManager.GetNetEntity(itemUid)));
Assert.That(containerSystem.ExpectedEntities.Count, Is.EqualTo(1));
});
await server.WaitAssertion(() =>
@@ -137,8 +140,9 @@ namespace Robust.UnitTesting.Shared.GameObjects
Assert.That(container.ContainedEntities.Count, Is.EqualTo(1));
Assert.That(container.ExpectedEntities.Count, Is.EqualTo(0));
Assert.That(!cContainerSys.ExpectedEntities.ContainsKey(sEntManager.GetNetEntity(itemUid)));
Assert.That(cContainerSys.ExpectedEntities, Is.Empty);
var containerSystem = cEntManager.System<ContainerSystem>();
Assert.That(!containerSystem.ExpectedEntities.ContainsKey(sEntManager.GetNetEntity(itemUid)));
Assert.That(containerSystem.ExpectedEntities, Is.Empty);
});
}
@@ -184,18 +188,16 @@ namespace Robust.UnitTesting.Shared.GameObjects
EntityUid sItemUid = default!;
NetEntity netEnt = default;
var cContainerSys = cEntManager.System<ContainerSystem>();
var sContainerSys = sEntManager.System<SharedContainerSystem>();
var sMetadataSys = sEntManager.System<MetaDataSystem>();
await server.WaitAssertion(() =>
{
var containerSys = sEntManager.System<SharedContainerSystem>();
mapId = sMapManager.CreateMap();
mapPos = new MapCoordinates(new Vector2(0, 0), mapId);
sEntityUid = sEntManager.SpawnEntity(null, mapPos);
sMetadataSys.SetEntityName(sEntityUid, "Container");
sContainerSys.EnsureContainer<Container>(sEntityUid, "dummy");
sEntManager.GetComponent<MetaDataComponent>(sEntityUid).EntityName = "Container";
containerSys.EnsureContainer<Container>(sEntityUid, "dummy");
// Setup PVS
sEntManager.AddComponent<EyeComponent>(sEntityUid);
@@ -212,10 +214,12 @@ namespace Robust.UnitTesting.Shared.GameObjects
await server.WaitAssertion(() =>
{
var containerSys = sEntManager.System<SharedContainerSystem>();
sItemUid = sEntManager.SpawnEntity(null, mapPos);
netEnt = sEntManager.GetNetEntity(sItemUid);
sMetadataSys.SetEntityName(sItemUid, "Item");
var container = sContainerSys.GetContainer(sEntityUid, "dummy");
sEntManager.GetComponent<MetaDataComponent>(sItemUid).EntityName = "Item";
var container = containerSys.GetContainer(sEntityUid, "dummy");
container.Insert(sItemUid);
// Move item out of PVS so that it doesn't get sent to the client
@@ -243,17 +247,20 @@ namespace Robust.UnitTesting.Shared.GameObjects
Assert.That(container.ContainedEntities.Count, Is.EqualTo(0));
Assert.That(container.ExpectedEntities.Count, Is.EqualTo(1));
Assert.That(cContainerSys.ExpectedEntities.ContainsKey(netEnt));
Assert.That(cContainerSys.ExpectedEntities.Count, Is.EqualTo(1));
var containerSystem = cEntManager.System<ContainerSystem>();
Assert.That(containerSystem.ExpectedEntities.ContainsKey(netEnt));
Assert.That(containerSystem.ExpectedEntities.Count, Is.EqualTo(1));
});
await server.WaitAssertion(() =>
{
var containerSystem = sEntManager.System<SharedContainerSystem>();
// If possible it'd be best to only have the DeleteEntity, but right now
// the entity deleted event is not played on the client if the entity does not exist on the client.
if (sEntManager.EntityExists(sItemUid)
// && itemUid.TryGetContainer(out var container))
&& sContainerSys.TryGetContainingContainer(sItemUid, out var container))
&& containerSystem.TryGetContainingContainer(sItemUid, out var container))
{
container.ForceRemove(sItemUid);
}
@@ -276,8 +283,9 @@ namespace Robust.UnitTesting.Shared.GameObjects
Assert.That(container.ContainedEntities.Count, Is.EqualTo(0));
Assert.That(container.ExpectedEntities.Count, Is.EqualTo(0));
Assert.That(!cContainerSys.ExpectedEntities.ContainsKey(netEnt));
Assert.That(cContainerSys.ExpectedEntities.Count, Is.EqualTo(0));
var containerSystem = cEntManager.System<ContainerSystem>();
Assert.That(!containerSystem.ExpectedEntities.ContainsKey(netEnt));
Assert.That(containerSystem.ExpectedEntities.Count, Is.EqualTo(0));
});
}
@@ -294,22 +302,22 @@ namespace Robust.UnitTesting.Shared.GameObjects
var sEntManager = server.ResolveDependency<IEntityManager>();
var mapManager = server.ResolveDependency<IMapManager>();
var sContainerSys = sEntManager.System<SharedContainerSystem>();
var sMetadataSys = sEntManager.System<MetaDataSystem>();
await server.WaitAssertion(() =>
{
var containerSys = sEntManager.EntitySysManager.GetEntitySystem<Robust.Server.Containers.ContainerSystem>();
// build the map
var mapIdOne = mapManager.CreateMap();
Assert.That(mapManager.IsMapInitialized(mapIdOne), Is.True);
var containerEnt = sEntManager.SpawnEntity(null, new MapCoordinates(1, 1, mapIdOne));
sMetadataSys.SetEntityName(containerEnt, "ContainerEnt");
sEntManager.GetComponent<MetaDataComponent>(containerEnt).EntityName = "ContainerEnt";
var containeeEnt = sEntManager.SpawnEntity(null, new MapCoordinates(2, 2, mapIdOne));
sMetadataSys.SetEntityName(containeeEnt, "ContaineeEnt");
sEntManager.GetComponent<MetaDataComponent>(containeeEnt).EntityName = "ContaineeEnt";
var container = sContainerSys.MakeContainer<Container>(containerEnt, "testContainer");
var container = containerSys.MakeContainer<Container>(containerEnt, "testContainer");
container.OccludesLight = true;
container.ShowContents = true;
container.Insert(containeeEnt);
@@ -339,21 +347,15 @@ namespace Robust.UnitTesting.Shared.GameObjects
await server.WaitAssertion(() =>
{
// verify container
Entity<ContainerManagerComponent> container = default;
var query = sEntManager.EntityQueryEnumerator<ContainerManagerComponent>();
while (query.MoveNext(out var uid, out var containerComp))
{
container = (uid, containerComp);
}
var containerEnt = container.Owner;
Assert.NotNull(container.Comp);
var containerQuery = sEntManager.EntityQuery<ContainerManagerComponent>();
var containerComp = containerQuery.First();
var containerEnt = containerComp.Owner;
Assert.That(sEntManager.GetComponent<MetaDataComponent>(containerEnt).EntityName, Is.EqualTo("ContainerEnt"));
Assert.That(container.Comp!.Containers.ContainsKey("testContainer"));
Assert.That(containerComp.Containers.ContainsKey("testContainer"));
var baseContainer = container.Comp.GetContainer("testContainer");
var baseContainer = containerComp.GetContainer("testContainer");
Assert.That(baseContainer.ContainedEntities, Has.Count.EqualTo(1));
var containeeEnt = baseContainer.ContainedEntities[0];

View File

@@ -1,3 +1,4 @@
using System;
using NUnit.Framework;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
@@ -50,6 +51,24 @@ namespace Robust.UnitTesting.Shared.GameObjects
}
}
[Test]
public void SubscriptionNoMixedRefValueDirectedEvent()
{
// Arrange.
var simulation = RobustServerSimulation
.NewSimulation()
.RegisterComponents(factory =>
{
factory.RegisterClass<DummyComponent>();
factory.RegisterClass<DummyTwoComponent>();
})
.RegisterEntitySystems(factory =>
factory.LoadExtraSystemType<SubscriptionNoMixedRefValueDirectedEventSystem>());
// Act. No mixed ref and value subscriptions are allowed.
Assert.Throws(typeof(InvalidOperationException), () => simulation.InitializeInstance());
}
[Reflect(false)]
private sealed class SubscriptionNoMixedRefValueDirectedEventSystem : EntitySystem
{

View File

@@ -1,120 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Robust.UnitTesting.Shared.GameObjects;
public sealed class GenericEntityPrint
{
// [Test]
public void Print()
{
// Using the test framework for things it was not meant for is my passion
var i = 8;
IEnumerable<string> Generics(int n, bool nullable)
{
for (var j = 1; j <= n; j++)
{
var jStr = n == 1 ? string.Empty : j.ToString();
yield return $"T{jStr}{(nullable ? "?" : string.Empty)}";
}
}
var structs = new StringBuilder();
var constraints = new StringBuilder();
var fields = new StringBuilder();
var parameters = new StringBuilder();
var asserts = new StringBuilder();
var assignments = new StringBuilder();
var tupleParameters = new StringBuilder();
var tupleAccess = new StringBuilder();
var defaults = new StringBuilder();
var compOperators = new StringBuilder();
var deConstructorParameters = new StringBuilder();
var deConstructorAccess = new StringBuilder();
for (var j = 1; j <= i; j++)
{
constraints.Clear();
fields.Clear();
parameters.Clear();
asserts.Clear();
assignments.Clear();
tupleParameters.Clear();
tupleAccess.Clear();
defaults.Clear();
compOperators.Clear();
deConstructorParameters.Clear();
deConstructorAccess.Clear();
var generics = string.Join(", ", Generics(j, false));
var nullableGenerics = string.Join(", ", Generics(j, true));
for (var k = 1; k <= j; k++)
{
var kStr = j == 1 ? string.Empty : k.ToString();
fields.AppendLine($" public T{kStr} Comp{kStr};");
constraints.Append($"where T{kStr} : IComponent? ");
parameters.Append($", T{kStr} comp{kStr}");
asserts.AppendLine($" DebugTools.AssertOwner(owner, comp{kStr});");
assignments.AppendLine($" Comp{kStr} = comp{kStr};");
tupleParameters.Append($", T{kStr} Comp{kStr}");
tupleAccess.Append($", tuple.Comp{kStr}");
defaults.Append(", default");
compOperators.AppendLine($$"""
public static implicit operator T{{kStr}}(Entity<{{generics}}> ent)
{
return ent.Comp{{kStr}};
}
""");
deConstructorParameters.Append($", out T{kStr} comp{kStr}");
deConstructorAccess.AppendLine($" comp{kStr} = Comp{kStr};");
}
structs.Append($$"""
public record struct Entity<{{generics}}>
{{constraints.ToString().TrimEnd()}}
{
public EntityUid Owner;
{{fields.ToString().TrimEnd()}}
public Entity(EntityUid owner{{parameters}})
{
{{asserts}}
Owner = owner;
{{assignments.ToString().TrimEnd()}}
}
public static implicit operator Entity<{{generics}}>((EntityUid Owner{{tupleParameters}}) tuple)
{
return new Entity<{{generics}}>(tuple.Owner{{tupleAccess}});
}
public static implicit operator Entity<{{nullableGenerics}}>(EntityUid owner)
{
return new Entity<{{nullableGenerics}}>(owner{{defaults}});
}
public static implicit operator EntityUid(Entity<{{generics}}> ent)
{
return ent.Owner;
}
{{compOperators.ToString().TrimEnd()}}
public readonly void Deconstruct(out EntityUid owner{{deConstructorParameters}})
{
owner = Owner;
{{deConstructorAccess.ToString().TrimEnd()}}
}
}
""");
}
Console.WriteLine(structs);
}
}

View File

@@ -1,14 +1,15 @@
using System.Linq;
using System.Numerics;
using NUnit.Framework;
using Robust.Shared.Containers;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems;
using Robust.UnitTesting.Server;
using System.Linq;
using System.Numerics;
// ReSharper disable AccessToStaticMemberViaDerivedType
@@ -45,9 +46,9 @@ namespace Robust.UnitTesting.Shared.GameObjects.Systems
mapManager.CreateMap(TestMapId);
// Add grid 1, as the default grid to anchor things to.
var grid = mapManager.CreateGridEntity(TestMapId);
var grid = mapManager.CreateGrid(TestMapId);
return (sim, grid);
return (sim, grid.Owner);
}
// An entity is anchored to the tile it is over on the target grid.
@@ -129,7 +130,7 @@ namespace Robust.UnitTesting.Shared.GameObjects.Systems
var ent1 = entMan.SpawnEntity(null, coordinates);
Assert.False(entMan.GetComponent<TransformComponent>(ent1).Anchored);
Assert.That(!grid.GetAnchoredEntities(pos).Any());
Assert.That(grid.GetAnchoredEntities(pos).Count() == 0);
entMan.DeleteEntity(ent1);
var ent2 = entMan.CreateEntityUninitialized(null, coordinates);
@@ -358,8 +359,8 @@ namespace Robust.UnitTesting.Shared.GameObjects.Systems
// Act
// We purposefully use the grid as container so parent stays the same, reparent will unanchor
var containerMan = entMan.AddComponent<ContainerManagerComponent>(gridId);
var container = containerMan.MakeContainer<Container>(gridId, "TestContainer");
var containerMan = entMan.AddComponent<ContainerManagerComponent>(grid.Owner);
var container = containerMan.MakeContainer<Container>("TestContainer");
container.Insert(ent1);
Assert.That(entMan.GetComponent<TransformComponent>(ent1).Anchored, Is.False);
@@ -477,8 +478,8 @@ namespace Robust.UnitTesting.Shared.GameObjects.Systems
var tileIndices = grid.TileIndicesFor(entMan.GetComponent<TransformComponent>(ent1).Coordinates);
grid.SetTile(tileIndices, new Tile(1));
var containerMan = entMan.AddComponent<ContainerManagerComponent>(gridId);
var container = containerMan.MakeContainer<Container>(gridId, "TestContainer");
var containerMan = entMan.AddComponent<ContainerManagerComponent>(grid.Owner);
var container = containerMan.MakeContainer<Container>("TestContainer");
container.Insert(ent1);
// Act

View File

@@ -57,19 +57,19 @@ namespace Robust.UnitTesting.Shared.GameObjects
var mapManager = server.Resolve<IMapManager>();
var mapId = mapManager.CreateMap();
var grid = mapManager.CreateGridEntity(mapId);
grid.Comp.SetTile(new Vector2i(0, 0), new Tile(1));
var gridXform = entManager.GetComponent<TransformComponent>(grid);
var grid = mapManager.CreateGrid(mapId);
grid.SetTile(new Vector2i(0, 0), new Tile(1));
var gridXform = entManager.GetComponent<TransformComponent>(grid.Owner);
gridXform.LocalPosition = new Vector2(0f, 100f);
var ent1 = entManager.SpawnEntity(null, new EntityCoordinates(grid, Vector2.One * grid.Comp.TileSize / 2));
var ent1 = entManager.SpawnEntity(null, new EntityCoordinates(grid.Owner, Vector2.One * grid.TileSize / 2));
var ent2 = entManager.SpawnEntity(null, new EntityCoordinates(ent1, Vector2.Zero));
var xform2 = entManager.GetComponent<TransformComponent>(ent2);
Assert.That(xform2.WorldPosition, Is.EqualTo(new Vector2(0.5f, 100.5f)));
xform2.AttachToGridOrMap();
Assert.That(xform2.LocalPosition, Is.EqualTo(Vector2.One * grid.Comp.TileSize / 2));
Assert.That(xform2.LocalPosition, Is.EqualTo(Vector2.One * grid.TileSize / 2));
}
}
}

View File

@@ -9,6 +9,11 @@ using Robust.Shared.GameObjects;
using Robust.Shared.Map;
using Robust.Shared.Maths;
using Robust.Shared.Network;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Collision.Shapes;
using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Dynamics;
using Robust.Shared.Physics.Systems;
using cIPlayerManager = Robust.Client.Player.IPlayerManager;
using sIPlayerManager = Robust.Server.Player.IPlayerManager;
@@ -65,14 +70,14 @@ public sealed class DeletionNetworkingTests : RobustIntegrationTest
{
var mapId = mapMan.CreateMap();
mapMan.GetMapEntityId(mapId);
var gridComp = mapMan.CreateGridEntity(mapId);
gridComp.Comp.SetTile(Vector2i.Zero, new Tile(1));
var gridComp = mapMan.CreateGrid(mapId);
gridComp.SetTile(Vector2i.Zero, new Tile(1));
grid1 = gridComp.Owner;
xformSys.SetLocalPosition(grid1, new Vector2(-2,0));
grid1Net = sEntMan.GetNetEntity(grid1);
gridComp = mapMan.CreateGridEntity(mapId);
gridComp.Comp.SetTile(Vector2i.Zero, new Tile(1));
gridComp = mapMan.CreateGrid(mapId);
gridComp.SetTile(Vector2i.Zero, new Tile(1));
grid2 = gridComp.Owner;
xformSys.SetLocalPosition(grid2, new Vector2(2,0));
grid2Net = sEntMan.GetNetEntity(grid2);

Some files were not shown because too many files have changed in this diff Show More