1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef FLUTTER_FML_TIME_TIME_DELTA_H_
6#define FLUTTER_FML_TIME_TIME_DELTA_H_
7
8#include <stdint.h>
9#include <time.h>
10
11#include <chrono>
12#include <iosfwd>
13#include <limits>
14
15namespace fml {
16
17using namespace std::chrono_literals;
18
19using Milliseconds = std::chrono::duration<double, std::milli>;
20
21// Default to 60fps.
22constexpr Milliseconds kDefaultFrameBudget = Milliseconds(1s) / 60;
23
24template <typename T>
25Milliseconds RefreshRateToFrameBudget(T refresh_rate) {
26 return Milliseconds(1s) / refresh_rate;
27}
28
29// A TimeDelta represents the difference between two time points.
30class TimeDelta {
31 public:
32 constexpr TimeDelta() = default;
33
34 static constexpr TimeDelta Zero() { return TimeDelta(); }
35 static constexpr TimeDelta Min() {
36 return TimeDelta(std::numeric_limits<int64_t>::min());
37 }
38 static constexpr TimeDelta Max() {
39 return TimeDelta(std::numeric_limits<int64_t>::max());
40 }
41 static constexpr TimeDelta FromNanoseconds(int64_t nanos) {
42 return TimeDelta(nanos);
43 }
44 static constexpr TimeDelta FromMicroseconds(int64_t micros) {
45 return FromNanoseconds(micros * 1000);
46 }
47 static constexpr TimeDelta FromMilliseconds(int64_t millis) {
48 return FromMicroseconds(millis * 1000);
49 }
50 static constexpr TimeDelta FromSeconds(int64_t seconds) {
51 return FromMilliseconds(seconds * 1000);
52 }
53
54 static constexpr TimeDelta FromSecondsF(double seconds) {
55 return FromNanoseconds(seconds * (1000.0 * 1000.0 * 1000.0));
56 }
57
58 static constexpr TimeDelta FromMillisecondsF(double millis) {
59 return FromNanoseconds(millis * (1000.0 * 1000.0));
60 }
61
62 constexpr int64_t ToNanoseconds() const { return delta_; }
63 constexpr int64_t ToMicroseconds() const { return ToNanoseconds() / 1000; }
64 constexpr int64_t ToMilliseconds() const { return ToMicroseconds() / 1000; }
65 constexpr int64_t ToSeconds() const { return ToMilliseconds() / 1000; }
66
67 constexpr double ToNanosecondsF() const { return delta_; }
68 constexpr double ToMicrosecondsF() const { return delta_ / 1000.0; }
69 constexpr double ToMillisecondsF() const {
70 return delta_ / (1000.0 * 1000.0);
71 }
72 constexpr double ToSecondsF() const {
73 return delta_ / (1000.0 * 1000.0 * 1000.0);
74 }
75
76 constexpr TimeDelta operator-(TimeDelta other) const {
77 return TimeDelta::FromNanoseconds(delta_ - other.delta_);
78 }
79
80 constexpr TimeDelta operator+(TimeDelta other) const {
81 return TimeDelta::FromNanoseconds(delta_ + other.delta_);
82 }
83
84 constexpr TimeDelta operator/(int64_t divisor) const {
85 return TimeDelta::FromNanoseconds(delta_ / divisor);
86 }
87
88 constexpr int64_t operator/(TimeDelta other) const {
89 return delta_ / other.delta_;
90 }
91
92 constexpr TimeDelta operator*(int64_t multiplier) const {
93 return TimeDelta::FromNanoseconds(delta_ * multiplier);
94 }
95
96 constexpr TimeDelta operator%(TimeDelta other) const {
97 return TimeDelta::FromNanoseconds(delta_ % other.delta_);
98 }
99
100 bool operator==(TimeDelta other) const { return delta_ == other.delta_; }
101 bool operator!=(TimeDelta other) const { return delta_ != other.delta_; }
102 bool operator<(TimeDelta other) const { return delta_ < other.delta_; }
103 bool operator<=(TimeDelta other) const { return delta_ <= other.delta_; }
104 bool operator>(TimeDelta other) const { return delta_ > other.delta_; }
105 bool operator>=(TimeDelta other) const { return delta_ >= other.delta_; }
106
107 static constexpr TimeDelta FromTimespec(struct timespec ts) {
108 return TimeDelta::FromSeconds(ts.tv_sec) +
109 TimeDelta::FromNanoseconds(ts.tv_nsec);
110 }
111 struct timespec ToTimespec() {
112 struct timespec ts;
113 constexpr int64_t kNanosecondsPerSecond = 1000000000ll;
114 ts.tv_sec = static_cast<time_t>(ToSeconds());
115 ts.tv_nsec = delta_ % kNanosecondsPerSecond;
116 return ts;
117 }
118
119 private:
120 // Private, use one of the FromFoo() types
121 explicit constexpr TimeDelta(int64_t delta) : delta_(delta) {}
122
123 int64_t delta_ = 0;
124};
125
126} // namespace fml
127
128#endif // FLUTTER_FML_TIME_TIME_DELTA_H_
129