1 | // Copyright © SixtyFPS GmbH <info@slint.dev> |
2 | // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial |
3 | |
4 | // cSpell: ignore singleshot |
5 | |
6 | #define CATCH_CONFIG_MAIN |
7 | #include "catch2/catch.hpp" |
8 | |
9 | #include <slint.h> |
10 | #include <thread> |
11 | |
12 | TEST_CASE("C++ Singleshot Timers" ) |
13 | { |
14 | using namespace slint; |
15 | int called = 0; |
16 | Timer testTimer(std::chrono::milliseconds(16), [&]() { |
17 | slint::quit_event_loop(); |
18 | called += 10; |
19 | }); |
20 | REQUIRE(called == 0); |
21 | slint::run_event_loop(); |
22 | REQUIRE(called == 10); |
23 | } |
24 | |
25 | TEST_CASE("C++ Repeated Timer" ) |
26 | { |
27 | int timer_triggered = 0; |
28 | slint::Timer timer; |
29 | |
30 | timer.start(slint::TimerMode::Repeated, std::chrono::milliseconds(30), |
31 | [&]() { timer_triggered++; }); |
32 | |
33 | REQUIRE(timer_triggered == 0); |
34 | |
35 | bool timer_was_running = false; |
36 | |
37 | slint::Timer::single_shot(std::chrono::milliseconds(500), [&]() { |
38 | timer_was_running = timer.running(); |
39 | slint::quit_event_loop(); |
40 | }); |
41 | |
42 | slint::run_event_loop(); |
43 | |
44 | REQUIRE(timer_triggered > 1); |
45 | REQUIRE(timer_was_running); |
46 | } |
47 | |
48 | TEST_CASE("C++ Restart Singleshot Timer" ) |
49 | { |
50 | int timer_triggered = 0; |
51 | slint::Timer timer; |
52 | |
53 | timer.start(slint::TimerMode::SingleShot, std::chrono::milliseconds(30), |
54 | [&]() { timer_triggered++; }); |
55 | |
56 | REQUIRE(timer_triggered == 0); |
57 | REQUIRE(timer.running()); |
58 | |
59 | bool timer_was_running = true; |
60 | |
61 | slint::Timer::single_shot(std::chrono::milliseconds(500), [&]() { |
62 | timer_was_running = timer.running(); |
63 | slint::quit_event_loop(); |
64 | }); |
65 | |
66 | slint::run_event_loop(); |
67 | |
68 | REQUIRE(!timer.running()); |
69 | REQUIRE(timer_triggered == 1); |
70 | REQUIRE(!timer_was_running); // At that point the timer is already considered stopped! |
71 | |
72 | timer_triggered = 0; |
73 | timer_was_running = true; |
74 | |
75 | timer.restart(); |
76 | REQUIRE(timer.running()); |
77 | slint::Timer::single_shot(std::chrono::milliseconds(500), [&]() { |
78 | timer_was_running = timer.running(); |
79 | slint::quit_event_loop(); |
80 | }); |
81 | |
82 | slint::run_event_loop(); |
83 | |
84 | REQUIRE(timer_triggered == 1); |
85 | REQUIRE(!timer_was_running); |
86 | REQUIRE(!timer.running()); |
87 | } |
88 | |
89 | TEST_CASE("C++ Restart Repeated Timer" ) |
90 | { |
91 | int timer_triggered = 0; |
92 | slint::Timer timer; |
93 | |
94 | timer.start(slint::TimerMode::Repeated, std::chrono::milliseconds(30), |
95 | [&]() { timer_triggered++; }); |
96 | |
97 | REQUIRE(timer_triggered == 0); |
98 | |
99 | bool timer_was_running = false; |
100 | |
101 | slint::Timer::single_shot(std::chrono::milliseconds(500), [&]() { |
102 | timer_was_running = timer.running(); |
103 | slint::quit_event_loop(); |
104 | }); |
105 | |
106 | slint::run_event_loop(); |
107 | |
108 | REQUIRE(timer_triggered > 1); |
109 | REQUIRE(timer_was_running); |
110 | |
111 | timer_was_running = false; |
112 | timer_triggered = 0; |
113 | timer.stop(); |
114 | slint::Timer::single_shot(std::chrono::milliseconds(500), [&]() { |
115 | timer_was_running = timer.running(); |
116 | slint::quit_event_loop(); |
117 | }); |
118 | |
119 | slint::run_event_loop(); |
120 | |
121 | REQUIRE(timer_triggered == 0); |
122 | REQUIRE(!timer_was_running); |
123 | |
124 | timer_was_running = false; |
125 | timer_triggered = 0; |
126 | |
127 | timer.restart(); |
128 | |
129 | slint::Timer::single_shot(std::chrono::milliseconds(500), [&]() { |
130 | timer_was_running = timer.running(); |
131 | slint::quit_event_loop(); |
132 | }); |
133 | |
134 | slint::run_event_loop(); |
135 | |
136 | REQUIRE(timer_triggered > 1); |
137 | REQUIRE(timer_was_running); |
138 | } |
139 | |
140 | TEST_CASE("Quit from event" ) |
141 | { |
142 | int called = 0; |
143 | slint::invoke_from_event_loop([&] { |
144 | slint::quit_event_loop(); |
145 | called += 10; |
146 | }); |
147 | REQUIRE(called == 0); |
148 | slint::run_event_loop(); |
149 | REQUIRE(called == 10); |
150 | } |
151 | |
152 | TEST_CASE("Event from thread" ) |
153 | { |
154 | std::atomic<int> called = 0; |
155 | auto t = std::thread([&] { |
156 | called += 10; |
157 | slint::invoke_from_event_loop([&] { |
158 | called += 100; |
159 | slint::quit_event_loop(); |
160 | }); |
161 | }); |
162 | |
163 | slint::run_event_loop(); |
164 | REQUIRE(called == 110); |
165 | t.join(); |
166 | } |
167 | |
168 | TEST_CASE("Blocking Event from thread" ) |
169 | { |
170 | std::atomic<int> called = 0; |
171 | auto t = std::thread([&] { |
172 | // test returning a, unique_ptr because it is movable-only |
173 | std::unique_ptr foo = |
174 | slint::blocking_invoke_from_event_loop([&] { return std::make_unique<int>(42); }); |
175 | called = *foo; |
176 | int xxx = 123; |
177 | slint::blocking_invoke_from_event_loop([&] { |
178 | slint::quit_event_loop(); |
179 | xxx = 888999; |
180 | }); |
181 | REQUIRE(xxx == 888999); |
182 | }); |
183 | |
184 | slint::run_event_loop(); |
185 | REQUIRE(called == 42); |
186 | t.join(); |
187 | } |
188 | |