Add CultMesh multi-document latest helpers
This commit is contained in:
parent
c45a11e2c8
commit
7bb6d7da8c
2 changed files with 80 additions and 0 deletions
|
|
@ -1675,6 +1675,55 @@ namespace GameCult.Mesh
|
|||
return new CultMeshDocumentCatalog(documents);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads two typed document handles and projects them into one caller-defined view.
|
||||
/// </summary>
|
||||
public static async Task<TResult> LatestAsync<TFirst, TSecond, TResult>(
|
||||
CultMeshDocumentHandle<TFirst> first,
|
||||
CultMeshDocumentHandle<TSecond> second,
|
||||
Func<TFirst, TSecond, TResult> project)
|
||||
where TFirst : class
|
||||
where TSecond : class
|
||||
{
|
||||
if (first == null) throw new ArgumentNullException(nameof(first));
|
||||
if (second == null) throw new ArgumentNullException(nameof(second));
|
||||
if (project == null) throw new ArgumentNullException(nameof(project));
|
||||
|
||||
var firstTask = first.LatestAsync();
|
||||
var secondTask = second.LatestAsync();
|
||||
await Task.WhenAll(firstTask, secondTask).ConfigureAwait(false);
|
||||
return project(
|
||||
await firstTask.ConfigureAwait(false),
|
||||
await secondTask.ConfigureAwait(false));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads three typed document handles and projects them into one caller-defined view.
|
||||
/// </summary>
|
||||
public static async Task<TResult> LatestAsync<TFirst, TSecond, TThird, TResult>(
|
||||
CultMeshDocumentHandle<TFirst> first,
|
||||
CultMeshDocumentHandle<TSecond> second,
|
||||
CultMeshDocumentHandle<TThird> third,
|
||||
Func<TFirst, TSecond, TThird, TResult> project)
|
||||
where TFirst : class
|
||||
where TSecond : class
|
||||
where TThird : class
|
||||
{
|
||||
if (first == null) throw new ArgumentNullException(nameof(first));
|
||||
if (second == null) throw new ArgumentNullException(nameof(second));
|
||||
if (third == null) throw new ArgumentNullException(nameof(third));
|
||||
if (project == null) throw new ArgumentNullException(nameof(project));
|
||||
|
||||
var firstTask = first.LatestAsync();
|
||||
var secondTask = second.LatestAsync();
|
||||
var thirdTask = third.LatestAsync();
|
||||
await Task.WhenAll(firstTask, secondTask, thirdTask).ConfigureAwait(false);
|
||||
return project(
|
||||
await firstTask.ConfigureAwait(false),
|
||||
await secondTask.ConfigureAwait(false),
|
||||
await thirdTask.ConfigureAwait(false));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a typed collection handle over all local CultCache records assignable to the document type.
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -736,6 +736,37 @@ public sealed class CultMeshStreamingTests
|
|||
catalog.Latest<MeshNoteAliasDocument>().Text.Should().Be("catalog-primary");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task DocumentHelpers_ProjectLatestSnapshotsFromMultipleHandles()
|
||||
{
|
||||
var primary = CultMesh.Document(
|
||||
"mesh.note.primary",
|
||||
CultMesh.Verse("starbridge", "unity-pilot"),
|
||||
_ => Task.FromResult(new MeshNoteDocument
|
||||
{
|
||||
Schema = "tests.mesh_note.v1",
|
||||
Text = "alpha",
|
||||
Revision = 3
|
||||
}),
|
||||
_ => new Subject<MeshNoteDocument>());
|
||||
var secondary = CultMesh.Document(
|
||||
"mesh.note.secondary",
|
||||
CultMesh.Verse("starbridge", "unity-pilot"),
|
||||
_ => Task.FromResult(new MeshOtherDocument
|
||||
{
|
||||
Schema = "tests.mesh_other.v1",
|
||||
Text = "beta"
|
||||
}),
|
||||
_ => new Subject<MeshOtherDocument>());
|
||||
|
||||
var projected = await CultMesh.LatestAsync(
|
||||
primary,
|
||||
secondary,
|
||||
(first, second) => $"{first.Text}:{first.Revision}:{second.Text}");
|
||||
|
||||
projected.Should().Be("alpha:3:beta");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task DocumentHandle_ReadsWatchesAndReplacesCultCacheRecords()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue