using System; using System.ComponentModel; using System.Globalization; namespace Avalonia.Animation { /// /// Defines the valid modes for a . /// public enum IterationType { Many, Infinite } /// /// Determines the number of iterations of an animation. /// Also defines its repeat behavior. /// [TypeConverter(typeof(IterationCountTypeConverter))] public struct IterationCount : IEquatable { private readonly IterationType _type; private readonly ulong _value; /// /// Initializes a new instance of the struct. /// /// The number of iterations of an animation. public IterationCount(ulong value) : this(value, IterationType.Many) { } /// /// Initializes a new instance of the struct. /// /// The size of the IterationCount. /// The unit of the IterationCount. public IterationCount(ulong value, IterationType type) { if (type > IterationType.Infinite) { throw new ArgumentException("Invalid value", nameof(type)); } _type = type; _value = value; } /// /// Gets an instance of that indicates that an animation /// should repeat forever. /// public static IterationCount Infinite => new IterationCount(0, IterationType.Infinite); /// /// Gets the unit of the . /// public IterationType RepeatType => _type; /// /// Gets a value that indicates whether the is set to Infinite. /// public bool IsInfinite => _type == IterationType.Infinite; /// /// Gets the number of repeat iterations. /// public ulong Value => _value; /// /// Compares two IterationCount structures for equality. /// /// The first IterationCount. /// The second IterationCount. /// True if the structures are equal, otherwise false. public static bool operator ==(IterationCount a, IterationCount b) { return (a.IsInfinite && b.IsInfinite) || (a._value == b._value && a._type == b._type); } /// /// Compares two IterationCount structures for inequality. /// /// The first IterationCount. /// The first IterationCount. /// True if the structures are unequal, otherwise false. public static bool operator !=(IterationCount rc1, IterationCount rc2) { return !(rc1 == rc2); } /// /// Determines whether the is equal to the specified object. /// /// The object with which to test equality. /// True if the objects are equal, otherwise false. public override bool Equals(object o) { if (o == null) { return false; } if (!(o is IterationCount)) { return false; } return this == (IterationCount)o; } /// /// Compares two IterationCount structures for equality. /// /// The structure with which to test equality. /// True if the structures are equal, otherwise false. public bool Equals(IterationCount IterationCount) { return this == IterationCount; } /// /// Gets a hash code for the IterationCount. /// /// The hash code. public override int GetHashCode() { return _value.GetHashCode() ^ _type.GetHashCode(); } /// /// Gets a string representation of the . /// /// The string representation. public override string ToString() { if (IsInfinite) { return "Infinite"; } string s = _value.ToString(); return s; } /// /// Parses a string to return a . /// /// The string. /// The . public static IterationCount Parse(string s) { s = s.ToUpperInvariant().Trim(); if (s.EndsWith("INFINITE")) { return Infinite; } else { if (s.StartsWith("-")) throw new InvalidCastException("IterationCount can't be a negative number."); var value = ulong.Parse(s, CultureInfo.InvariantCulture); return new IterationCount(value); } } } }