diff --git a/src/NexusMods.MnemonicDB.Abstractions/Query/ObservableDatoms.cs b/src/NexusMods.MnemonicDB.Abstractions/Query/ObservableDatoms.cs index d4a73bb..26db3a5 100644 --- a/src/NexusMods.MnemonicDB.Abstractions/Query/ObservableDatoms.cs +++ b/src/NexusMods.MnemonicDB.Abstractions/Query/ObservableDatoms.cs @@ -1,24 +1,20 @@ using System; -using System.Collections.Generic; -using System.Diagnostics.CodeAnalysis; -using System.Linq; using System.Reactive.Linq; using System.Runtime.CompilerServices; using DynamicData; +using JetBrains.Annotations; using NexusMods.MnemonicDB.Abstractions.Attributes; -using NexusMods.MnemonicDB.Abstractions.DatomComparators; using NexusMods.MnemonicDB.Abstractions.DatomIterators; using NexusMods.MnemonicDB.Abstractions.IndexSegments; -using NexusMods.MnemonicDB.Abstractions.Internals; namespace NexusMods.MnemonicDB.Abstractions.Query; /// /// Extensions for observing datoms in the database /// +[PublicAPI] public static class ObservableDatoms { - /// /// Delays the creation of the IObservable until after the first value from the src is received. Once the first /// value arrives the ctor function will be called to create the observable. This is useful for situations where @@ -92,7 +88,15 @@ public static IObservable> ObserveDatoms(this IConne { return conn.Revisions.DelayUntilFirstValue(() => conn.ObserveDatoms(SliceDescriptor.Create(attribute, conn.AttributeCache))); } - + + /// + /// Observe whether datoms for the descriptor exist at all. + /// + public static IObservable ObserveHasAnyDatoms(this IConnection connection, SliceDescriptor descriptor) + { + return connection.Revisions.Select(revision => revision.Datoms(descriptor).Count != 0); + } + /// /// Converts a set of observed datoms to a set of observed entity ids, assumes that there will be no datoms with /// duplicate entity ids. @@ -115,9 +119,10 @@ public static IObservable> AsEntityIds(this IObserva private static IChangeSet Diff(AttributeCache cache, IndexSegment updates, SliceDescriptor descriptor) { var changes = new ChangeSet(); + var index = descriptor.Index; - for (var i = 0; i < updates.Count; i++) + for (var i = 0; i < updates.Count; i++) { var datom = updates[i].WithIndex(index); if (!descriptor.Includes(datom)) diff --git a/tests/NexusMods.MnemonicDB.Tests/DbTests.cs b/tests/NexusMods.MnemonicDB.Tests/DbTests.cs index da5d46c..2a72807 100644 --- a/tests/NexusMods.MnemonicDB.Tests/DbTests.cs +++ b/tests/NexusMods.MnemonicDB.Tests/DbTests.cs @@ -1173,4 +1173,38 @@ public async Task CanExciseEntities() .NotBeEmpty(); } + + [Fact] + public async Task Test_ObserveHasAnyDatoms() + { + var hasAnyDatoms = false; + + using var disposable = Connection + .ObserveHasAnyDatoms(SliceDescriptor.Create(Loadout.Name, Connection.AttributeCache)) + .Subscribe(value => hasAnyDatoms = value); + + hasAnyDatoms.Should().BeFalse(); + + EntityId entityId; + using (var tx = Connection.BeginTransaction()) + { + var loadout = new Loadout.New(tx) + { + Name = "Test Loadout" + }; + + var result = await tx.Commit(); + entityId = result.Remap(loadout).Id; + } + + hasAnyDatoms.Should().BeTrue(); + + using (var tx = Connection.BeginTransaction()) + { + tx.Delete(entityId, recursive: false); + await tx.Commit(); + } + + hasAnyDatoms.Should().BeFalse(); + } }