Files
RobustToolbox/Robust.Client/GameObjects/EntitySystems/ContainerSystem.cs
T
Pieter-Jan Briers b72b0e5984 Use a DynamicTree for sprite finding.
Significantly improves client CPU usage.
2020-06-29 16:18:11 +02:00

88 lines
2.4 KiB
C#

using System.Collections.Generic;
using Robust.Shared.Containers;
using Robust.Shared.GameObjects.Systems;
using Robust.Shared.Interfaces.GameObjects;
namespace Robust.Client.GameObjects.EntitySystems
{
public class ContainerSystem : EntitySystem
{
private readonly HashSet<IEntity> _updateQueue = new HashSet<IEntity>();
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<UpdateContainerOcclusionMessage>(UpdateContainerOcclusion);
UpdatesBefore.Add(typeof(SpriteSystem));
}
private void UpdateContainerOcclusion(UpdateContainerOcclusionMessage ev)
{
_updateQueue.Add(ev.Entity);
}
public override void FrameUpdate(float frameTime)
{
base.FrameUpdate(frameTime);
foreach (var toUpdate in _updateQueue)
{
if (toUpdate.Deleted)
{
continue;
}
UpdateEntityRecursively(toUpdate);
}
_updateQueue.Clear();
}
private static void UpdateEntityRecursively(IEntity entity)
{
// TODO: Since we are recursing down,
// we could cache ShowContents data here to speed it up for children.
// Am lazy though.
UpdateEntity(entity);
foreach (var child in entity.Transform.Children)
{
UpdateEntityRecursively(child.Owner);
}
}
private static void UpdateEntity(IEntity entity)
{
if (!entity.TryGetComponent(out SpriteComponent sprite))
{
return;
}
sprite.ContainerOccluded = false;
// We have to recursively scan for containers upwards in case of nested containers.
var tempParent = entity;
while (ContainerHelpers.TryGetContainer(tempParent, out var container))
{
if (!container.ShowContents)
{
sprite.ContainerOccluded = true;
return;
}
}
}
}
internal readonly struct UpdateContainerOcclusionMessage
{
public UpdateContainerOcclusionMessage(IEntity entity)
{
Entity = entity;
}
public IEntity Entity { get; }
}
}