blob: 0f46de7f774a30e4e748680b78eb9e446ceca148 [file] [log] [blame]
Matt Spinlerd82a5f42017-07-24 13:40:37 -05001#pragma once
2
3#include <chrono>
4#include <functional>
5#include <memory>
6#include "event.hpp"
7
8namespace witherspoon
9{
10namespace power
11{
12
13
14/**
15 * @class Timer
16 *
17 * This class implements a simple timer that runs an arbitrary
18 * function on expiration. The timeout value is set in microseconds.
19 * It can be stopped while it is running, and queried to see if it is
20 * running.
21 *
22 * If started with the 'repeating' argument, it will keep calling the
23 * callback function every <timeout> microseconds. If started with the
24 * 'oneshot' argument, it will just call the callback function one time.
25 *
26 * It needs an sd_event loop to function.
27 */
28class Timer
29{
30 public:
31
32 enum class TimerType
33 {
34 oneshot,
35 repeating
36 };
37
38 Timer() = delete;
39 Timer(const Timer&) = delete;
40 Timer& operator=(const Timer&) = delete;
41 Timer(Timer&&) = default;
42 Timer& operator=(Timer&&) = default;
43
44 /**
45 * @brief Constructs timer object
46 *
47 * @param[in] events - sd_event pointer, previously created
48 * @param[in] callbackFunc - The function to call on timer expiration
49 */
50 Timer(event::Event& events,
51 std::function<void()> callbackFunc);
52
53 /**
54 * @brief Destructor
55 */
56 ~Timer();
57
58 /**
59 * @brief Starts the timer
60 *
61 * The input is an offset from the current steady clock.
62 *
63 * @param[in] usec - the timeout value in microseconds
64 * @param[in] type - either a oneshot, or repeating
65 */
66 void start(std::chrono::microseconds usec,
67 TimerType type = TimerType::oneshot);
68
69 /**
70 * @brief Stop the timer
71 */
72 void stop();
73
74 /**
75 * @brief Returns true if the timer is running
76 */
77 bool running();
78
79 /**
80 * @brief Returns the timeout value
81 *
82 * @return - the last value sent in via start().
83 */
84 inline auto getTimeout() const
85 {
86 return timeout;
87 }
88
89 /**
90 * @brief Returns the timer type
91 */
92 inline auto getType() const
93 {
94 return type;
95 }
96
97 private:
98
99 /**
100 * @brief Callback function when timer goes off
101 *
102 * Calls the callback function passed in by the user.
103 *
104 * @param[in] eventSource - Source of the event
105 * @param[in] usec - time in micro seconds
106 * @param[in] userData - User data pointer
107 */
108 static int timeoutHandler(sd_event_source* eventSource,
109 uint64_t usec, void* userData);
110
111 /**
112 * @brief Gets the current time from the steady clock
113 */
114 std::chrono::microseconds getTime();
115
116 /**
117 * @brief Wrapper around sd_event_source_set_enabled
118 *
119 * @param[in] action - either SD_EVENT_OFF, SD_EVENT_ON,
120 * or SD_EVENT_ONESHOT
121 */
122 void setTimer(int action);
123
124
125 /**
126 * @brief Sets the expiration time for the timer
127 *
128 * Sets it to timeout microseconds in the future
129 */
130 void setTimeout();
131
132 /**
133 * @brief The sd_event structure
134 */
135 event::Event& timeEvent;
136
137 /**
138 * @brief Source of events
139 */
140 event::EventSource eventSource;
141
142 /**
143 * @brief Either 'repeating' or 'oneshot'
144 */
145 TimerType type = TimerType::oneshot;
146
147 /**
148 * @brief The function to call when the timer expires
149 */
150 std::function<void()> callback;
151
152 /**
153 * @brief What the timer was set to run for
154 *
155 * Not cleared on timer expiration
156 */
157 std::chrono::microseconds timeout;
158};
159
160}
161}