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
12TEST_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
25TEST_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
48TEST_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
89TEST_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
140TEST_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
152TEST_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
168TEST_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

source code of slint/api/cpp/tests/eventloop.cpp