AlexaClientSDK  3.0.0
A cross-platform, modular SDK for interacting with the Alexa Voice Service
Timer.h
Go to the documentation of this file.
1 /*
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
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  * A copy of the License is located at
7  *
8  * http://aws.amazon.com/apache2.0/
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 
16 #ifndef ALEXA_CLIENT_SDK_AVSCOMMON_UTILS_INCLUDE_AVSCOMMON_UTILS_TIMING_TIMER_H_
17 #define ALEXA_CLIENT_SDK_AVSCOMMON_UTILS_INCLUDE_AVSCOMMON_UTILS_TIMING_TIMER_H_
18 
19 #include <chrono>
20 #include <condition_variable>
21 #include <functional>
22 #include <future>
23 #include <mutex>
24 #include <thread>
25 
28 
29 namespace alexaClientSDK {
30 namespace avsCommon {
31 namespace utils {
32 namespace timing {
33 
39 class Timer {
40 public:
45  static constexpr size_t FOREVER = 0;
46 
48  enum class PeriodType {
57  ABSOLUTE,
58 
63  RELATIVE
64  };
65 
72  Timer(
73  const std::shared_ptr<sdkInterfaces::timing::TimerDelegateFactoryInterface>& timerDelegateFactory =
74  avs::initialization::SDKPrimitivesProvider::getInstance()->getTimerDelegateFactory()) noexcept;
75 
79  ~Timer() noexcept;
80 
82  static inline size_t getForever() noexcept {
83  return FOREVER;
84  }
85 
114  template <typename Delay, typename Period, typename Task, typename... Args>
115  bool start(
116  Delay&& delay,
117  Period&& period,
118  PeriodType periodType,
119  size_t maxCount,
120  Task&& task,
121  Args&&... args) noexcept;
122 
147  template <typename Period, typename Task, typename... Args>
148  bool start(Period&& period, PeriodType periodType, size_t maxCount, Task&& task, Args&&... args) noexcept;
149 
171  template <typename Delay, typename Task, typename... Args>
172  auto start(Delay&& delay, Task&& task, Args&&... args) noexcept -> std::future<decltype(task(args...))>;
173 
184  void stop() noexcept;
185 
195  bool isActive() const noexcept;
196 
197 private:
201  static constexpr size_t ONCE = 1u;
202 
208  bool activate() noexcept;
209 
221  bool callTask(
222  const std::chrono::nanoseconds& delayNano,
223  const std::chrono::nanoseconds& periodNano,
224  PeriodType periodType,
225  size_t maxCount,
226  std::function<void()>&& task) noexcept;
227 
242  template <typename Delay, typename Period>
243  bool adaptTypesAndCallTask(
244  const Delay& delayNano,
245  const Period& periodNano,
246  PeriodType periodType,
247  size_t maxCount,
248  std::function<void()>&& task) noexcept;
249 
251  std::unique_ptr<sdkInterfaces::timing::TimerDelegateInterface> m_timer;
252 
254  std::thread m_thread;
255 };
256 
257 template <typename Delay, typename Period, typename Task, typename... Args>
259  Delay&& delay,
260  Period&& period,
261  PeriodType periodType,
262  size_t maxCount,
263  Task&& task,
264  Args&&... args) noexcept {
265  // convert arguments to lambda
266  auto boundTask = std::bind(std::forward<Task>(task), std::forward<Args>(args)...);
267 
268  // Kick off the new timer thread.
269  return adaptTypesAndCallTask(
270  std::forward<Delay>(delay), std::forward<Period>(period), periodType, maxCount, std::move(boundTask));
271 }
272 
273 template <typename Period, typename Task, typename... Args>
274 bool Timer::start(Period&& period, PeriodType periodType, size_t maxCount, Task&& task, Args&&... args) noexcept {
275  // convert arguments to lambda
276  auto boundTask = std::bind(std::forward<Task>(task), std::forward<Args>(args)...);
277 
278  // Kick off the new timer thread.
279  return adaptTypesAndCallTask(
280  std::forward<Period>(period), std::forward<Period>(period), periodType, maxCount, std::move(boundTask));
281 }
282 
283 template <typename Delay, typename Task, typename... Args>
284 auto Timer::start(Delay&& delay, Task&& task, Args&&... args) noexcept -> std::future<decltype(task(args...))> {
285  // Task result value type.
286  using Value = decltype(task(args...));
287 
288  // Remove arguments from the task's type by binding the arguments to the task.
289  auto boundTask = std::bind(std::forward<Task>(task), std::forward<Args>(args)...);
290 
291  /*
292  * Create a std::packaged_task with the correct return type. The reference will be passed into execution context
293  * and will not be shared between threads.
294  */
295  auto packagedTask = std::make_shared<std::packaged_task<Value()>>(std::move(boundTask));
296  // Get future object reference for function result.
297  auto packagedTaskFuture = packagedTask->get_future();
298 
299  // Remove the return type from the task by wrapping it in a lambda with no return value.
300  auto translatedTask = std::bind(&std::packaged_task<Value()>::operator(), std::move(packagedTask));
301 
302  // Kick off the new timer thread.
303  if (!adaptTypesAndCallTask(
304  std::forward<Delay>(delay),
305  std::forward<Delay>(delay),
307  ONCE,
308  std::move(translatedTask))) {
309  return std::future<Value>();
310  }
311 
312  return packagedTaskFuture;
313 }
314 
315 template <typename Delay, typename Period>
316 bool Timer::adaptTypesAndCallTask(
317  const Delay& delay,
318  const Period& period,
319  PeriodType periodType,
320  size_t maxCount,
321  std::function<void()>&& task) noexcept {
322  return callTask(delay, period, periodType, maxCount, std::move(task));
323 }
324 
325 // Externalize templates for common parameter types.
326 extern template bool Timer::adaptTypesAndCallTask(
327  const std::chrono::milliseconds&,
328  const std::chrono::milliseconds&,
329  PeriodType,
330  size_t,
331  std::function<void()>&&) noexcept;
332 extern template bool Timer::adaptTypesAndCallTask(
333  const std::chrono::nanoseconds&,
334  const std::chrono::nanoseconds&,
335  PeriodType,
336  size_t,
337  std::function<void()>&&) noexcept;
338 
339 } // namespace timing
340 } // namespace utils
341 } // namespace avsCommon
342 } // namespace alexaClientSDK
343 
344 #endif // ALEXA_CLIENT_SDK_AVSCOMMON_UTILS_INCLUDE_AVSCOMMON_UTILS_TIMING_TIMER_H_
def args
Definition: android_test.py:111
PeriodType
Specifies different ways to apply the period of a recurring task.
Definition: Timer.h:48
internal::ArgsMatcher< InnerMatcher > Args(const InnerMatcher &matcher)
Definition: gmock-generated-matchers.h:481
static size_t getForever() noexcept
Static member function to get FOREVER.
Definition: Timer.h:82
bool start(Delay &&delay, Period &&period, PeriodType periodType, size_t maxCount, Task &&task, Args &&... args) noexcept
Submit a callable type for periodic execution.
Definition: Timer.h:258
void stop() noexcept
Stop the timer.
bool Value(const T &value, M matcher)
Definition: gmock-matchers.h:4347
Timer to schedule task for delayed and periodic execution.
Definition: Timer.h:39
static constexpr size_t FOREVER
Definition: Timer.h:45
Whether or not curl logs should be emitted.
Definition: AVSConnectionManager.h:36
static std::shared_ptr< SDKPrimitivesProvider > getInstance()
Timer(const std::shared_ptr< sdkInterfaces::timing::TimerDelegateFactoryInterface > &timerDelegateFactory=avs::initialization::SDKPrimitivesProvider::getInstance() ->getTimerDelegateFactory()) noexcept
Constructs a Timer.
const T & move(const T &t)
Definition: gtest-port.h:1317
bool isActive() const noexcept
Check if timer is active.

AlexaClientSDK 3.0.0 - Copyright 2016-2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. Licensed under the Apache License, Version 2.0