Files
RobustToolbox/Robust.Shared/GameObjects/Systems/SharedTransformSystem.cs
T
e5013d9e3f Add support for struct directed events, add by-ref directed/broadcast events. (#1931)
* Add support for struct directed events.
- Turn transform events into readonly structs

* TransformComponent events have readonly fields.

* Reduce boxing allocations, add DirectedRegistration readonly struct.

* Use typeof in a few places instead of GetType

* Add overloads to allow passing directed events by ref.

* Raise transform events by ref.

* Fix occluder AnchorStateChangedEvent subscription

* Fix broadphase subscriptions

* Fix bug oops

* Fix transform system raising moveevents by value

* Don't reflect the test entity systems.

* Directed EventBus uses ref everywhere, internally
Deduplicates a bunch of code. Whoo!

* Add broadcast by-ref events

* Fix by-ref events bug using Unsafe, add new tests for sorted by-ref events.

* Port broadcast events to by-ref.

* Speed, more correctness, reduce generics bloat.

* Clean up subscription code some.

* Remove bad test.

Co-authored-by: Pieter-Jan Briers <pieterjan.briers+git@gmail.com>
2021-08-21 11:37:02 +02:00

86 lines
2.5 KiB
C#

using System.Collections.Generic;
using System.Linq;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Maths;
namespace Robust.Shared.GameObjects
{
internal class SharedTransformSystem : EntitySystem
{
[Dependency] private readonly IMapManager _mapManager = default!;
private readonly Queue<MoveEvent> _gridMoves = new();
private readonly Queue<MoveEvent> _otherMoves = new();
public override void Initialize()
{
base.Initialize();
_mapManager.TileChanged += MapManagerOnTileChanged;
}
public override void Shutdown()
{
_mapManager.TileChanged -= MapManagerOnTileChanged;
base.Shutdown();
}
private void MapManagerOnTileChanged(object? sender, TileChangedEventArgs e)
{
if(e.NewTile.Tile != Tile.Empty)
return;
var grid = _mapManager.GetGrid(e.NewTile.GridIndex);
var tileIndices = e.NewTile.GridIndices;
UnanchorAllEntsOnTile(grid, tileIndices);
}
private void UnanchorAllEntsOnTile(IMapGrid grid, Vector2i tileIndices)
{
var anchoredEnts = grid.GetAnchoredEntities(tileIndices);
foreach (var ent in anchoredEnts.ToList()) // changing anchored modifies this set
{
if (!EntityManager.EntityExists(ent)) continue;
ComponentManager.GetComponent<TransformComponent>(ent).Anchored = false;
}
}
public void DeferMoveEvent(ref MoveEvent moveEvent)
{
if (moveEvent.Sender.HasComponent<IMapGridComponent>())
_gridMoves.Enqueue(moveEvent);
else
_otherMoves.Enqueue(moveEvent);
}
public override void Update(float frameTime)
{
base.Update(frameTime);
// Process grid moves first.
Process(_gridMoves);
Process(_otherMoves);
void Process(Queue<MoveEvent> queue)
{
while (queue.TryDequeue(out var ev))
{
if (ev.Sender.Deleted)
continue;
// Hopefully we can remove this when PVS gets updated to not use NaNs
if (!ev.NewPosition.IsValid(EntityManager))
{
continue;
}
RaiseLocalEvent(ev.Sender.Uid, ref ev);
}
}
}
}
}