using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using FluentValidation;
using MfGames.Gallium;
using MfGames.Nitride.Generators;
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,
CancellationToken cancellationToken = default)
{
// 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);
}
}
}