using System; using System.Collections.Generic; using System.Linq; using FluentValidation; using MfGames.Gallium; namespace MfGames.Nitride.Entities; /// /// Links a series of entities together in some manner. This assumes that /// the entities coming into the operation are already ordered. /// [WithProperties] public partial class LinkEntitySequence : OperationBase, IResolvingOperation { private readonly IValidator validator; public LinkEntitySequence(IValidator validator) { this.validator = validator; this.CreateSequenceIndex = ( list, index) => new EntitySequence(list, index); this.AddSequenceIndex = ( entity, sequence) => entity.Add(sequence); } /// /// Gets or sets a callback to add a sequence into a given entity. /// public Func AddSequenceIndex { get; set; } /// /// Gets or sets the function used to create the sequence index. /// public Func, int, EntitySequence> CreateSequenceIndex { get; set; } /// public override IEnumerable Run(IEnumerable input) { // Make sure everything is good. this.validator.ValidateAndThrow(this); // We pull all the entities into a list so we can walk through them // more than once along with index access. We also don't reorder the // list since we assumed it has been ordered already. var list = input.ToList(); // Go through the list and assign each entity in order with a unique // copy of the sequence. for (int i = 0; i < list.Count; i++) { Entity entity = list[i]; EntitySequence index = this.CreateSequenceIndex( list.AsReadOnly(), i); yield return this.AddSequenceIndex(entity, index); } } }