169 lines
5.6 KiB
C#
169 lines
5.6 KiB
C#
using System;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
|
|
namespace KitsuneCafe.System
|
|
{
|
|
public enum TimeUnit : byte
|
|
{
|
|
Ticks,
|
|
Milliseconds,
|
|
Seconds,
|
|
Minutes,
|
|
Hours,
|
|
Days
|
|
}
|
|
|
|
[Serializable]
|
|
public struct Duration : IComparable, IComparable<Duration>, IComparable<TimeSpan>, IEquatable<Duration>, IEquatable<TimeSpan>
|
|
{
|
|
[SerializeField, HideInInspector]
|
|
private long value;
|
|
|
|
[SerializeField]
|
|
private TimeUnit unit;
|
|
|
|
public Duration(long ticks, TimeUnit unit)
|
|
{
|
|
value = ticks;
|
|
this.unit = unit;
|
|
}
|
|
|
|
public Duration(long ticks) : this(ticks, TimeUnit.Ticks) { }
|
|
|
|
public static implicit operator Duration(TimeSpan ts) => new(ts.Ticks, TimeUnit.Ticks);
|
|
public static implicit operator TimeSpan(Duration duration) => duration.AsTimeSpan();
|
|
public static implicit operator TimeValue(Duration duration) => duration.AsTimeValue();
|
|
public static Duration operator +(Duration lhs, Duration rhs) => lhs.AsTimeSpan() + rhs.AsTimeSpan();
|
|
|
|
public readonly TimeSpan AsTimeSpan() => new(value);
|
|
public readonly TimeValue AsTimeValue() => new((float)Into(TimeUnit.Seconds));
|
|
|
|
public static Duration From(long value, TimeUnit unit)
|
|
{
|
|
var ticks = unit switch
|
|
{
|
|
TimeUnit.Ticks => value,
|
|
TimeUnit.Milliseconds => TimeSpan.TicksPerMillisecond * value,
|
|
TimeUnit.Seconds => TimeSpan.TicksPerSecond * value,
|
|
TimeUnit.Minutes => TimeSpan.TicksPerMinute * value,
|
|
TimeUnit.Hours => TimeSpan.TicksPerHour * value,
|
|
TimeUnit.Days => TimeSpan.TicksPerHour * value,
|
|
var x => throw new ArgumentException($"{x} is not a valid TimeUnit.")
|
|
};
|
|
|
|
return new Duration(ticks, unit);
|
|
}
|
|
|
|
public static Duration From(double value, TimeUnit unit)
|
|
{
|
|
var ticks = unit switch
|
|
{
|
|
TimeUnit.Ticks => value,
|
|
TimeUnit.Milliseconds => TimeSpan.TicksPerMillisecond * value,
|
|
TimeUnit.Seconds => TimeSpan.TicksPerSecond * value,
|
|
TimeUnit.Minutes => TimeSpan.TicksPerMinute * value,
|
|
TimeUnit.Hours => TimeSpan.TicksPerHour * value,
|
|
TimeUnit.Days => TimeSpan.TicksPerHour * value,
|
|
var x => throw new ArgumentException($"{x} is not a valid TimeUnit.")
|
|
};
|
|
|
|
return new Duration(Convert.ToInt64(ticks), unit);
|
|
}
|
|
|
|
public static double ToDisplayValue(long ticks, TimeUnit unit)
|
|
{
|
|
decimal value = unit switch
|
|
{
|
|
TimeUnit.Ticks => ticks,
|
|
TimeUnit.Milliseconds => (decimal)ticks / TimeSpan.TicksPerMillisecond,
|
|
TimeUnit.Seconds => (decimal)ticks / TimeSpan.TicksPerSecond,
|
|
TimeUnit.Minutes => (decimal)ticks / TimeSpan.TicksPerMinute,
|
|
TimeUnit.Hours => (decimal)ticks / TimeSpan.TicksPerHour,
|
|
TimeUnit.Days => (decimal)ticks / TimeSpan.TicksPerHour,
|
|
var x => throw new ArgumentException($"{x} is not a valid TimeUnit.")
|
|
};
|
|
|
|
return Convert.ToDouble(value);
|
|
}
|
|
|
|
public static long FromDisplayValue(double value, TimeUnit unit)
|
|
{
|
|
var ticks = unit switch
|
|
{
|
|
TimeUnit.Ticks => value,
|
|
TimeUnit.Milliseconds => TimeSpan.TicksPerMillisecond * value,
|
|
TimeUnit.Seconds => TimeSpan.TicksPerSecond * value,
|
|
TimeUnit.Minutes => TimeSpan.TicksPerMinute * value,
|
|
TimeUnit.Hours => TimeSpan.TicksPerHour * value,
|
|
TimeUnit.Days => TimeSpan.TicksPerHour * value,
|
|
var x => throw new ArgumentException($"{x} is not a valid TimeUnit.")
|
|
};
|
|
|
|
return Convert.ToInt64(ticks);
|
|
}
|
|
|
|
public readonly double Into() => Into(unit);
|
|
public readonly double Into(TimeUnit unit)
|
|
{
|
|
return ToDisplayValue(value, unit);
|
|
}
|
|
|
|
public readonly int CompareTo(object obj)
|
|
{
|
|
return obj switch
|
|
{
|
|
Duration d => CompareTo(d),
|
|
TimeSpan ts => CompareTo(ts),
|
|
TimeValue tv => CompareTo(tv),
|
|
var value => throw new ArgumentException($"{value} is not comparable to Duration")
|
|
};
|
|
}
|
|
|
|
public static bool Equals(Duration a, Duration b)
|
|
{
|
|
return a.value == b.value;
|
|
}
|
|
|
|
public static int Compare(Duration a, Duration b)
|
|
{
|
|
return a.value.CompareTo(b.value);
|
|
}
|
|
|
|
public readonly int CompareTo(Duration other)
|
|
{
|
|
return Compare(this, other);
|
|
}
|
|
|
|
public readonly int CompareTo(TimeSpan other)
|
|
{
|
|
return TimeSpan.Compare(this, other);
|
|
}
|
|
|
|
public readonly bool Equals(Duration other)
|
|
{
|
|
return Equals(this, other);
|
|
}
|
|
|
|
public readonly bool Equals(TimeSpan other)
|
|
{
|
|
return other.Equals(this);
|
|
}
|
|
|
|
public override readonly bool Equals(object obj)
|
|
{
|
|
return (obj is Duration d && Equals(this, d))
|
|
|| (obj is TimeSpan ts && Equals(this, ts));
|
|
}
|
|
|
|
public override readonly int GetHashCode()
|
|
{
|
|
return HashCode.Combine(value);
|
|
}
|
|
|
|
public override readonly string ToString()
|
|
{
|
|
return $"{value} {nameof(unit)}";
|
|
}
|
|
}
|
|
}
|