Skip to content

Commit 6140c88

Browse files
committed
perf opted
1 parent 031f865 commit 6140c88

10 files changed

Lines changed: 178 additions & 104 deletions

File tree

src/ModVerify/ModVerifyServiceExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using AET.ModVerify.Verifiers;
1+
using AET.ModVerify.Verifiers.Caching;
22
using Microsoft.Extensions.DependencyInjection;
33

44
namespace AET.ModVerify;
@@ -14,7 +14,7 @@ public IServiceCollection AddModVerify()
1414

1515
public IServiceCollection RegisterVerifierCache()
1616
{
17-
return serviceCollection.AddSingleton<IAlreadyVerifiedCache>(sp => new AlreadyVerifiedCache(sp));
17+
return serviceCollection.AddSingleton<IAlreadyVerifiedCache>(new AlreadyVerifiedCache());
1818
}
1919
}
2020
}

src/ModVerify/Verifiers/AlreadyVerifiedCache.cs

Lines changed: 0 additions & 28 deletions
This file was deleted.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System.Collections.Generic;
2+
3+
namespace AET.ModVerify.Verifiers.Caching;
4+
5+
internal sealed class AlreadyVerifiedCache : IAlreadyVerifiedCache
6+
{
7+
private readonly Dictionary<string, bool> _cachedEntries = new();
8+
9+
public bool TryAddEntry(string entry, bool assetExists)
10+
{
11+
var upper = entry.ToUpperInvariant();
12+
13+
#if NETSTANDARD2_1 || NET
14+
return _cachedEntries.TryAdd(upper, assetExists);
15+
#else
16+
var alreadyVerified = _cachedEntries.ContainsKey(upper);
17+
if (alreadyVerified)
18+
return false;
19+
20+
_cachedEntries[upper] = assetExists;
21+
return true;
22+
#endif
23+
}
24+
25+
public VerifiedCacheEntry GetEntry(string entry)
26+
{
27+
var upper = entry.ToUpperInvariant();
28+
var alreadyVerified = _cachedEntries.TryGetValue(upper, out var exists);
29+
return alreadyVerified ? new VerifiedCacheEntry(true, exists) : default;
30+
}
31+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace AET.ModVerify.Verifiers.Caching;
2+
3+
public interface IAlreadyVerifiedCache
4+
{
5+
bool TryAddEntry(string entry, bool assetExists);
6+
7+
VerifiedCacheEntry GetEntry(string entry);
8+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
namespace AET.ModVerify.Verifiers.Caching;
2+
3+
public readonly struct VerifiedCacheEntry
4+
{
5+
public bool AlreadyVerified { get; }
6+
7+
public bool AssetExists { get; }
8+
9+
public VerifiedCacheEntry(bool alreadyVerified, bool assetExists)
10+
{
11+
AlreadyVerified = alreadyVerified;
12+
AssetExists = assetExists;
13+
}
14+
}

src/ModVerify/Verifiers/Commons/AudioFileVerifier.cs

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using PG.StarWarsGame.Engine;
77
using System.Threading;
88
using Microsoft.Extensions.DependencyInjection;
9+
using AET.ModVerify.Verifiers.Caching;
910

1011
namespace AET.ModVerify.Verifiers.Commons;
1112

@@ -30,9 +31,30 @@ public AudioFileVerifier(IGameVerifierInfo? parent,
3031

3132
public override void Verify(AudioFileInfo sampleInfo, IReadOnlyCollection<string> contextInfo, CancellationToken token)
3233
{
34+
var cached = _alreadyVerifiedCache?.GetEntry(sampleInfo.SampleName);
35+
36+
if (cached?.AlreadyVerified is true)
37+
{
38+
if (!cached.Value.AssetExists)
39+
{
40+
AddError(VerificationError.Create(
41+
this,
42+
VerifierErrorCodes.FileNotFound,
43+
$"Audio file '{sampleInfo.SampleName}' could not be found.",
44+
VerificationSeverity.Error,
45+
[.. contextInfo],
46+
sampleInfo.SampleName));
47+
}
48+
return;
49+
}
50+
51+
3352
var sampleString = sampleInfo.SampleName;
3453

3554
using var sampleStream = Repository.TryOpenFile(sampleString.AsSpan());
55+
56+
_alreadyVerifiedCache?.TryAddEntry(sampleInfo.SampleName, sampleStream is not null);
57+
3658
if (sampleStream is null)
3759
{
3860
AddError(VerificationError.Create(
@@ -45,9 +67,6 @@ public override void Verify(AudioFileInfo sampleInfo, IReadOnlyCollection<string
4567
return;
4668
}
4769

48-
if (!_alreadyVerifiedCache?.TryAddEntry(sampleInfo.SampleName) is false)
49-
return;
50-
5170
if (sampleInfo.ExpectedType == AudioFileType.Mp3)
5271
{
5372
// TODO: MP3 support to be implemented

src/ModVerify/Verifiers/Commons/SingleModelVerifier.cs

Lines changed: 65 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using AET.ModVerify.Reporting;
55
using AET.ModVerify.Settings;
66
using AET.ModVerify.Utilities;
7+
using AET.ModVerify.Verifiers.Caching;
78
using Microsoft.Extensions.DependencyInjection;
89
using PG.StarWarsGame.Engine;
910
using PG.StarWarsGame.Files;
@@ -43,36 +44,71 @@ public SingleModelVerifier(
4344

4445
public override void Verify(string modelName, IReadOnlyCollection<string> contextInfo, CancellationToken token)
4546
{
47+
var cacheEntry = _cache?.GetEntry(modelName);
48+
if (cacheEntry?.AlreadyVerified is true)
49+
{
50+
if (!cacheEntry.Value.AssetExists)
51+
{
52+
var error = VerificationError.Create(
53+
this,
54+
VerifierErrorCodes.FileNotFound,
55+
$"Unable to find .ALO file '{modelName}'",
56+
VerificationSeverity.Error,
57+
contextInfo,
58+
modelName);
59+
AddError(error);
60+
}
61+
return;
62+
}
4663

4764
var modelPath = BuildModelPath(modelName);
48-
VerifyAlamoFile(modelPath, contextInfo, token);
65+
VerifyAlamoFile(modelPath, contextInfo, token, out var modelExists);
4966

50-
foreach (var textureError in _textureVerifier.VerifyErrors)
51-
AddError(textureError);
52-
}
53-
54-
private void VerifyAlamoFile(string modelPath, IReadOnlyCollection<string> contextInfo, CancellationToken token)
55-
{
56-
token.ThrowIfCancellationRequested();
57-
58-
var modelName = FileSystem.Path.GetFileName(modelPath.AsSpan());
59-
60-
// We always want to report that a file was not found, so that error reports show all XRefs to the not found model.
61-
if (!GameEngine.GameRepository.ModelRepository.FileExists(modelPath))
67+
if (!modelExists)
6268
{
63-
var modelNameString = modelName.ToString();
6469
var error = VerificationError.Create(
6570
this,
6671
VerifierErrorCodes.FileNotFound,
67-
$"Unable to find .ALO file '{modelNameString}'",
72+
$"Unable to find .ALO file '{modelName}'",
6873
VerificationSeverity.Error,
6974
contextInfo,
70-
modelNameString);
75+
modelName);
7176
AddError(error);
7277
}
7378

74-
if (_cache?.TryAddEntry(modelName) is false)
75-
return;
79+
_cache?.TryAddEntry(modelName, modelExists);
80+
81+
foreach (var textureError in _textureVerifier.VerifyErrors)
82+
AddError(textureError);
83+
}
84+
85+
public void VerifyModelOrParticle(
86+
IAloFile<IAloDataContent, AloFileInformation> aloFile,
87+
IReadOnlyCollection<string> contextInfo,
88+
CancellationToken token)
89+
{
90+
switch (aloFile)
91+
{
92+
case IAloModelFile model:
93+
VerifyModel(model, contextInfo, token);
94+
break;
95+
case IAloParticleFile particle:
96+
VerifyParticle(particle, contextInfo);
97+
break;
98+
default:
99+
throw new InvalidOperationException("The data stream is neither a model nor particle.");
100+
}
101+
}
102+
103+
private void VerifyAlamoFile(
104+
string modelPath,
105+
IReadOnlyCollection<string> contextInfo,
106+
CancellationToken token,
107+
out bool modelExists)
108+
{
109+
token.ThrowIfCancellationRequested();
110+
111+
modelExists = true;
76112

77113
IAloFile<IAloDataContent, AloFileInformation>? aloFile = null;
78114
try
@@ -90,8 +126,13 @@ private void VerifyAlamoFile(string modelPath, IReadOnlyCollection<string> conte
90126
return;
91127
}
92128

129+
// Because throwsException is true, we know that if aloFile is null,
130+
// the file does not exist
93131
if (aloFile is null)
132+
{
133+
modelExists = false;
94134
return;
135+
}
95136

96137
VerifyModelOrParticle(aloFile, contextInfo, token);
97138
}
@@ -101,21 +142,6 @@ private void VerifyAlamoFile(string modelPath, IReadOnlyCollection<string> conte
101142
}
102143
}
103144

104-
public void VerifyModelOrParticle(IAloFile<IAloDataContent, AloFileInformation> aloFile, IReadOnlyCollection<string> contextInfo, CancellationToken token)
105-
{
106-
switch (aloFile)
107-
{
108-
case IAloModelFile model:
109-
VerifyModel(model, contextInfo, token);
110-
break;
111-
case IAloParticleFile particle:
112-
VerifyParticle(particle, contextInfo);
113-
break;
114-
default:
115-
throw new InvalidOperationException("The data stream is neither a model nor particle.");
116-
}
117-
}
118-
119145
private void VerifyParticle(IAloParticleFile file, IReadOnlyCollection<string> contextInfo)
120146
{
121147
foreach (var texture in file.Content.Textures)
@@ -220,22 +246,21 @@ private void VerifyProxyExists(IPetroglyphFileHolder model, string proxy, IReadO
220246
var proxyPath = BuildModelPath(proxyName);
221247

222248
var modelFilePath = FileSystem.Path.GetGameStrippedPath(Repository.Path.AsSpan(), model.FilePath.AsSpan()).ToString();
249+
250+
VerifyAlamoFile(proxyPath, [..contextInfo, modelFilePath], token, out var proxyExists);
223251

224-
if (!Repository.ModelRepository.FileExists(proxyPath))
252+
if (!proxyExists)
225253
{
226254
var message = $"Proxy particle '{proxyName}' not found for model '{modelFilePath}'";
227255
var error = VerificationError.Create(
228256
this,
229257
VerifierErrorCodes.FileNotFound,
230-
message,
231-
VerificationSeverity.Error,
232-
[..contextInfo, modelFilePath],
258+
message,
259+
VerificationSeverity.Error,
260+
[.. contextInfo, modelFilePath],
233261
proxyName);
234262
AddError(error);
235-
return;
236263
}
237-
238-
VerifyAlamoFile(proxyPath, [..contextInfo, modelFilePath], token);
239264
}
240265

241266
private void VerifyShaderExists(IPetroglyphFileHolder model, string shader, IReadOnlyCollection<string> contextInfo)

0 commit comments

Comments
 (0)