diff --git a/src/NexusMods.MnemonicDB.Abstractions/IndexSegments/EntityIds.cs b/src/NexusMods.MnemonicDB.Abstractions/IndexSegments/EntityIds.cs index a0061964..fcbd0df7 100644 --- a/src/NexusMods.MnemonicDB.Abstractions/IndexSegments/EntityIds.cs +++ b/src/NexusMods.MnemonicDB.Abstractions/IndexSegments/EntityIds.cs @@ -51,7 +51,7 @@ IEnumerator IEnumerable.GetEnumerator() /// /// Creates a view of these Ids that auto-casts every Id into a model of the given model type /// - Entities AsModels(IDb db) + public Entities AsModels(IDb db) where TModel : IReadOnlyModel { return new Entities(this, db); diff --git a/src/NexusMods.MnemonicDB.Abstractions/IndexSegments/ValueEntities.cs b/src/NexusMods.MnemonicDB.Abstractions/IndexSegments/ValueEntities.cs new file mode 100644 index 00000000..c25c858c --- /dev/null +++ b/src/NexusMods.MnemonicDB.Abstractions/IndexSegments/ValueEntities.cs @@ -0,0 +1,46 @@ +using System.Collections; +using System.Collections.Generic; +using NexusMods.MnemonicDB.Abstractions.Models; + +namespace NexusMods.MnemonicDB.Abstractions.IndexSegments; + +/// +/// A wrapper around Values that auto-creates the given ReadModel on-the-fly +/// +public readonly struct ValueEntities : IReadOnlyCollection + where TModel : IReadOnlyModel +{ + private readonly Values _values; + + /// + /// The database the models are read from + /// + private IDb Db { get; } + + /// + /// Creates a new ValueEntities, from the given values, database, and entity id + /// + public ValueEntities(Values values, IDb db) + { + _values = values; + Db = db; + } + + /// + public IEnumerator GetEnumerator() + { + foreach (var value in _values) + { + yield return TModel.Create(Db, value); + } + } + + IEnumerator IEnumerable.GetEnumerator() + { + return GetEnumerator(); + } + + + /// + public int Count => _values.Count; +} diff --git a/src/NexusMods.MnemonicDB.Abstractions/IndexSegments/ValuesExtensions.cs b/src/NexusMods.MnemonicDB.Abstractions/IndexSegments/ValuesExtensions.cs index 37b43a41..d7d48eb4 100644 --- a/src/NexusMods.MnemonicDB.Abstractions/IndexSegments/ValuesExtensions.cs +++ b/src/NexusMods.MnemonicDB.Abstractions/IndexSegments/ValuesExtensions.cs @@ -15,4 +15,13 @@ public static Entities, TModel> As(this Values, TModel>(ids, db); } + + /// + /// Returns a view of the values as models whose ids are the given id + /// + public static ValueEntities AsModels(this Values values, IDb db) + where TModel : IReadOnlyModel + { + return new ValueEntities(values, db); + } } diff --git a/src/NexusMods.MnemonicDB.SourceGenerator/Template.weave b/src/NexusMods.MnemonicDB.SourceGenerator/Template.weave index 6a7fe926..800f3c4b 100644 --- a/src/NexusMods.MnemonicDB.SourceGenerator/Template.weave +++ b/src/NexusMods.MnemonicDB.SourceGenerator/Template.weave @@ -265,7 +265,7 @@ public partial class {{= model.Name}} { {{each attr in model.Attributes}} {{if attr.IsCollection && attr.IsReference && !attr.IsMarker}} public __SEGMENTS__.Values<__ABSTRACTIONS__.EntityId, ulong> {{= attr.ContextualName}} => {{= attr.FieldName}}.Get(this); - public IEnumerable<{{= attr.ReferenceType.ToDisplayString()}}.ReadOnly> {{= attr.Name}} => {{= attr.FieldName}}.Get(this).Select(id => new {{= attr.ReferenceType.ToDisplayString()}}.ReadOnly(Db, id)); + public __SEGMENTS__.ValueEntities<{{= attr.ReferenceType.ToDisplayString()}}.ReadOnly> {{= attr.Name}} => __SEGMENTS__.ValuesExtensions.AsModels<{{= attr.ReferenceType.ToDisplayString()}}.ReadOnly>({{= attr.FieldName}}.Get(this), Db); {{elif attr.IsMarker}} public bool Is{{= attr.ContextualName}} => {{= attr.FieldName}}.Contains(this); {{else}} @@ -281,7 +281,7 @@ public partial class {{= model.Name}} { {{each backref in model.BackReferences}} - public __SEGMENTS__.Entities<{{= backref.OtherModel.ToDisplayString()}}.ReadOnly> {{= backref.Name}} => Db.GetBackRefs({{= backref.OtherAttribute.ToDisplayString()}}, this.Id).AsModels<{{= backRef.OtherModel.ToDisplayString()}}.ReadOnly>(Db); + public __SEGMENTS__.Entities<{{= backref.OtherModel.ToDisplayString()}}.ReadOnly> {{= backref.Name}} => Db.GetBackRefs({{= backref.OtherAttribute.ToDisplayString()}}, this.Id).AsModels<{{= backref.OtherModel.ToDisplayString()}}.ReadOnly>(Db); {{/each}} /// diff --git a/tests/NexusMods.MnemonicDB.Tests/DbTests.cs b/tests/NexusMods.MnemonicDB.Tests/DbTests.cs index e9d9ad97..608890d8 100644 --- a/tests/NexusMods.MnemonicDB.Tests/DbTests.cs +++ b/tests/NexusMods.MnemonicDB.Tests/DbTests.cs @@ -281,7 +281,7 @@ public async Task CanGetDatomsFromEntity() mod.Contains(Mod.Source).Should().BeTrue(); mod.Contains(Loadout.Name).Should().BeFalse(); - mod.ToString().Should().Be("Mod<200000000000002>"); + mod.ToString().Should().Be("Mod"); await VerifyTable(mod); }