// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "MetasoundDataReferenceMacro.h" #include "MetasoundOperatorSettings.h" namespace Metasound { class FSampleCounter; // Strongly typed time class class FTime { using TimeType = double; static_assert(TIsFloatingPoint::Value, "TimeType must be floating point."); TimeType Time = 0; public: FTime() { } explicit FTime(TimeType InTime) : Time(InTime) { } explicit FTime(float InTime) : Time(static_cast(InTime)) { } FTime(const FTime& InOtherTime) : Time(InOtherTime.Time) { } static const FTime& Zero() { static const FTime ZeroTime; return ZeroTime; } /** Return the time as seconds. */ TimeType GetSeconds() const { return Time; } FTime& operator=(const FTime& InRHS) { Time = InRHS.Time; return *this; } template friend ArithmeticType& operator*=(ArithmeticType& InLHS, const FTime& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); InLHS.Time *= InRHS.Time; return InLHS; } template friend FTime& operator*=(FTime& InLHS, const ArithmeticType& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); InLHS.Time *= InRHS; return InLHS; } template friend ArithmeticType& operator/=(ArithmeticType& InLHS, const FTime& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); InLHS.Time /= InRHS.Time; return InLHS; } template friend FTime& operator/=(FTime& InLHS, const ArithmeticType& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); InLHS.Time /= InRHS; return InLHS; } FTime& operator-=(const FTime& InRHS) { Time -= InRHS.Time; return *this; } template friend ArithmeticType& operator-=(ArithmeticType& InLHS, const FTime& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); InLHS -= InRHS.Time; return InLHS; } template friend FTime& operator-=(FTime& InLHS, const ArithmeticType& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); InLHS.Time -= InRHS; return InLHS; } FTime& operator+=(const FTime& InRHS) { Time += InRHS.Time; return *this; } template friend ArithmeticType& operator+=(ArithmeticType& InLHS, const FTime& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); InLHS += InRHS.Time; return InLHS; } template friend FTime& operator+=(FTime& InLHS, const ArithmeticType& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); InLHS.Time += InRHS; return InLHS; } FTime operator-(const FTime& InRHS) const { return FTime(Time - InRHS.Time); } template friend ArithmeticType operator-(const ArithmeticType& InLHS, const FTime& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return InLHS - InRHS.Time; } template friend FTime operator-(const FTime& InLHS, const ArithmeticType& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return FTime(InLHS.Time - InRHS); } FTime operator+(const FTime& InRHS) const { return FTime(Time + InRHS.Time); } template friend ArithmeticType operator+(const ArithmeticType& InLHS, const FTime& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return InLHS + InRHS.Time; } template friend FTime operator+(const FTime& InLHS, const ArithmeticType& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return FTime(InLHS.Time + InRHS); } template ArithmeticType operator*(const FTime& InRHS) const { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return static_cast(Time * InRHS.Time); } template friend ArithmeticType operator*(const ArithmeticType& InLHS, const FTime& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return InLHS * InRHS.Time; } template friend FTime operator*(const FTime& InLHS, const ArithmeticType& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return FTime(InLHS.Time * InRHS); } template ArithmeticType operator/(const FTime& InRHS) const { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return static_cast(Time / InRHS.Time); } template friend ArithmeticType& operator/(const ArithmeticType& InLHS, const FTime& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return InLHS / InRHS.Time; } template friend FTime operator/(const FTime& InLHS, const ArithmeticType& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return FTime(InLHS.Time / InRHS); } bool operator<(const FTime& InRHS) const { return Time < InRHS.Time; } template friend bool operator<(const ArithmeticType& InLHS, const FTime& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return InLHS < InRHS.Time; } template friend bool operator<(const FTime& InLHS, const ArithmeticType& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return InLHS.Time < InRHS; } bool operator<=(const FTime& InRHS) const { return Time <= InRHS.Time; } template friend bool operator<=(const ArithmeticType& InLHS, const FTime& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return InLHS <= InRHS.Time; } template friend bool operator<=(const FTime& InLHS, const ArithmeticType& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return InLHS.Time <= InRHS; } bool operator>(const FTime& InRHS) const { return Time > InRHS.Time; } template friend bool operator>(const FTime& InLHS, const ArithmeticType& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return InLHS.Time > InRHS; } template friend bool operator>(const ArithmeticType& InLHS, const FTime& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return InLHS > InRHS.Time; } bool operator>=(const FTime& InRHS) const { return Time >= InRHS.Time; } template friend bool operator>=(const ArithmeticType& InLHS, const FTime& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return InLHS >= InRHS.Time; } template friend bool operator>=(const FTime& InLHS, const ArithmeticType& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return InLHS.Time >= InRHS; } template friend bool operator!=(const ArithmeticType& InLHS, const FTime& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return InLHS != InRHS.Time; } bool operator!=(const FTime& InRHS) const { return Time != InRHS.Time; } template friend bool operator!=(const FTime& InLHS, const ArithmeticType& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return InLHS.Time != InRHS; } friend bool operator==(const FTime& InLHS, const FTime& InRHS) { return InLHS.Time == InRHS.Time; } template friend bool operator==(const ArithmeticType& InLHS, const FTime& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return InLHS == InRHS.Time; } template friend bool operator==(const FTime& InLHS, const ArithmeticType& InRHS) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return InLHS.Time == InRHS; } template static ArithmeticType ToMilliseconds(const FTime& InTime) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return static_cast(InTime.GetSeconds() * 1e3); } template static ArithmeticType ToMicroseconds(const FTime& InTime) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return static_cast(InTime.GetSeconds() * 1e6); } template static FTime FromSeconds(const ArithmeticType& InSeconds) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return FTime(static_cast(InSeconds)); } template static FTime FromMilliseconds(const ArithmeticType& InMilliseconds) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return FTime(static_cast(InMilliseconds * 1e-3)); } template static FTime FromMicroseconds(const ArithmeticType& InMicroseconds) { static_assert(TIsArithmetic::Value, "Must be arithmetic type."); return FTime(static_cast(InMicroseconds * 1e-6)); } friend FORCEINLINE uint32 GetTypeHash(const FTime& InTime) { return ::GetTypeHash(InTime.Time); } friend FSampleCounter; }; DECLARE_METASOUND_DATA_REFERENCE_TYPES(FTime, METASOUNDFRONTEND_API, FTimeTypeInfo, FTimeReadRef, FTimeWriteRef); }