mirror of
https://github.com/slint-ui/slint.git
synced 2025-11-02 21:03:00 +00:00
C++ platform: duration_until_next_timer_update and change return type of duration_since_start
This commit is contained in:
parent
de532d372a
commit
81bb6e2c70
3 changed files with 158 additions and 4 deletions
|
|
@ -216,7 +216,7 @@ public:
|
|||
/// Returns the amount of milliseconds since start of the application.
|
||||
///
|
||||
/// This function should only be implemented if the runtime is compiled with no_std
|
||||
virtual uint64_t duration_since_start() const { return 0; }
|
||||
virtual std::chrono::milliseconds duration_since_start() const { return {}; }
|
||||
|
||||
/// Spins an event loop and renders the visible windows.
|
||||
virtual void run_event_loop() { }
|
||||
|
|
@ -248,7 +248,7 @@ public:
|
|||
(void)w.release();
|
||||
},
|
||||
[](void *p) -> uint64_t {
|
||||
return reinterpret_cast<const Platform *>(p)->duration_since_start();
|
||||
return reinterpret_cast<const Platform *>(p)->duration_since_start().count();
|
||||
},
|
||||
[](void *p) { return reinterpret_cast<Platform *>(p)->run_event_loop(); },
|
||||
[](void *p) { return reinterpret_cast<Platform *>(p)->quit_event_loop(); },
|
||||
|
|
@ -427,6 +427,19 @@ inline void update_timers_and_animations()
|
|||
cbindgen_private::slint_platform_update_timers_and_animations();
|
||||
}
|
||||
|
||||
/// Returns the duration until the next timer if there are pending timers
|
||||
inline std::optional<std::chrono::milliseconds> duration_until_next_timer_update()
|
||||
{
|
||||
uint64_t val = cbindgen_private::slint_platform_duration_until_next_timer_update();
|
||||
if (val == std::numeric_limits<uint64_t>::max()) {
|
||||
return std::nullopt;
|
||||
} else if (val >= uint64_t(std::chrono::milliseconds::max().count())) {
|
||||
return std::chrono::milliseconds::max();
|
||||
} else {
|
||||
return std::chrono::milliseconds(val);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -240,6 +240,13 @@ pub extern "C" fn slint_platform_update_timers_and_animations() {
|
|||
i_slint_core::platform::update_timers_and_animations()
|
||||
}
|
||||
|
||||
/// Returns the duration in millisecond until the next timer or `u64::MAX` if there is no pending timers
|
||||
#[no_mangle]
|
||||
pub extern "C" fn slint_platform_duration_until_next_timer_update() -> u64 {
|
||||
i_slint_core::platform::duration_until_next_timer_update()
|
||||
.map_or(u64::MAX, |d| d.as_millis() as u64)
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct PlatformEventOpaque(*const c_void, *const c_void);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial
|
||||
|
||||
#include <optional>
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch2/catch.hpp"
|
||||
|
||||
|
|
@ -10,6 +9,8 @@
|
|||
#include <deque>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <chrono>
|
||||
#include <optional>
|
||||
|
||||
namespace slint_platform = slint::experimental::platform;
|
||||
|
||||
|
|
@ -19,6 +20,7 @@ struct TestPlatform : slint_platform::Platform
|
|||
std::deque<slint_platform::PlatformEvent> queue;
|
||||
bool quit = false;
|
||||
std::condition_variable cv;
|
||||
std::chrono::time_point<std::chrono::steady_clock> start = std::chrono::steady_clock::now();
|
||||
|
||||
/// Returns a new WindowAdapter
|
||||
virtual std::unique_ptr<slint_platform::WindowAdapter> create_window_adapter() const override
|
||||
|
|
@ -31,6 +33,7 @@ struct TestPlatform : slint_platform::Platform
|
|||
virtual void run_event_loop() override
|
||||
{
|
||||
while (true) {
|
||||
slint_platform::update_timers_and_animations();
|
||||
std::optional<slint_platform::PlatformEvent> event;
|
||||
{
|
||||
std::unique_lock lock(the_mutex);
|
||||
|
|
@ -39,7 +42,11 @@ struct TestPlatform : slint_platform::Platform
|
|||
quit = false;
|
||||
break;
|
||||
}
|
||||
cv.wait(lock);
|
||||
if (auto duration = slint_platform::duration_until_next_timer_update()) {
|
||||
cv.wait_for(lock, *duration);
|
||||
} else {
|
||||
cv.wait(lock);
|
||||
}
|
||||
continue;
|
||||
} else {
|
||||
event = std::move(queue.front());
|
||||
|
|
@ -77,10 +84,137 @@ struct TestPlatform : slint_platform::Platform
|
|||
queue.push_back(std::move(event));
|
||||
cv.notify_all();
|
||||
}
|
||||
|
||||
virtual std::chrono::milliseconds duration_since_start() const override
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::steady_clock::now() - start);
|
||||
}
|
||||
};
|
||||
|
||||
bool init_platform = (TestPlatform::register_platform(std::make_unique<TestPlatform>()), true);
|
||||
|
||||
TEST_CASE("C++ Singleshot Timers")
|
||||
{
|
||||
using namespace slint;
|
||||
int called = 0;
|
||||
Timer testTimer(std::chrono::milliseconds(16), [&]() {
|
||||
slint::quit_event_loop();
|
||||
called += 10;
|
||||
});
|
||||
REQUIRE(called == 0);
|
||||
slint::run_event_loop();
|
||||
REQUIRE(called == 10);
|
||||
}
|
||||
|
||||
TEST_CASE("C++ Repeated Timer")
|
||||
{
|
||||
int timer_triggered = 0;
|
||||
slint::Timer timer;
|
||||
|
||||
timer.start(slint::TimerMode::Repeated, std::chrono::milliseconds(30),
|
||||
[&]() { timer_triggered++; });
|
||||
|
||||
REQUIRE(timer_triggered == 0);
|
||||
|
||||
bool timer_was_running = false;
|
||||
|
||||
slint::Timer::single_shot(std::chrono::milliseconds(500), [&]() {
|
||||
timer_was_running = timer.running();
|
||||
slint::quit_event_loop();
|
||||
});
|
||||
|
||||
slint::run_event_loop();
|
||||
|
||||
REQUIRE(timer_triggered > 1);
|
||||
REQUIRE(timer_was_running);
|
||||
}
|
||||
|
||||
TEST_CASE("C++ Restart Singleshot Timer")
|
||||
{
|
||||
int timer_triggered = 0;
|
||||
slint::Timer timer;
|
||||
|
||||
timer.start(slint::TimerMode::SingleShot, std::chrono::milliseconds(30),
|
||||
[&]() { timer_triggered++; });
|
||||
|
||||
REQUIRE(timer_triggered == 0);
|
||||
|
||||
bool timer_was_running = false;
|
||||
|
||||
slint::Timer::single_shot(std::chrono::milliseconds(500), [&]() {
|
||||
timer_was_running = timer.running();
|
||||
slint::quit_event_loop();
|
||||
});
|
||||
|
||||
slint::run_event_loop();
|
||||
|
||||
REQUIRE(timer_triggered == 1);
|
||||
REQUIRE(timer_was_running);
|
||||
timer_triggered = 0;
|
||||
timer.restart();
|
||||
slint::Timer::single_shot(std::chrono::milliseconds(500), [&]() {
|
||||
timer_was_running = timer.running();
|
||||
slint::quit_event_loop();
|
||||
});
|
||||
|
||||
slint::run_event_loop();
|
||||
|
||||
REQUIRE(timer_triggered == 1);
|
||||
REQUIRE(timer_was_running);
|
||||
}
|
||||
|
||||
TEST_CASE("C++ Restart Repeated Timer")
|
||||
{
|
||||
int timer_triggered = 0;
|
||||
slint::Timer timer;
|
||||
|
||||
timer.start(slint::TimerMode::Repeated, std::chrono::milliseconds(30),
|
||||
[&]() { timer_triggered++; });
|
||||
|
||||
REQUIRE(timer_triggered == 0);
|
||||
|
||||
bool timer_was_running = false;
|
||||
|
||||
slint::Timer::single_shot(std::chrono::milliseconds(500), [&]() {
|
||||
timer_was_running = timer.running();
|
||||
slint::quit_event_loop();
|
||||
});
|
||||
|
||||
slint::run_event_loop();
|
||||
|
||||
REQUIRE(timer_triggered > 1);
|
||||
REQUIRE(timer_was_running);
|
||||
|
||||
timer_was_running = false;
|
||||
timer_triggered = 0;
|
||||
timer.stop();
|
||||
slint::Timer::single_shot(std::chrono::milliseconds(500), [&]() {
|
||||
timer_was_running = timer.running();
|
||||
slint::quit_event_loop();
|
||||
});
|
||||
|
||||
slint::run_event_loop();
|
||||
|
||||
REQUIRE(timer_triggered == 0);
|
||||
REQUIRE(!timer_was_running);
|
||||
|
||||
timer_was_running = false;
|
||||
timer_triggered = 0;
|
||||
|
||||
timer.restart();
|
||||
|
||||
slint::Timer::single_shot(std::chrono::milliseconds(500), [&]() {
|
||||
timer_was_running = timer.running();
|
||||
slint::quit_event_loop();
|
||||
});
|
||||
|
||||
slint::run_event_loop();
|
||||
|
||||
REQUIRE(timer_triggered > 1);
|
||||
REQUIRE(timer_was_running);
|
||||
}
|
||||
|
||||
TEST_CASE("Quit from event")
|
||||
{
|
||||
int called = 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue