DxLibEx
time.hpp
Go to the documentation of this file.
1 /*=============================================================================
2  Copyright (C) 2015-2017 DxLibEx project
3  https://github.com/Nagarei/DxLibEx/
4 
5  Distributed under the Boost Software License, Version 1.0.
6  (See http://www.boost.org/LICENSE_1_0.txt)
7 =============================================================================*/
8 #ifndef DXLE_INC_TIME_HPP_
9 #define DXLE_INC_TIME_HPP_
10 
12 #if defined(__c2__) && __clang_major__ == 3 && __clang_minor__ == 8
13 //To avoid compile error
14 //C:\Program Files (x86)\Windows Kits\8.1\Include\um\combaseapi.h(229,21): error : unknown type name 'IUnknown'
15 // static_cast<IUnknown*>(*pp); // make sure everyone derives from IUnknown
16 struct IUnknown;
17 #endif
18 #include <vector>
19 #include <chrono>
20 #include <type_traits>
21 #include <utility>
22 #include <algorithm>
23 #include <assert.h>
24 #include <DxLib.h>
25 #include "dxlibex/config/defines.h"
27 namespace dxle
28 {
29  namespace time
30  {
31 
32  class timer {
33  public:
34  timer();
35 
36  void start(void);
37  void stop(void);
38  bool is_stop(void);
39  void reset(std::chrono::milliseconds = std::chrono::milliseconds{ 0 });
40 
41  std::chrono::milliseconds get_pass_time();
42  private:
43  int old_time;
44  bool is_stop_;
45  std::chrono::milliseconds pass_time;
46 
47  void update();
48  };
49 
51  namespace timing_maker
52  {
54  {
55  virtual std::vector<std::chrono::milliseconds> make_timing()const DXLE_REF_QUALIFIERS_LVALUE = 0;
56 #ifndef DXLE_NO_CXX11_REF_QUALIFIERS
57  virtual std::vector<std::chrono::milliseconds> make_timing() &&
58  {
59  return this->make_timing();
60  }
61 #endif
62  };
64  {
65  public:
67  count_per_second(size_t count, std::chrono::milliseconds millisecond = std::chrono::milliseconds(1000))
68  : timing(millisecond / count)
69  {}
70  std::vector<std::chrono::milliseconds> make_timing()const DXLE_REF_QUALIFIERS_LVALUE override
71  {
72  return std::vector<std::chrono::milliseconds>(1, timing);
73  }
74  private:
75  std::chrono::milliseconds timing;
76  };
78  {
79  public:
81  raw_timing(std::vector<std::chrono::milliseconds> timing_)
82  : timing(std::move(timing_))
83  {}
84  std::vector<std::chrono::milliseconds> make_timing()const DXLE_REF_QUALIFIERS_LVALUE override
85  {
86  return timing;
87  }
88 #ifndef DXLE_NO_CXX11_REF_QUALIFIERS
89  std::vector<std::chrono::milliseconds> make_timing() && override
90  {
91  return std::move(timing);
92  }
93 #endif
94  private:
95  std::vector<std::chrono::milliseconds> timing;
96  };
97 
98  }
99 
100  class counter
101  {
102  public:
103  template<typename timing_maker_T, typename std::enable_if<std::is_base_of<timing_maker::timing_maker_bace, typename std::remove_reference<timing_maker_T>::type>::value, nullptr_t>::type = nullptr>
104  counter(timing_maker_T&& timing_maker);
105 
106  counter(const counter& other);
107  counter(counter&& other);
108  counter& operator=(const counter& other);
109  counter& operator=(counter&& other);
110 
111  void start(void);
112  void stop(void);
113  bool is_stop(void);
114  void reset_pass_time(std::chrono::milliseconds = std::chrono::milliseconds{ 0 });
115  std::chrono::milliseconds get_pass_time();
116 
117  size_t get();
118  void reset_count(size_t = 0);
119 
120  private:
121  size_t count;
122  std::vector<std::chrono::milliseconds> timing;
123  size_t next_timing_index;
124  std::chrono::milliseconds last_pass_time;
125  timer timer_;
126 
127  void update();
128  };
129 
130  }
131  using namespace time;
132 }
133 #ifdef DXLE_SUPPORT_CXX11_USER_DEFINED_LITERALS
134 namespace dxle
135 {
136  namespace literals {
137  namespace time_literals {
138 
139  inline time::timing_maker::count_per_second operator""_cps(unsigned long long int count_per_second)
140  {
141  return time::timing_maker::count_per_second{static_cast<size_t>(count_per_second)};
142  }
143 
144  }
145  using namespace time_literals;
146  }
147  using namespace literals;
148 
149  namespace time {
150  using namespace literals::time_literals;
151  }
152 }
153 #endif //#ifdef DXLE_SUPPORT_CXX11_USER_DEFINED_LITERALS
154 namespace dxle
155 {
156  namespace time
157  {
158 
159  //----------timer----------//
160 
161  inline timer::timer()
162  : old_time(0)
163  , is_stop_(true)
164  , pass_time(0)
165  {}
166  inline void timer::start(void)
167  {
168  if (is_stop_ == true){
169  is_stop_ = false;
170  old_time = DxLib::GetNowCount();
171  }
172  }
173  inline void timer::stop(void)
174  {
175  update();
176  is_stop_ = true;
177  }
178  inline bool timer::is_stop(void)
179  {
180  return is_stop_;
181  }
182  inline void timer::reset(std::chrono::milliseconds set_time)
183  {
184  update();
185  pass_time = set_time;
186  }
187  inline std::chrono::milliseconds timer::get_pass_time(void)
188  {
189  update();
190  return pass_time;
191  }
192  inline void timer::update()
193  {
194  if (is_stop_ == false){
195  int now_time = DxLib::GetNowCount();
196  pass_time += std::chrono::milliseconds((now_time - old_time) & INT_MAX);
197  old_time = now_time;
198  }
199  }
200 
201  //----------counter----------//
202 
203  template<typename timing_maker_T, typename std::enable_if<std::is_base_of<timing_maker::timing_maker_bace, typename std::remove_reference<timing_maker_T>::type>::value, nullptr_t >::type>
204  inline counter::counter(timing_maker_T&& timing_maker)
205  : count(0)
206  , timing(std::forward<timing_maker_T>(timing_maker).make_timing())
207  , next_timing_index(0)
208  , last_pass_time(0)
209  , timer_()
210  {}
211  inline counter::counter(const counter& other)
212  : count((other.count))
213  , timing((other.timing))
214  , next_timing_index((other.next_timing_index))
215  , last_pass_time(other.last_pass_time)
216  , timer_((other.timer_))
217  {}
218  inline counter& counter::operator=(const counter& other)
219  {
220  count = (other.count);
221  timing = (other.timing);
222  next_timing_index = (other.next_timing_index);
223  last_pass_time = (other.last_pass_time);
224  timer_ = (other.timer_);
225  return *this;
226  }
227  inline counter::counter(counter&& other)
228  : count(std::move(other.count))
229  , timing(std::move(other.timing))
230  , next_timing_index(std::move(other.next_timing_index))
231  , last_pass_time(std::move(other.last_pass_time))
232  , timer_(std::move(other.timer_))
233  {}
235  {
236  count = std::move(other.count);
237  timing = std::move(other.timing);
238  next_timing_index = std::move(other.next_timing_index);
239  last_pass_time = std::move(other.last_pass_time);
240  timer_ = std::move(other.timer_);
241  return *this;
242  }
243  inline void counter::start(void)
244  {
245  timer_.start();
246  }
247  inline void counter::stop(void)
248  {
249  timer_.stop();
250  }
251  inline bool counter::is_stop(void)
252  {
253  return timer_.is_stop();
254  }
255  inline void counter::reset_pass_time(std::chrono::milliseconds new_pass_time)
256  {
257  if (new_pass_time < timer_.get_pass_time()){
258  last_pass_time = std::chrono::milliseconds{ 0 };
259  count = 0;
260  }
261  timer_.reset(new_pass_time);
262  }
263  inline std::chrono::milliseconds counter::get_pass_time()
264  {
265  return timer_.get_pass_time();
266  }
267 
268  inline size_t counter::get()
269  {
270  update();
271  return count;
272  }
273  inline void counter::reset_count(size_t new_count)
274  {
275  update();
276  count = new_count;
277  }
278 
279  inline void counter::update()
280  {
281  using std::chrono::milliseconds;
282  assert(!timing.empty());
283  assert((std::any_of(timing.begin(), timing.end(), [](const milliseconds& x) { return x.count() > 0; })));
284 
285  milliseconds now_time = timer_.get_pass_time();
286  for (;;)
287  {
288  milliseconds pass_time{ now_time - last_pass_time };
289  if (timing[next_timing_index] <= pass_time) {
290  ++count;
291  last_pass_time += pass_time;
292  ++next_timing_index;
293  next_timing_index %= timing.size();
294  continue;
295  }
296  break;
297  }
298  }
299  }
300 }
301 
302 #endif
#define DXLE_REF_QUALIFIERS_LVALUE
Definition: suffix.hpp:132
std::chrono::milliseconds get_pass_time()
Definition: time.hpp:187
void stop(void)
Definition: time.hpp:173
counter(timing_maker_T &&timing_maker)
Definition: time.hpp:204
std::vector< std::chrono::milliseconds > make_timing() &&override
Definition: time.hpp:89
bool is_stop(void)
Definition: time.hpp:251
Definition: point2d.hpp:672
count_per_second(size_t count, std::chrono::milliseconds millisecond=std::chrono::milliseconds(1000))
Definition: time.hpp:67
std::vector< std::chrono::milliseconds > make_timing() const DXLE_REF_QUALIFIERS_LVALUE override
Definition: time.hpp:84
Definition: cast_if.hpp:12
std::vector< std::chrono::milliseconds > make_timing() const DXLE_REF_QUALIFIERS_LVALUE override
Definition: time.hpp:70
void reset_pass_time(std::chrono::milliseconds=std::chrono::milliseconds{ 0 })
Definition: time.hpp:255
bool is_stop(void)
Definition: time.hpp:178
size_t get()
Definition: time.hpp:268
counter & operator=(const counter &other)
Definition: time.hpp:218
raw_timing(std::vector< std::chrono::milliseconds > timing_)
Definition: time.hpp:81
void start(void)
Definition: time.hpp:166
void reset(std::chrono::milliseconds=std::chrono::milliseconds{ 0 })
Definition: time.hpp:182
void start(void)
Definition: time.hpp:243
void stop(void)
Definition: time.hpp:247
void reset_count(size_t=0)
Definition: time.hpp:273
virtual std::vector< std::chrono::milliseconds > make_timing() &&
Definition: time.hpp:57
std::chrono::milliseconds get_pass_time()
Definition: time.hpp:263