diff --git a/src/AcDream.App/Rendering/Wb/EntityClassificationCache.cs b/src/AcDream.App/Rendering/Wb/EntityClassificationCache.cs index 5683346..7d5a65b 100644 --- a/src/AcDream.App/Rendering/Wb/EntityClassificationCache.cs +++ b/src/AcDream.App/Rendering/Wb/EntityClassificationCache.cs @@ -62,4 +62,13 @@ internal sealed class EntityClassificationCache Batches = batches, }; } + + /// + /// Remove the cache entry for . No-op if the + /// id isn't cached. + /// + public void InvalidateEntity(uint entityId) + { + _entries.Remove(entityId); + } } diff --git a/tests/AcDream.Core.Tests/Rendering/Wb/EntityClassificationCacheTests.cs b/tests/AcDream.Core.Tests/Rendering/Wb/EntityClassificationCacheTests.cs index 6f37bff..a7949c1 100644 --- a/tests/AcDream.Core.Tests/Rendering/Wb/EntityClassificationCacheTests.cs +++ b/tests/AcDream.Core.Tests/Rendering/Wb/EntityClassificationCacheTests.cs @@ -103,6 +103,29 @@ public class EntityClassificationCacheTests Assert.Equal(0x105u, entry.Batches[5].BindlessTextureHandle); } + [Fact] + public void InvalidateEntity_RemovesEntry() + { + var cache = new EntityClassificationCache(); + cache.Populate(100, 0u, new[] { MakeCachedBatch(1, 0, 6, 0xAA) }); + Assert.True(cache.TryGet(100, out _)); + + cache.InvalidateEntity(100); + + Assert.False(cache.TryGet(100, out var entry)); + Assert.Null(entry); + Assert.Equal(0, cache.Count); + } + + [Fact] + public void InvalidateEntity_OnMissingId_NoThrow() + { + var cache = new EntityClassificationCache(); + var ex = Record.Exception(() => cache.InvalidateEntity(99999)); + Assert.Null(ex); + Assert.Equal(0, cache.Count); + } + private static CachedBatch MakeCachedBatch( uint ibo, uint firstIndex, int indexCount, ulong texHandle) {