using System.Globalization; using System.IO; using Vellum; namespace Amphora.Vellum { /// /// Saves a Duration as its tick count, with the length in words beside it for people reading the save. /// /// /// The two ends of the tick count are Forever and -Forever. A finite length saves as the same number a TimeSpan of /// that length does, so a saved TimeSpan loads as a Duration. /// public sealed class DurationConverter : SaveConverter { public const long ForeverTicks = long.MaxValue; public const long NegativeForeverTicks = long.MinValue; // The one count in from -Forever that no Duration is ever saved as. private const long UnusedTicks = long.MinValue + 1L; public override SaveNode Write(Duration value, SaveSession session) { long ticks; if (value == Duration.Forever) { ticks = ForeverTicks; } else if (value == -Duration.Forever) { ticks = NegativeForeverTicks; } else { ticks = value.Ticks; } return SaveNode.OfText(ticks.ToString(CultureInfo.InvariantCulture), comment: value.ToString("c", CultureInfo.InvariantCulture)); } public override Duration Read(SaveNode node, SaveSession session) { long ticks = (long)session.FromNode(node, typeof(long)); if (ticks == ForeverTicks) { return Duration.Forever; } if (ticks == NegativeForeverTicks) { return -Duration.Forever; } if (ticks == UnusedTicks) { throw new InvalidDataException("A saved duration of " + ticks + " ticks isn't a length of time."); } return Duration.FromTicks(ticks); } } }