LeechCraft  0.6.70-18450-gabe19ee3b0
Modular cross-platform feature rich live environment.
throttle.cpp
Go to the documentation of this file.
1 /**********************************************************************
2  * LeechCraft - modular cross-platform feature rich internet client.
3  * Copyright (C) 2006-2014 Georg Rudoy
4  *
5  * Distributed under the Boost Software License, Version 1.0.
6  * (See accompanying file LICENSE or copy at https://www.boost.org/LICENSE_1_0.txt)
7  **********************************************************************/
8 
9 #include "throttle.h"
10 #include <QTimer>
11 
12 namespace LC::Util
13 {
14  Throttle::Throttle (std::chrono::milliseconds interval, Qt::TimerType type)
15  : Interval_ { interval }
16  {
17  LastInvocation_.start ();
18 
19  Timer_.setTimerType (type);
20  Timer_.setSingleShot (true);
21  Timer_.callOnTimeout ([this]
22  {
23  LastInvocation_.restart ();
24 
25  if (Queue_.size () > 1)
26  StartTimer (Interval_);
27  if (!Queue_.isEmpty ())
28  Queue_.takeFirst () ();
29  });
30  }
31 
32  std::chrono::milliseconds Throttle::GetInterval () const
33  {
34  return Interval_;
35  }
36 
38  {
39  BackoffFactor_ += 2;
40  }
41 
43  : Throttle_ { throttle }
44  {
45  }
46 
48  : Throttle_ { other.Throttle_ }
49  , Handle_ { std::exchange (other.Handle_, {}) }
50  {
51  }
52 
53  Throttle::Awaiter::~Awaiter ()
54  {
55  if (Handle_)
56  Throttle_.Queue_.removeOne (Handle_);
57  }
58 
59  bool Throttle::Awaiter::await_ready () const
60  {
61  const bool allowed = std::chrono::milliseconds { Throttle_.LastInvocation_.elapsed () } >= Throttle_.Interval_ && Throttle_.Queue_.isEmpty ();
62  if (allowed)
63  Throttle_.LastInvocation_.restart ();
64  return allowed;
65  }
66 
67  void Throttle::Awaiter::await_suspend (std::coroutine_handle<> handle)
68  {
69  if (Throttle_.Queue_.isEmpty ())
70  Throttle_.StartTimer (Throttle_.Interval_ - std::chrono::milliseconds { Throttle_.LastInvocation_.elapsed () });
71 
72  Throttle_.Queue_ << handle;
73  Handle_ = handle;
74  }
75 
76  void Throttle::Awaiter::await_resume ()
77  {
78  Handle_ = {};
79  }
80 
81  Throttle::Awaiter Throttle::operator co_await ()
82  {
83  return Awaiter { *this };
84  }
85 
86  void Throttle::StartTimer (std::chrono::milliseconds timeout)
87  {
88  BackoffFactor_ = std::max (0, BackoffFactor_ - 1);
89  Timer_.start (timeout * (BackoffFactor_ + 1));
90  }
91 }
decltype(auto) Awaiter(T &&obj)
Definition: context.h:38
constexpr detail::AggregateType< detail::AggregateFunction::Max, Ptr > max
Definition: oral.h:1110
Throttle(std::chrono::milliseconds, Qt::TimerType=Qt::TimerType::CoarseTimer)
Definition: throttle.cpp:14
std::chrono::milliseconds GetInterval() const
Definition: throttle.cpp:32
auto Tup2 &&tup2 noexcept
Definition: ctstringutils.h:68