Easy3D 2.5.3
Test_Timer
1/********************************************************************
2 * Copyright (C) 2015 Liangliang Nan <liangliang.nan@gmail.com>
3 * https://3d.bk.tudelft.nl/liangliang/
4 *
5 * This file is part of Easy3D. If it is useful in your research/work,
6 * I would be grateful if you show your appreciation by citing it:
7 * ------------------------------------------------------------------
8 * Liangliang Nan.
9 * Easy3D: a lightweight, easy-to-use, and efficient C++ library
10 * for processing and rendering 3D data.
11 * Journal of Open Source Software, 6(64), 3255, 2021.
12 * ------------------------------------------------------------------
13 *
14 * Easy3D is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License Version 3
16 * as published by the Free Software Foundation.
17 *
18 * Easy3D is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 ********************************************************************/
26
27
28#include <easy3d/util/timer.h>
29#include <easy3d/core/signal.h>
30
31#include <iostream>
32#include <string>
33#include <mutex>
34
35std::mutex mutex;
36
37using namespace easy3d;
38
39// Trivial classes (that do not make sense, but can show the use of the Signal class).
40
41class Vehicle {
42public:
43 virtual void start() {
44 std::lock_guard<std::mutex> guard(mutex);
45 std::cout << "do nothing\n";
46 }
47};
48
49class Car : public Vehicle {
50public:
51 Car(int speed) : speed_(speed) {}
52
53public:
54 int speed() const { return speed_; }
55
56 void start() override {
57 std::lock_guard<std::mutex> guard(mutex);
58 std::cout << "started\n";
59 }
60
61 void start(int new_speed) {
62 std::lock_guard<std::mutex> guard(mutex);
63 std::cout << "speed changed from " << speed_ << " to " << new_speed << "\n";
64 speed_ = new_speed;
65 }
66
67 void stop(int hours, const std::string &msg) const {
68 std::lock_guard<std::mutex> guard(mutex);
69 std::cout << msg << ". After driving for " << hours << " hours\n";
70 }
71
72private:
73 int speed_;
74};
75
76
77void test_timer_for_members(Car *car) {
78 // ---- a non-const class member, no argument
79 Timer<>::single_shot(33, car, &Car::start);
80
81 // ---- a non-const overloaded class member, one argument
82 Timer<int>::single_shot(33, car, &Car::start, 100);
83
84 // ---- a const class member, two arguments
85 Timer<int, const std::string &>::single_shot(33, car, &Car::stop, 6, "I have to stop");
86
87 {
88 static Timer<> t;
89 t.single_shot(33, car, &Car::start); // This works
90 t.set_interval(33, car, &Car::start); // This also works
91 t.set_timeout(33, car, &Car::start);
93 }
94
95 {
96 static Timer<int> t;
97 t.single_shot(33, car, &Car::start, 100);
98 t.set_interval(33, car, &Car::start, 100);
99 t.set_timeout(33, car, &Car::start, 100);
101 }
102
103 {
105 t.single_shot(33, car, &Car::stop, 6, "I have to stop");
106 t.set_interval(33, car, &Car::stop, 6, "I have to stop");
107 t.set_timeout(33, car, &Car::stop, 6, "I have to stop");
109 }
110}
111
112
113void timer_func_start() {
114 std::lock_guard<std::mutex> guard(mutex);
115 std::cout << "started\n";
116}
117
118void timer_func_start(Car *car) {
119 std::lock_guard<std::mutex> guard(mutex);
120 std::cout << "speed is " << car->speed() << "\n";
121}
122
123void timer_func_report_speed(int max_allow_speed, const Car *car) {
124 std::lock_guard<std::mutex> guard(mutex);
125 std::cout << "max allowed is " << max_allow_speed << ". I am at " << car->speed() << "\n";
126}
127
128void timer_func_stop(const Car *car, int hours, const std::string &msg) {
129 std::lock_guard<std::mutex> guard(mutex);
130 std::cout << msg << " after driving for " << hours << " hours. My speed was " << car->speed() << "\n";
131}
132
133
134void test_timer_for_functions(Car *car) {
135 // ---- no argument
136
137 Timer<>::single_shot(33, static_cast<void (*)(void)> (timer_func_start));
138 Timer<>::single_shot(33, overload<>(timer_func_start)); // also works
139
140 // ---- one argument
141 Timer<Car *>::single_shot(33, static_cast<void (*)(Car *)> (timer_func_start), car);
142 Timer<Car *>::single_shot(33, overload<Car *> (timer_func_start), car);
143
144
145 // ---- two argument
146 Timer<int, const Car *>::single_shot(33, timer_func_report_speed, 120, car);
147
148 // ---- three arguments
149 Timer<const Car *, int, const std::string &>::single_shot(333, timer_func_stop, car, 6, "I have to stop");
150
151 { // ---- no argument
152 static Timer<> t;
153 t.single_shot(33, static_cast<void (*)(void)> (timer_func_start));
154 t.single_shot(33, overload<>(timer_func_start)); // also works
155
156 t.set_interval(33, static_cast<void (*)(void)> (timer_func_start));
157 t.set_interval(33, overload<>(timer_func_start)); // also works
158
159 t.set_timeout(33, static_cast<void (*)(void)> (timer_func_start));
160 t.set_timeout(33, overload<>(timer_func_start)); // also works
161
163 }
164
165 { // ---- one argument
166 static Timer<Car *> t;
167 t.single_shot(33, static_cast<void (*)(Car *)> (timer_func_start), car);
168 t.single_shot(33, overload<Car*> (timer_func_start), car); // also works
169
170 t.set_interval(33, static_cast<void (*)(Car *)> (timer_func_start), car);
171 t.set_interval(33, overload<Car*> (timer_func_start), car); // also works
172
173 t.set_timeout(33, static_cast<void (*)(Car *)> (timer_func_start), car);
174 t.set_timeout(33, overload<Car*> (timer_func_start), car); // also works
175
177 }
178
179 { // ---- two argument
181 t.single_shot(33, timer_func_report_speed, 120, car);
182 t.set_interval(33, timer_func_report_speed, 120, car);
183 t.set_timeout(33, timer_func_report_speed, 120, car);
185 }
186
187 { // ---- three arguments
189 t.single_shot(333, timer_func_stop, car, 6, "I have to stop");
190 t.set_interval(333, timer_func_stop, car, 6, "I have to stop");
191 t.set_timeout(333, timer_func_stop, car, 6, "I have to stop");
193 }
194}
195
196
197void test_timer_for_lambda_functions(Car *car) {
198 auto lambda_start = []() -> void {
199 std::lock_guard<std::mutex> guard(mutex);
200 std::cout << "started\n";
201 };
202
203 auto lambda_start_1arg = [](Car *car) -> void {
204 std::lock_guard<std::mutex> guard(mutex);
205 std::cout << "speed is " << car->speed() << "\n";
206 };
207
208 auto lambda_report_speed = [](int max_allow_speed, const Car *car) -> void {
209 std::lock_guard<std::mutex> guard(mutex);
210 std::cout << "max allowed is " << max_allow_speed << ". I am at " << car->speed() << "\n";
211 };
212
213 auto lambda_stop = [](const Car *car, int hours, const std::string &msg) -> void {
214 std::lock_guard<std::mutex> guard(mutex);
215 std::cout << msg << " after driving for " << hours << " hours. My speed was " << car->speed() << "\n";
216 };
217
218 // ---- no argument
219 Timer<>::single_shot(33, lambda_start);
220
221 // ---- one argument
222 Timer<Car *>::single_shot(33, lambda_start_1arg, car);
223
224 // ---- two argument
225 Timer<int, const Car *>::single_shot(33, lambda_report_speed, 120, car);
226
227 // ---- three arguments
228 Timer<const Car *, int, const std::string &>::single_shot(33, lambda_stop, car, 6, "I have to stop");
229
230 { // ---- no argument
231 static Timer<> t;
232 t.single_shot(33, lambda_start);
233 t.set_interval(33, lambda_start);
234 t.set_timeout(33, lambda_start);
236 }
237
238 { // ---- one argument
239 static Timer<Car *> t;
240 t.single_shot(33, lambda_start_1arg, car);
241 t.set_interval(33, lambda_start_1arg, car);
242 t.set_timeout(33, lambda_start_1arg, car);
244 }
245
246 { // ---- two argument
248 t.single_shot(33, lambda_report_speed, 120, car);
249 t.set_interval(33, lambda_report_speed, 120, car);
250 t.set_timeout(33, lambda_report_speed, 120, car);
252 }
253
254 { // ---- three arguments
256 t.single_shot(333, lambda_stop, car, 6, "I have to stop");
257 t.set_interval(333, lambda_stop, car, 6, "I have to stop");
258 t.set_timeout(333, lambda_stop, car, 6, "I have to stop");
260 }
261}
262
263
264int test_timer() {
265 Car car(100);
266
267 std::cout << "triggers a class member ------------------------------------------------------------------\n";
268 test_timer_for_members(&car);
269 std::this_thread::sleep_for(std::chrono::seconds(1));
270
271 std::cout << "\ntriggers a function ------------------------------------------------------------------\n";
272 test_timer_for_functions(&car);
273 std::this_thread::sleep_for(std::chrono::seconds(1));
274
275 std::cout << "\ntriggers a lambda function -----------------------------------------------------------\n";
276 test_timer_for_lambda_functions(&car);
277 std::this_thread::sleep_for(std::chrono::seconds(1));
278
279 return EXIT_SUCCESS;
280}
A light-weight implementation of the timer mechanism.
Definition: timer.h:49
void set_interval(int interval, std::function< void(Args...)> const &func, Args... args) const
Executes function func for every interval milliseconds.
Definition: timer.h:268
static void single_shot(int delay, std::function< void(Args...)> const &func, Args... args)
Executes function func after delay milliseconds.
Definition: timer.h:195
void set_timeout(int delay, std::function< void(Args...)> const &func, Args... args) const
Executes function func after delay milliseconds.
Definition: timer.h:227
Definition: collider.cpp:182