feat(schedules): changed ApplySchedules.Schedules to a getter GetSchedules
This commit is contained in:
parent
fc1ab22a0e
commit
08aafb144c
6 changed files with 100 additions and 31 deletions
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
|
@ -8,24 +9,6 @@ using MfGames.Nitride.Generators;
|
|||
|
||||
namespace MfGames.Nitride.Temporal.Schedules;
|
||||
|
||||
public enum SchedulePeriod
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that all the matching schedule periods are instant (zero time).
|
||||
/// </summary>
|
||||
Instant,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the entities will be scheduled a day apart.
|
||||
/// </summary>
|
||||
Day,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the entities will be scheduled seven days apart.
|
||||
/// </summary>
|
||||
Week,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies schedules against the list of entities.
|
||||
/// </summary>
|
||||
|
@ -40,13 +23,15 @@ public partial class ApplySchedules : OperationBase
|
|||
{
|
||||
this.Timekeeper = timekeeper;
|
||||
this.validator = validator;
|
||||
this.Schedules = new List<ISchedule>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the ordered list of schedules to apply to the entities.
|
||||
/// Gets or sets the callback to get the schedules for the entity. This is
|
||||
/// used to allow for per-entity schedules or generic schedules across
|
||||
/// the entire system. If this returns null, then no schedule will be
|
||||
/// applied.
|
||||
/// </summary>
|
||||
public IList<ISchedule> Schedules { get; set; }
|
||||
public Func<Entity, IList<ISchedule>?>? GetSchedules { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the timekeeper associated with this operation.
|
||||
|
@ -61,16 +46,30 @@ public partial class ApplySchedules : OperationBase
|
|||
return input.Select(this.Apply);
|
||||
}
|
||||
|
||||
public ApplySchedules WithSchedules<TItem>(IEnumerable<TItem> items)
|
||||
where TItem : ISchedule
|
||||
public ApplySchedules WithGetSchedules<TType>(
|
||||
Func<Entity, IEnumerable<TType>?> value)
|
||||
where TType : ISchedule
|
||||
{
|
||||
this.Schedules = items.OfType<ISchedule>().ToList();
|
||||
this.GetSchedules = entity => value?
|
||||
.Invoke(entity)
|
||||
?.Cast<ISchedule>()
|
||||
.ToList();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private Entity Apply(Entity entity)
|
||||
{
|
||||
foreach (ISchedule schedule in this.Schedules)
|
||||
// Get the schedule for this entity.
|
||||
IList<ISchedule>? schedules = this.GetSchedules?.Invoke(entity);
|
||||
|
||||
if (schedules == null || schedules.Count == 0)
|
||||
{
|
||||
return entity;
|
||||
}
|
||||
|
||||
// Otherwise, apply the schedules to this entity.
|
||||
foreach (ISchedule schedule in schedules)
|
||||
{
|
||||
if (!schedule.CanApply(entity))
|
||||
{
|
||||
|
|
|
@ -20,7 +20,7 @@ public partial class NumericalPathSchedule : ISchedule
|
|||
public NumericalPathSchedule()
|
||||
{
|
||||
this.PathRegex = new Regex(@"^.*(\d+)");
|
||||
this.GetPath = (entity) => entity.Get<UPath>().ToString();
|
||||
this.GetPath = entity => entity.Get<UPath>().ToString();
|
||||
this.CaptureGroup = 1;
|
||||
this.CaptureOffset = -1;
|
||||
}
|
||||
|
|
19
src/MfGames.Nitride.Temporal.Schedules/SchedulePeriod.cs
Normal file
19
src/MfGames.Nitride.Temporal.Schedules/SchedulePeriod.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
namespace MfGames.Nitride.Temporal.Schedules;
|
||||
|
||||
public enum SchedulePeriod
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that all the matching schedule periods are instant (zero time).
|
||||
/// </summary>
|
||||
Instant,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the entities will be scheduled a day apart.
|
||||
/// </summary>
|
||||
Day,
|
||||
|
||||
/// <summary>
|
||||
/// Indicates that the entities will be scheduled seven days apart.
|
||||
/// </summary>
|
||||
Week,
|
||||
}
|
51
src/MfGames.Nitride.Temporal.Schedules/SimplePathSchedule.cs
Normal file
51
src/MfGames.Nitride.Temporal.Schedules/SimplePathSchedule.cs
Normal file
|
@ -0,0 +1,51 @@
|
|||
using System;
|
||||
|
||||
using MfGames.Gallium;
|
||||
using MfGames.Nitride.Generators;
|
||||
|
||||
using NodaTime;
|
||||
|
||||
namespace MfGames.Nitride.Temporal.Schedules;
|
||||
|
||||
/// <summary>
|
||||
/// A schedule that goes against all entities it is applied to.
|
||||
/// </summary>
|
||||
[WithProperties]
|
||||
public partial class SimplePathSchedule : ISchedule
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets when the first item is scheduled.
|
||||
/// </summary>
|
||||
public DateTime? ScheduleStart { get; set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual Entity Apply(
|
||||
Entity entity,
|
||||
Timekeeper timekeeper)
|
||||
{
|
||||
DateTime start = this.ScheduleStart
|
||||
?? throw new NullReferenceException(
|
||||
"Cannot use a schedule without a start date.");
|
||||
Instant instant = timekeeper.CreateInstant(start);
|
||||
|
||||
// If the time hasn't past, then we don't apply it.
|
||||
Instant now = timekeeper.Clock.GetCurrentInstant();
|
||||
|
||||
return instant > now
|
||||
? entity
|
||||
: this.Apply(entity, instant);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public virtual bool CanApply(Entity entity)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual Entity Apply(
|
||||
Entity entity,
|
||||
Instant instant)
|
||||
{
|
||||
return entity.Set(instant);
|
||||
}
|
||||
}
|
|
@ -6,8 +6,8 @@ public class ApplySchedulesValidator : AbstractValidator<ApplySchedules>
|
|||
{
|
||||
public ApplySchedulesValidator()
|
||||
{
|
||||
this.RuleFor(x => x.Schedules)
|
||||
.NotEmpty();
|
||||
this.RuleFor(x => x.GetSchedules)
|
||||
.NotNull();
|
||||
|
||||
this.RuleFor(x => x.Timekeeper)
|
||||
.NotNull();
|
||||
|
|
|
@ -56,7 +56,7 @@ public class NumericalPathScheduleTests : TemporalSchedulesTestBase
|
|||
// second but before the third item.
|
||||
Timekeeper time = context.Resolve<Timekeeper>();
|
||||
ApplySchedules op = context.Resolve<ApplySchedules>()
|
||||
.WithSchedules(schedules);
|
||||
.WithGetSchedules(_ => schedules);
|
||||
var now = Instant.FromUtc(2023, 1, 9, 0, 0);
|
||||
|
||||
time.Clock = new FakeClock(now);
|
||||
|
@ -111,7 +111,7 @@ public class NumericalPathScheduleTests : TemporalSchedulesTestBase
|
|||
// second but before the third item.
|
||||
Timekeeper time = context.Resolve<Timekeeper>();
|
||||
ApplySchedules op = context.Resolve<ApplySchedules>()
|
||||
.WithSchedules(schedules);
|
||||
.WithGetSchedules(_ => schedules);
|
||||
var now = Instant.FromUtc(2023, 1, 9, 0, 0);
|
||||
|
||||
time.Clock = new FakeClock(now);
|
||||
|
@ -171,7 +171,7 @@ public class NumericalPathScheduleTests : TemporalSchedulesTestBase
|
|||
// second but before the third item.
|
||||
Timekeeper time = context.Resolve<Timekeeper>();
|
||||
ApplySchedules op = context.Resolve<ApplySchedules>()
|
||||
.WithSchedules(schedules);
|
||||
.WithGetSchedules(_ => schedules);
|
||||
var now = Instant.FromUtc(2023, 1, 9, 0, 0);
|
||||
|
||||
time.Clock = new FakeClock(now);
|
||||
|
|
Reference in a new issue