Optimize PVS a little bit.

This commit is contained in:
Pieter-Jan Briers
2020-07-09 02:56:07 +02:00
parent 8f590a7ba9
commit bec9639554
7 changed files with 100 additions and 17 deletions
@@ -26,7 +26,7 @@ namespace Robust.Client.GameObjects.Components.Containers
[ViewVariables] public string ID { get; }
[ViewVariables] public IEntity Owner => Manager.Owner;
[ViewVariables] public bool Deleted { get; private set; }
[ViewVariables] public IReadOnlyCollection<IEntity> ContainedEntities => Entities;
[ViewVariables] public IReadOnlyList<IEntity> ContainedEntities => Entities;
public bool ShowContents { get; set; }
public bool CanInsert(IEntity toinsert)
@@ -26,8 +26,10 @@ namespace Robust.Client.GameObjects.Components.Containers
throw new NotSupportedException("Cannot modify containers on the client.");
}
public override IEnumerable<IContainer> GetAllContainers() =>
_containers.Values.Where(c => !c.Deleted);
protected override IEnumerable<IContainer> GetAllContainersImpl()
{
return _containers.Values.Where(c => !c.Deleted);
}
public override IContainer GetContainer(string id)
{
@@ -29,7 +29,7 @@ namespace Robust.Server.GameObjects.Components.Container
public Container(string id, IContainerManager manager) : base(id, manager) { }
/// <inheritdoc />
public override IReadOnlyCollection<IEntity> ContainedEntities => _containerList.AsReadOnly();
public override IReadOnlyList<IEntity> ContainedEntities => _containerList;
/// <inheritdoc />
protected override void InternalInsert(IEntity toinsert)
@@ -85,7 +85,7 @@ namespace Robust.Server.GameObjects.Components.Container
/// <inheritdoc />
[ViewVariables]
public abstract IReadOnlyCollection<IEntity> ContainedEntities { get; }
public abstract IReadOnlyList<IEntity> ContainedEntities { get; }
/// <inheritdoc />
[ViewVariables(VVAccess.ReadWrite)]
@@ -1,6 +1,7 @@
using Robust.Shared.GameObjects;
using Robust.Shared.Interfaces.GameObjects;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
@@ -21,8 +22,7 @@ namespace Robust.Server.GameObjects.Components.Container
private readonly Dictionary<string, IContainer> EntityContainers = new Dictionary<string, IContainer>();
private Dictionary<string, List<EntityUid>>? _entitiesWaitingResolve;
[ViewVariables]
private IEnumerable<IContainer> _allContainers => EntityContainers.Values;
[ViewVariables] private IEnumerable<IContainer> _allContainers => EntityContainers.Values;
/// <summary>
/// Shortcut method to make creation of containers easier.
@@ -63,7 +63,8 @@ namespace Robust.Server.GameObjects.Components.Container
if (!(existing is T container))
{
throw new InvalidOperationException($"The container exists but is of a different type: {existing.GetType()}");
throw new InvalidOperationException(
$"The container exists but is of a different type: {existing.GetType()}");
}
alreadyExisted = true;
@@ -81,15 +82,22 @@ namespace Robust.Server.GameObjects.Components.Container
{
throw new ArgumentException($"Container with specified ID already exists: '{id}'");
}
var container = (IContainer)Activator.CreateInstance(type, id, this)!;
var container = (IContainer) Activator.CreateInstance(type, id, this)!;
EntityContainers[id] = container;
Dirty();
return container;
}
/// <inheritdoc />
public override IEnumerable<IContainer> GetAllContainers() =>
EntityContainers.Values.Where(c => !c.Deleted);
public new AllContainersEnumerable GetAllContainers()
{
return new AllContainersEnumerable(this);
}
protected override IEnumerable<IContainer> GetAllContainersImpl()
{
return GetAllContainers();
}
/// <inheritdoc />
public override IContainer GetContainer(string id)
@@ -111,6 +119,7 @@ namespace Robust.Server.GameObjects.Components.Container
container = null;
return false;
}
container = GetContainer(id);
return true;
}
@@ -171,6 +180,7 @@ namespace Robust.Server.GameObjects.Components.Container
return containers.Remove(entity);
}
}
return true; // If we don't contain the entity, it will always be removed
}
@@ -179,10 +189,11 @@ namespace Robust.Server.GameObjects.Components.Container
base.OnRemove();
// IContianer.Shutdown modifies the EntityContainers collection
foreach(var container in EntityContainers.Values.ToArray())
foreach (var container in EntityContainers.Values.ToArray())
{
container.Shutdown();
}
EntityContainers.Clear();
}
@@ -209,6 +220,7 @@ namespace Robust.Server.GameObjects.Components.Container
{
continue;
}
var list = new List<EntityUid>(datum.Entities.Where(u => u.IsValid()));
_entitiesWaitingResolve.Add(key, list);
}
@@ -225,7 +237,8 @@ namespace Robust.Server.GameObjects.Components.Container
}
// ReSharper disable once RedundantTypeArgumentsOfMethod
serializer.DataWriteFunction<Dictionary<string, ContainerPrototypeData>?>("containers", null, () => dict);
serializer.DataWriteFunction<Dictionary<string, ContainerPrototypeData>?>("containers", null,
() => dict);
}
}
@@ -275,5 +288,68 @@ namespace Robust.Server.GameObjects.Components.Container
serializer.DataField(ref Type, "type", null);
}
}
public struct AllContainersEnumerable : IEnumerable<IContainer>
{
private readonly ContainerManagerComponent _manager;
public AllContainersEnumerable(ContainerManagerComponent manager)
{
_manager = manager;
}
public AllContainersEnumerator GetEnumerator()
{
return new AllContainersEnumerator(_manager);
}
IEnumerator<IContainer> IEnumerable<IContainer>.GetEnumerator()
{
return GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public struct AllContainersEnumerator : IEnumerator<IContainer>
{
private Dictionary<string, IContainer>.ValueCollection.Enumerator _enumerator;
public AllContainersEnumerator(ContainerManagerComponent manager)
{
_enumerator = manager.EntityContainers.Values.GetEnumerator();
Current = default;
}
public bool MoveNext()
{
while (_enumerator.MoveNext())
{
if (!_enumerator.Current.Deleted)
{
Current = _enumerator.Current;
return true;
}
}
return false;
}
void IEnumerator.Reset()
{
((IEnumerator<IContainer>) _enumerator).Reset();
}
[AllowNull] public IContainer Current { get; private set; }
object? IEnumerator.Current => Current;
public void Dispose()
{
}
}
}
}
@@ -311,8 +311,11 @@ namespace Robust.Server.GameObjects
foreach (var container in contMgr.GetAllContainers())
{
foreach (var contEnt in container.ContainedEntities)
// Manual for loop to cut out allocations.
// ReSharper disable once ForCanBeConvertedToForeach
for (var i = 0; i < container.ContainedEntities.Count; i++)
{
var contEnt = container.ContainedEntities[i];
set.Add(contEnt);
AddContainedRecursive(contEnt, set);
}
@@ -35,7 +35,9 @@ namespace Robust.Shared.GameObjects.Components.Containers
}
}
public abstract IEnumerable<IContainer> GetAllContainers();
public IEnumerable<IContainer> GetAllContainers() => GetAllContainersImpl();
// Separate impl method to facilitate method hiding in the subclasses.
protected abstract IEnumerable<IContainer> GetAllContainersImpl();
}
}
@@ -46,7 +46,7 @@ namespace Robust.Shared.Interfaces.GameObjects.Components
/// <summary>
/// Readonly collection of all the entities contained within this specific container
/// </summary>
IReadOnlyCollection<IEntity> ContainedEntities { get; }
IReadOnlyList<IEntity> ContainedEntities { get; }
/// <summary>
/// Should the contents of this container be shown? False for closed containers like lockers, true for