perf(content): remove exception-driven setup probes
This commit is contained in:
parent
f05afc07c1
commit
230a7df454
11 changed files with 598 additions and 47 deletions
|
|
@ -68,6 +68,12 @@ public sealed class BoundedTestDatCollection : DatReaderWriter.DatCollection, ID
|
|||
IEnumerable<IDatReaderWriter.IdResolution> IDatReaderWriter.ResolveId(uint id) =>
|
||||
_bounded.ResolveId(id);
|
||||
|
||||
bool IDatReaderWriter.TryResolvePreferred(
|
||||
uint id,
|
||||
[NotNullWhen(true)] out IDatDatabase? database,
|
||||
out DatReaderWriter.Enums.DBObjType type) =>
|
||||
_bounded.TryResolvePreferred(id, out database, out type);
|
||||
|
||||
bool IDatReaderWriter.TrySave<T>(T obj, int iteration) =>
|
||||
_bounded.TrySave(obj, iteration);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,124 @@
|
|||
using AcDream.App.Composition;
|
||||
using AcDream.Content;
|
||||
using AcDream.Content.Pak;
|
||||
using DatReaderWriter.DBObjs;
|
||||
|
||||
namespace AcDream.App.Tests.Composition;
|
||||
|
||||
public sealed class PreparedSetupResolverTests
|
||||
{
|
||||
[Fact]
|
||||
public void MissingPreparedSetupDoesNotTouchDatLoader()
|
||||
{
|
||||
int loads = 0;
|
||||
var resolver = new PreparedSetupResolver(
|
||||
new PresenceSource(PreparedAssetPresence.Missing),
|
||||
_ =>
|
||||
{
|
||||
loads++;
|
||||
return new Setup();
|
||||
},
|
||||
_ => { });
|
||||
|
||||
Assert.False(resolver.TryResolve(0x0100_0001u, out Setup? setup));
|
||||
Assert.Null(setup);
|
||||
Assert.Equal(0, loads);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void AvailablePreparedSetupLoadsMatchingDatRecord()
|
||||
{
|
||||
var expected = new Setup();
|
||||
var resolver = new PreparedSetupResolver(
|
||||
new PresenceSource(PreparedAssetPresence.Available),
|
||||
id =>
|
||||
{
|
||||
Assert.Equal(0x0200_0001u, id);
|
||||
return expected;
|
||||
},
|
||||
_ => { });
|
||||
|
||||
Assert.True(resolver.TryResolve(0x0200_0001u, out Setup? actual));
|
||||
Assert.Same(expected, actual);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CorruptPreparedEntryFailsLoudlyWithoutDatGuess()
|
||||
{
|
||||
int loads = 0;
|
||||
var resolver = new PreparedSetupResolver(
|
||||
new PresenceSource(PreparedAssetPresence.Corrupt),
|
||||
_ =>
|
||||
{
|
||||
loads++;
|
||||
return null;
|
||||
},
|
||||
_ => { });
|
||||
|
||||
Assert.Throws<InvalidDataException>(() =>
|
||||
resolver.TryResolve(0x0200_0001u, out _));
|
||||
Assert.Equal(0, loads);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[MemberData(nameof(KnownMalformedDatExceptions))]
|
||||
public void KnownMalformedDatRecordIsDiagnosedOnce(
|
||||
Func<Exception> exceptionFactory)
|
||||
{
|
||||
var diagnostics = new List<string>();
|
||||
var resolver = new PreparedSetupResolver(
|
||||
new PresenceSource(PreparedAssetPresence.Available),
|
||||
_ => throw exceptionFactory(),
|
||||
diagnostics.Add);
|
||||
|
||||
Assert.False(resolver.TryResolve(0x0200_0001u, out _));
|
||||
Assert.False(resolver.TryResolve(0x0200_0001u, out _));
|
||||
Assert.Single(diagnostics);
|
||||
Assert.Contains("malformed", diagnostics[0], StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UnexpectedDatFailurePropagates()
|
||||
{
|
||||
var expected = new InvalidOperationException("unexpected");
|
||||
var resolver = new PreparedSetupResolver(
|
||||
new PresenceSource(PreparedAssetPresence.Available),
|
||||
_ => throw expected,
|
||||
_ => { });
|
||||
|
||||
InvalidOperationException actual = Assert.Throws<InvalidOperationException>(
|
||||
() => resolver.TryResolve(0x0200_0001u, out _));
|
||||
Assert.Same(expected, actual);
|
||||
}
|
||||
|
||||
public static TheoryData<Func<Exception>> KnownMalformedDatExceptions => new()
|
||||
{
|
||||
() => new InvalidDataException("bad payload"),
|
||||
() => new EndOfStreamException("truncated"),
|
||||
() => new ArgumentOutOfRangeException("index"),
|
||||
};
|
||||
|
||||
private sealed class PresenceSource(PreparedAssetPresence presence)
|
||||
: IPreparedAssetSource
|
||||
{
|
||||
public PreparedAssetSourceStats Stats => default;
|
||||
public CacheStats DecodedTextureCacheStats => default;
|
||||
|
||||
public PreparedAssetPresence Probe(
|
||||
PakAssetType type,
|
||||
uint sourceFileId)
|
||||
{
|
||||
Assert.Equal(PakAssetType.SetupMesh, type);
|
||||
return presence;
|
||||
}
|
||||
|
||||
public PreparedAssetReadResult Read(
|
||||
in PreparedAssetRequest request,
|
||||
CancellationToken cancellationToken = default) =>
|
||||
throw new NotSupportedException();
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,23 @@ namespace AcDream.App.Tests.Rendering.Wb;
|
|||
|
||||
public sealed class WbTextureResolutionPolicyTests
|
||||
{
|
||||
[Fact]
|
||||
public void BakedDefaultPaletteAndRuntimePaletteOverlayKeepDistinctOwnership()
|
||||
{
|
||||
Assert.Equal(
|
||||
WbTextureResolutionKind.SharedAtlas,
|
||||
WbTextureResolutionPolicy.Select(
|
||||
hasOriginalTextureOverride: false,
|
||||
hasPaletteOverride: false,
|
||||
sourceIsPaletteIndexed: true));
|
||||
Assert.Equal(
|
||||
WbTextureResolutionKind.PaletteComposite,
|
||||
WbTextureResolutionPolicy.Select(
|
||||
hasOriginalTextureOverride: false,
|
||||
hasPaletteOverride: true,
|
||||
sourceIsPaletteIndexed: true));
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(false, false, false, (int)WbTextureResolutionKind.SharedAtlas)]
|
||||
[InlineData(false, true, false, (int)WbTextureResolutionKind.SharedAtlas)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue