Introduce slint::run_event_loop_until_quit

Closes #1499
This commit is contained in:
Olivier Goffart 2024-01-11 13:52:02 +01:00 committed by GitHub
parent e1c5f4ff03
commit 9111946a82
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 192 additions and 44 deletions

View file

@ -25,13 +25,24 @@ struct TestPlatform : slint::platform::Platform
/// Returns a new WindowAdapter
virtual std::unique_ptr<slint::platform::WindowAdapter> create_window_adapter() override
{
#ifdef SLINT_FEATURE_RENDERER_SOFTWARE
struct TestWindowAdapter : slint::platform::WindowAdapter
{
slint::platform::SoftwareRenderer r { {} };
slint::PhysicalSize size() override { return slint::PhysicalSize({}); }
slint::platform::AbstractRenderer &renderer() override { return r; }
};
return std::make_unique<TestWindowAdapter>();
#else
assert(!"creating window in this test");
return nullptr;
#endif
};
/// Spins an event loop and renders the visible windows.
virtual void run_event_loop() override
{
quit = false;
while (true) {
slint::platform::update_timers_and_animations();
std::optional<slint::platform::Platform::Task> event;
@ -103,14 +114,14 @@ TEST_CASE("C++ Repeated Timer")
int timer_triggered = 0;
slint::Timer timer;
timer.start(slint::TimerMode::Repeated, std::chrono::milliseconds(30),
timer.start(slint::TimerMode::Repeated, std::chrono::milliseconds(3),
[&]() { timer_triggered++; });
REQUIRE(timer_triggered == 0);
bool timer_was_running = false;
slint::Timer::single_shot(std::chrono::milliseconds(500), [&]() {
slint::Timer::single_shot(std::chrono::milliseconds(100), [&]() {
timer_was_running = timer.running();
slint::quit_event_loop();
});
@ -126,7 +137,7 @@ TEST_CASE("C++ Restart Singleshot Timer")
int timer_triggered = 0;
slint::Timer timer;
timer.start(slint::TimerMode::SingleShot, std::chrono::milliseconds(30),
timer.start(slint::TimerMode::SingleShot, std::chrono::milliseconds(3),
[&]() { timer_triggered++; });
REQUIRE(timer.running());
@ -134,7 +145,7 @@ TEST_CASE("C++ Restart Singleshot Timer")
bool timer_was_running = true;
slint::Timer::single_shot(std::chrono::milliseconds(500), [&]() {
slint::Timer::single_shot(std::chrono::milliseconds(50), [&]() {
timer_was_running = timer.running();
slint::quit_event_loop();
});
@ -148,7 +159,7 @@ TEST_CASE("C++ Restart Singleshot Timer")
timer_triggered = 0;
timer.restart();
REQUIRE(timer.running());
slint::Timer::single_shot(std::chrono::milliseconds(500), [&]() {
slint::Timer::single_shot(std::chrono::milliseconds(50), [&]() {
timer_was_running = timer.running();
slint::quit_event_loop();
});
@ -164,14 +175,14 @@ TEST_CASE("C++ Restart Repeated Timer")
int timer_triggered = 0;
slint::Timer timer;
timer.start(slint::TimerMode::Repeated, std::chrono::milliseconds(30),
timer.start(slint::TimerMode::Repeated, std::chrono::milliseconds(3),
[&]() { timer_triggered++; });
REQUIRE(timer_triggered == 0);
bool timer_was_running = false;
slint::Timer::single_shot(std::chrono::milliseconds(500), [&]() {
slint::Timer::single_shot(std::chrono::milliseconds(50), [&]() {
timer_was_running = timer.running();
slint::quit_event_loop();
});
@ -184,7 +195,7 @@ TEST_CASE("C++ Restart Repeated Timer")
timer_was_running = false;
timer_triggered = 0;
timer.stop();
slint::Timer::single_shot(std::chrono::milliseconds(500), [&]() {
slint::Timer::single_shot(std::chrono::milliseconds(50), [&]() {
timer_was_running = timer.running();
slint::quit_event_loop();
});
@ -199,7 +210,7 @@ TEST_CASE("C++ Restart Repeated Timer")
timer.restart();
slint::Timer::single_shot(std::chrono::milliseconds(500), [&]() {
slint::Timer::single_shot(std::chrono::milliseconds(50), [&]() {
timer_was_running = timer.running();
slint::quit_event_loop();
});
@ -258,3 +269,96 @@ TEST_CASE("Blocking Event from thread")
REQUIRE(called == 42);
t.join();
}
#if defined(SLINT_FEATURE_INTERPRETER) && defined(SLINT_FEATURE_RENDERER_SOFTWARE)
# include <slint-interpreter.h>
TEST_CASE("Quit on last window closed")
{
using namespace slint::interpreter;
using namespace slint;
int ok = 0;
ComponentCompiler compiler;
auto comp_def = compiler.build_from_source("export component App inherits Window { }", "");
REQUIRE(comp_def.has_value());
auto instance = comp_def->create();
instance->hide(); // hide before show should mess the counter
REQUIRE(instance->window().is_visible() == false);
instance->show();
REQUIRE(instance->window().is_visible() == true);
slint::Timer::single_shot(std::chrono::milliseconds(10), [&]() {
REQUIRE(instance->window().is_visible() == true);
instance->hide();
REQUIRE(instance->window().is_visible() == false);
ok = 1;
slint::Timer::single_shot(std::chrono::milliseconds(0), [&]() {
// event loop should be stopped
ok = -1;
});
});
slint::run_event_loop();
REQUIRE(ok == 1);
REQUIRE(instance->window().is_visible() == false);
ok = 0;
slint::Timer::single_shot(std::chrono::milliseconds(5), [&]() {
REQUIRE(ok == -1); // the event we started previously should have been ran first
ok = 1;
REQUIRE(instance->window().is_visible() == false);
instance->show();
instance->show(); // two show shouldn't make the loop alive
slint::Timer::single_shot(std::chrono::milliseconds(0), [&]() {
REQUIRE(instance->window().is_visible() == true);
instance->hide();
ok = 2;
slint::Timer::single_shot(std::chrono::milliseconds(0), [&]() {
// event loop should be stopped
ok = -2;
});
});
});
slint::run_event_loop();
REQUIRE(ok == 2);
ok = 0;
auto instance2 = comp_def->create();
instance2->show();
slint::Timer::single_shot(std::chrono::milliseconds(5), [&]() {
REQUIRE(ok == -2); // the event we started previously should have been ran first
instance->show();
instance2->hide();
slint::Timer::single_shot(std::chrono::milliseconds(0), [&]() {
instance2->show();
instance->hide();
slint::Timer::single_shot(std::chrono::milliseconds(0), [&]() {
instance2->hide();
ok = 3;
});
});
});
slint::run_event_loop();
REQUIRE(ok == 3);
ok = 0;
slint::Timer::single_shot(std::chrono::milliseconds(0), [&]() {
REQUIRE(ok == 0);
instance->show();
slint::Timer::single_shot(std::chrono::milliseconds(0), [&]() {
instance2->hide();
instance->hide();
slint::Timer::single_shot(std::chrono::milliseconds(0), [&]() {
instance2->show();
slint::quit_event_loop();
ok = 4;
});
});
});
slint::run_event_loop(slint::EventLoopMode::RunUntilQuit);
REQUIRE(ok == 4);
}
#endif

View file

@ -1,4 +1,4 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial
export Test := Rectangle {}
export componentTest := Rectangle {}