$darkmode
progress.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2020 Robert Bosch GmbH
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  * SPDX-License-Identifier: Apache-2.0
17  */
22 #pragma once
23 
24 #include <chrono> // for time_point, now, duration_cast
25 
26 #include <cloe/core.hpp> // for Json, Duration
27 
28 namespace engine {
29 
30 template <typename T>
31 cloe::Duration cast_duration(T tp) {
32  return std::chrono::duration_cast<cloe::Duration>(tp);
33 }
34 
35 class Progress {
36  public:
37  using Clock = std::chrono::steady_clock;
38  using TimePoint = std::chrono::steady_clock::time_point;
39  using Duration = cloe::Duration;
40 
41  Progress() = default;
42  virtual ~Progress() noexcept = default;
43 
50  void begin() { beg_ = Clock::now(); }
51 
59  void end() {
60  end_ = Clock::now();
61  eta_ = Duration{0};
62  cur_ = 1.0;
63  }
64 
68  bool is_ended() const { return cur_ == 1.0 && eta_ == Duration{0}; }
69 
73  void update(double p) {
74  if (p == 0.0) {
75  // We can't do any predicting when p==0, because we don't have a time
76  // interval yet, so just return.
77  return;
78  }
79 
80  assert(p > 0.0 && p <= 1.0);
81  auto dur = Clock::now() - beg_;
82  assert(cast_duration(dur) > Duration(0));
83  prev_ = cur_;
84  auto total = Duration(static_cast<long long>(static_cast<double>(dur.count()) / p));
85  assert(total >= Duration(0));
86  eta_ = total - dur;
87  assert(eta_ >= Duration(0));
88  cur_ = p;
89  }
90 
94  void update_safe(double p) {
95  if (p < 0.0) {
96  p = 0.0;
97  } else if (p > 1.0) {
98  p = 1.0;
99  }
100  update(p);
101  }
102 
106  double percent() const { return cur_; }
107 
111  Duration eta() const { return eta_; }
112 
116  Duration elapsed() const {
117  if (cur_ < 1) {
118  auto now = Clock::now();
119  return cast_duration(now - beg_);
120  }
121  return cast_duration(end_ - beg_);
122  }
123 
124  friend void to_json(cloe::Json& j, const Progress& e) {
125  j = cloe::Json{
126  {"percent", e.percent()},
127  {"elapsed", e.elapsed()},
128  {"eta", e.eta()},
129  };
130  }
131 
132  private:
133  double prev_{0.0};
134  double cur_{0.0};
135  TimePoint beg_{};
136  TimePoint end_{};
137  Duration eta_{0};
138 };
139 
140 } // namespace engine
Definition: progress.hpp:35
void update_safe(double p)
Definition: progress.hpp:94
double percent() const
Definition: progress.hpp:106
Duration elapsed() const
Definition: progress.hpp:116
void update(double p)
Definition: progress.hpp:73
void end()
Definition: progress.hpp:59
bool is_ended() const
Definition: progress.hpp:68
Duration eta() const
Definition: progress.hpp:111
void begin()
Definition: progress.hpp:50
std::chrono::nanoseconds Duration
Definition: cloe_fwd.hpp:36