Files
wwdpublic/Content.Shared/Decals/DecalGridComponent.cs
metalgearsloth cd8b5b96b5 Optimise DecalOverlay (#25266)
ChunkSize is still 32 so doesn't cut down on heaps of decals atm though we avoid passing many decals to drawing with the coordinates bounds check now.

(cherry picked from commit d8e5f5c24b88bf8096ddaec11e80f1af2953637b)
2024-03-05 09:49:43 +01:00

118 lines
3.6 KiB
C#

using Robust.Shared.GameStates;
using Robust.Shared.Serialization;
using Robust.Shared.Serialization.TypeSerializers.Implementations.Generic;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
using static Content.Shared.Decals.DecalGridComponent;
namespace Content.Shared.Decals
{
[RegisterComponent]
[Access(typeof(SharedDecalSystem))]
[NetworkedComponent]
public sealed partial class DecalGridComponent : Component
{
[Access(Other = AccessPermissions.ReadExecute)]
[DataField(serverOnly: true)]
public DecalGridChunkCollection ChunkCollection = new(new ());
/// <summary>
/// Dictionary mapping decals to their corresponding grid chunks.
/// </summary>
public readonly Dictionary<uint, Vector2i> DecalIndex = new();
/// <summary>
/// Tick at which PVS was last toggled. Ensures that all players receive a full update when toggling PVS.
/// </summary>
public GameTick ForceTick { get; set; }
[DataDefinition]
[Serializable, NetSerializable]
public sealed partial class DecalChunk
{
[IncludeDataField(customTypeSerializer:typeof(DictionarySerializer<uint, Decal>))]
public Dictionary<uint, Decal> Decals;
[NonSerialized]
public GameTick LastModified;
public DecalChunk()
{
Decals = new();
}
public DecalChunk(Dictionary<uint, Decal> decals)
{
Decals = decals;
}
public DecalChunk(DecalChunk chunk)
{
// decals are readonly, so this should be fine.
Decals = chunk.Decals.ShallowClone();
LastModified = chunk.LastModified;
}
}
[DataRecord, Serializable, NetSerializable]
public record DecalGridChunkCollection(Dictionary<Vector2i, DecalChunk> ChunkCollection)
{
public uint NextDecalId;
}
}
[Serializable, NetSerializable]
public sealed class DecalGridState : ComponentState, IComponentDeltaState
{
public Dictionary<Vector2i, DecalChunk> Chunks;
public bool FullState => AllChunks == null;
// required to infer deleted/missing chunks for delta states
public HashSet<Vector2i>? AllChunks;
public DecalGridState(Dictionary<Vector2i, DecalChunk> chunks)
{
Chunks = chunks;
}
public void ApplyToFullState(IComponentState fullState)
{
DebugTools.Assert(!FullState);
var state = (DecalGridState) fullState;
DebugTools.Assert(state.FullState);
foreach (var key in state.Chunks.Keys)
{
if (!AllChunks!.Contains(key))
state.Chunks.Remove(key);
}
foreach (var (chunk, data) in Chunks)
{
state.Chunks[chunk] = new(data);
}
}
public IComponentState CreateNewFullState(IComponentState fullState)
{
DebugTools.Assert(!FullState);
var state = (DecalGridState) fullState;
DebugTools.Assert(state.FullState);
var chunks = new Dictionary<Vector2i, DecalChunk>(state.Chunks.Count);
foreach (var (chunk, data) in Chunks)
{
chunks[chunk] = new(data);
}
foreach (var (chunk, data) in state.Chunks)
{
if (AllChunks!.Contains(chunk))
chunks.TryAdd(chunk, new(data));
}
return new DecalGridState(chunks);
}
}
}