Files
RobustToolbox/Robust.Shared/ComponentTrees/RecursiveMoveSystem.cs
Kara d416344aef MoveEvent broadcast -> C# event (#4732)
* MoveEvent broadcast -> C# event

* Broadcast MoveEvent -> C# event

* oops

* forgob

* release notes

* Update description of moveevent
2023-12-19 12:26:13 +11:00

78 lines
2.3 KiB
C#

using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Map;
using Robust.Shared.Utility;
namespace Robust.Shared.ComponentTrees;
/// <summary>
/// This system will recursively raise events to update component tree positions any time any entity moves.
/// </summary>
/// <remarks>
/// This is used by some client-side systems (e.g., sprites, lights, etc). However this can be quite expensive and if possible should not be used by the server.
/// </remarks>
internal sealed class RecursiveMoveSystem : EntitySystem
{
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
public delegate void TreeRecursiveMoveEventHandler(EntityUid uid, TransformComponent xform);
public event TreeRecursiveMoveEventHandler? OnTreeRecursiveMove;
private EntityQuery<TransformComponent> _xformQuery;
bool _subscribed = false;
public override void Initialize()
{
base.Initialize();
_xformQuery = GetEntityQuery<TransformComponent>();
}
public override void Shutdown()
{
if (_subscribed)
_transform.OnGlobalMoveEvent -= AnythingMoved;
_subscribed = false;
}
internal void AddSubscription()
{
if (_subscribed)
return;
_subscribed = true;
_transform.OnGlobalMoveEvent += AnythingMoved;
}
private void AnythingMoved(ref MoveEvent args)
{
if (args.Component.MapUid == args.Sender || args.Component.GridUid == args.Sender)
return;
DebugTools.Assert(!_mapManager.IsMap(args.Sender));
DebugTools.Assert(!_mapManager.IsGrid(args.Sender));
AnythingMovedSubHandler(args.Sender, args.Component);
}
private void AnythingMovedSubHandler(
EntityUid uid,
TransformComponent xform)
{
OnTreeRecursiveMove?.Invoke(uid, xform);
// TODO only enumerate over entities in containers if necessary?
// annoyingly, containers aren't guaranteed to occlude sprites & lights
// but AFAIK thats currently unused???
foreach (var child in xform._children)
{
if (_xformQuery.TryGetComponent(child, out var childXform))
AnythingMovedSubHandler(child, childXform);
}
}
}