// Copyright 2013 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef FLUTTER_FML_TIME_TIME_DELTA_H_ #define FLUTTER_FML_TIME_TIME_DELTA_H_ #include #include #include #include #include namespace fml { using namespace std::chrono_literals; using Milliseconds = std::chrono::duration; // Default to 60fps. constexpr Milliseconds kDefaultFrameBudget = Milliseconds(1s) / 60; template Milliseconds RefreshRateToFrameBudget(T refresh_rate) { return Milliseconds(1s) / refresh_rate; } // A TimeDelta represents the difference between two time points. class TimeDelta { public: constexpr TimeDelta() = default; static constexpr TimeDelta Zero() { return TimeDelta(); } static constexpr TimeDelta Min() { return TimeDelta(std::numeric_limits::min()); } static constexpr TimeDelta Max() { return TimeDelta(std::numeric_limits::max()); } static constexpr TimeDelta FromNanoseconds(int64_t nanos) { return TimeDelta(nanos); } static constexpr TimeDelta FromMicroseconds(int64_t micros) { return FromNanoseconds(micros * 1000); } static constexpr TimeDelta FromMilliseconds(int64_t millis) { return FromMicroseconds(millis * 1000); } static constexpr TimeDelta FromSeconds(int64_t seconds) { return FromMilliseconds(seconds * 1000); } static constexpr TimeDelta FromSecondsF(double seconds) { return FromNanoseconds( static_cast(seconds * (1000.0 * 1000.0 * 1000.0))); } static constexpr TimeDelta FromMillisecondsF(double millis) { return FromNanoseconds(static_cast(millis * (1000.0 * 1000.0))); } constexpr int64_t ToNanoseconds() const { return delta_; } constexpr int64_t ToMicroseconds() const { return ToNanoseconds() / 1000; } constexpr int64_t ToMilliseconds() const { return ToMicroseconds() / 1000; } constexpr int64_t ToSeconds() const { return ToMilliseconds() / 1000; } constexpr double ToNanosecondsF() const { return static_cast(delta_); } constexpr double ToMicrosecondsF() const { return static_cast(delta_) / 1000.0; } constexpr double ToMillisecondsF() const { return static_cast(delta_) / (1000.0 * 1000.0); } constexpr double ToSecondsF() const { return static_cast(delta_) / (1000.0 * 1000.0 * 1000.0); } constexpr TimeDelta operator-(TimeDelta other) const { return TimeDelta::FromNanoseconds(delta_ - other.delta_); } constexpr TimeDelta operator+(TimeDelta other) const { return TimeDelta::FromNanoseconds(delta_ + other.delta_); } constexpr TimeDelta operator/(int64_t divisor) const { return TimeDelta::FromNanoseconds(delta_ / divisor); } constexpr int64_t operator/(TimeDelta other) const { return delta_ / other.delta_; } constexpr TimeDelta operator*(int64_t multiplier) const { return TimeDelta::FromNanoseconds(delta_ * multiplier); } constexpr TimeDelta operator%(TimeDelta other) const { return TimeDelta::FromNanoseconds(delta_ % other.delta_); } bool operator==(TimeDelta other) const { return delta_ == other.delta_; } bool operator!=(TimeDelta other) const { return delta_ != other.delta_; } bool operator<(TimeDelta other) const { return delta_ < other.delta_; } bool operator<=(TimeDelta other) const { return delta_ <= other.delta_; } bool operator>(TimeDelta other) const { return delta_ > other.delta_; } bool operator>=(TimeDelta other) const { return delta_ >= other.delta_; } static constexpr TimeDelta FromTimespec(struct timespec ts) { return TimeDelta::FromSeconds(ts.tv_sec) + TimeDelta::FromNanoseconds(ts.tv_nsec); } struct timespec ToTimespec() { struct timespec ts; constexpr int64_t kNanosecondsPerSecond = 1000000000ll; ts.tv_sec = static_cast(ToSeconds()); ts.tv_nsec = delta_ % kNanosecondsPerSecond; return ts; } private: // Private, use one of the FromFoo() types explicit constexpr TimeDelta(int64_t delta) : delta_(delta) {} int64_t delta_ = 0; }; } // namespace fml #endif // FLUTTER_FML_TIME_TIME_DELTA_H_