89 lines
2.9 KiB
C#
89 lines
2.9 KiB
C#
|
using System;
|
||
|
using System.Collections.Generic;
|
||
|
using Gallium;
|
||
|
using NodaTime;
|
||
|
|
||
|
namespace Nitride.Temporal
|
||
|
{
|
||
|
/// <summary>
|
||
|
/// Sets the instant from another component. This has methods for handling
|
||
|
/// nullable properties inside the component.
|
||
|
/// </summary>
|
||
|
public class SetInstantFromComponent<TComponent> : NitrideOperationBase
|
||
|
{
|
||
|
private readonly NitrideClock clock;
|
||
|
|
||
|
public SetInstantFromComponent(NitrideClock clock)
|
||
|
{
|
||
|
this.clock = clock;
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// The callback used to get a date time object which is converted into
|
||
|
/// an Instant automatically. This can handle DateTime, DateTimeOffset,
|
||
|
/// LocalDate, and Instant. Nulls are skipped.
|
||
|
/// </summary>
|
||
|
public Func<Entity, TComponent, object?>? GetDateTimeObject
|
||
|
{
|
||
|
get;
|
||
|
set;
|
||
|
}
|
||
|
|
||
|
/// <inheritdoc />
|
||
|
public override IEnumerable<Entity> Run(IEnumerable<Entity> input)
|
||
|
{
|
||
|
this.CheckNotNull(
|
||
|
nameof(this.GetDateTimeObject),
|
||
|
this.GetDateTimeObject);
|
||
|
|
||
|
return input
|
||
|
.ForEachEntity<TComponent>(this.Set);
|
||
|
}
|
||
|
|
||
|
/// <summary>
|
||
|
/// Sets the callback used to get a date time object which is converted
|
||
|
/// into an Instant automatically. This can handle DateTime,
|
||
|
/// DateTimeOffset, LocalDate, and Instant. Nulls are skipped.
|
||
|
/// </summary>
|
||
|
public SetInstantFromComponent<TComponent> WithGetDateTimeObject(
|
||
|
Func<Entity, TComponent, object?>? callback)
|
||
|
{
|
||
|
this.GetDateTimeObject = callback;
|
||
|
return this;
|
||
|
}
|
||
|
|
||
|
private Entity Set(Entity entity, TComponent component)
|
||
|
{
|
||
|
object? temporal = this.GetDateTimeObject!(entity, component);
|
||
|
Instant instant;
|
||
|
|
||
|
switch (temporal)
|
||
|
{
|
||
|
case null:
|
||
|
return entity;
|
||
|
case Instant direct:
|
||
|
instant = direct;
|
||
|
break;
|
||
|
case LocalDate other:
|
||
|
instant = this.clock.CreateInstant(other);
|
||
|
break;
|
||
|
case DateTime other:
|
||
|
instant = this.clock.CreateInstant(other);
|
||
|
break;
|
||
|
case DateTimeOffset other:
|
||
|
instant = this.clock.CreateInstant(other);
|
||
|
break;
|
||
|
default:
|
||
|
throw new InvalidOperationException(
|
||
|
"Did not get a date time object from the callback. "
|
||
|
+ "Can only handle DateTime, DateTimeOffset, LocalDate, "
|
||
|
+ "and Instant. Got a "
|
||
|
+ temporal.GetType().Name
|
||
|
+ " instead.");
|
||
|
}
|
||
|
|
||
|
return entity.Set(instant);
|
||
|
}
|
||
|
}
|
||
|
}
|