mirror of
https://github.com/slint-ui/slint.git
synced 2025-11-02 04:48:27 +00:00
C++: add asserts that we are in the main thread
Some checks are pending
autofix.ci / format_fix (push) Waiting to run
autofix.ci / lint_typecheck (push) Waiting to run
CI / mcu (pico-st7789, thumbv6m-none-eabi) (push) Blocked by required conditions
CI / python_test (windows-2022) (push) Blocked by required conditions
CI / files-changed (push) Waiting to run
CI / build_and_test (--exclude bevy-example, ubuntu-22.04, 1.82) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, --exclude bevy-example, windows-2022, 1.82) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, macos-14, stable) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, windows-2022, beta) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, windows-2022, stable) (push) Blocked by required conditions
CI / build_and_test (ubuntu-22.04, nightly) (push) Blocked by required conditions
CI / node_test (macos-14) (push) Blocked by required conditions
CI / node_test (ubuntu-22.04) (push) Blocked by required conditions
CI / node_test (windows-2022) (push) Blocked by required conditions
CI / python_test (macos-14) (push) Blocked by required conditions
CI / python_test (ubuntu-22.04) (push) Blocked by required conditions
CI / cpp_test_driver (macos-13) (push) Blocked by required conditions
CI / cpp_test_driver (ubuntu-22.04) (push) Blocked by required conditions
CI / cpp_test_driver (windows-2022) (push) Blocked by required conditions
CI / cpp_cmake (macos-14, 1.82) (push) Blocked by required conditions
CI / cpp_cmake (windows-2022, nightly) (push) Blocked by required conditions
CI / cpp_cmake (ubuntu-22.04, stable) (push) Blocked by required conditions
CI / cpp_package_test (push) Blocked by required conditions
CI / vsce_build_test (push) Blocked by required conditions
CI / mcu (pico2-st7789, thumbv8m.main-none-eabihf) (push) Blocked by required conditions
CI / mcu (stm32h735g, thumbv7em-none-eabihf) (push) Blocked by required conditions
CI / mcu-embassy (push) Blocked by required conditions
CI / ffi_32bit_build (push) Blocked by required conditions
CI / docs (push) Blocked by required conditions
CI / wasm (push) Blocked by required conditions
CI / wasm_demo (push) Blocked by required conditions
CI / tree-sitter (push) Blocked by required conditions
CI / updater_test (0.3.0) (push) Blocked by required conditions
CI / fmt_test (push) Blocked by required conditions
CI / esp-idf-quick (push) Blocked by required conditions
CI / android (push) Blocked by required conditions
CI / miri (push) Blocked by required conditions
CI / test-figma-inspector (push) Blocked by required conditions
Some checks are pending
autofix.ci / format_fix (push) Waiting to run
autofix.ci / lint_typecheck (push) Waiting to run
CI / mcu (pico-st7789, thumbv6m-none-eabi) (push) Blocked by required conditions
CI / python_test (windows-2022) (push) Blocked by required conditions
CI / files-changed (push) Waiting to run
CI / build_and_test (--exclude bevy-example, ubuntu-22.04, 1.82) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, --exclude bevy-example, windows-2022, 1.82) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, macos-14, stable) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, windows-2022, beta) (push) Blocked by required conditions
CI / build_and_test (--exclude ffmpeg --exclude gstreamer-player, windows-2022, stable) (push) Blocked by required conditions
CI / build_and_test (ubuntu-22.04, nightly) (push) Blocked by required conditions
CI / node_test (macos-14) (push) Blocked by required conditions
CI / node_test (ubuntu-22.04) (push) Blocked by required conditions
CI / node_test (windows-2022) (push) Blocked by required conditions
CI / python_test (macos-14) (push) Blocked by required conditions
CI / python_test (ubuntu-22.04) (push) Blocked by required conditions
CI / cpp_test_driver (macos-13) (push) Blocked by required conditions
CI / cpp_test_driver (ubuntu-22.04) (push) Blocked by required conditions
CI / cpp_test_driver (windows-2022) (push) Blocked by required conditions
CI / cpp_cmake (macos-14, 1.82) (push) Blocked by required conditions
CI / cpp_cmake (windows-2022, nightly) (push) Blocked by required conditions
CI / cpp_cmake (ubuntu-22.04, stable) (push) Blocked by required conditions
CI / cpp_package_test (push) Blocked by required conditions
CI / vsce_build_test (push) Blocked by required conditions
CI / mcu (pico2-st7789, thumbv8m.main-none-eabihf) (push) Blocked by required conditions
CI / mcu (stm32h735g, thumbv7em-none-eabihf) (push) Blocked by required conditions
CI / mcu-embassy (push) Blocked by required conditions
CI / ffi_32bit_build (push) Blocked by required conditions
CI / docs (push) Blocked by required conditions
CI / wasm (push) Blocked by required conditions
CI / wasm_demo (push) Blocked by required conditions
CI / tree-sitter (push) Blocked by required conditions
CI / updater_test (0.3.0) (push) Blocked by required conditions
CI / fmt_test (push) Blocked by required conditions
CI / esp-idf-quick (push) Blocked by required conditions
CI / android (push) Blocked by required conditions
CI / miri (push) Blocked by required conditions
CI / test-figma-inspector (push) Blocked by required conditions
- In the timer functions - in the generated getter/setters and callback invocation
This commit is contained in:
parent
ab7f884106
commit
dc915b1af3
3 changed files with 58 additions and 32 deletions
|
|
@ -8,8 +8,38 @@
|
|||
#include <chrono>
|
||||
#include <slint_timer_internal.h>
|
||||
|
||||
#ifndef SLINT_FEATURE_FREESTANDING
|
||||
# include <thread>
|
||||
# include <iostream>
|
||||
#endif
|
||||
|
||||
namespace slint {
|
||||
|
||||
namespace private_api {
|
||||
/// Internal function that checks that the API that must be called from the main
|
||||
/// thread is indeed called from the main thread, or abort the program otherwise
|
||||
///
|
||||
/// Most API should be called from the main thread. When using thread one must
|
||||
/// use slint::invoke_from_event_loop
|
||||
inline void assert_main_thread()
|
||||
{
|
||||
#ifndef SLINT_FEATURE_FREESTANDING
|
||||
# ifndef NDEBUG
|
||||
static auto main_thread_id = std::this_thread::get_id();
|
||||
if (main_thread_id != std::this_thread::get_id()) {
|
||||
std::cerr << "A function that should be only called from the main thread was called from a "
|
||||
"thread."
|
||||
<< std::endl;
|
||||
std::cerr << "Most API should be called from the main thread. When using thread one must "
|
||||
"use slint::invoke_from_event_loop."
|
||||
<< std::endl;
|
||||
std::abort();
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
} // namespace private_api
|
||||
|
||||
using cbindgen_private::TimerMode;
|
||||
|
||||
/// A Timer that can call a callback at repeated interval
|
||||
|
|
@ -32,10 +62,15 @@ struct Timer
|
|||
[](void *data) { (*reinterpret_cast<F *>(data))(); }, new F(std::move(callback)),
|
||||
[](void *data) { delete reinterpret_cast<F *>(data); }))
|
||||
{
|
||||
private_api::assert_main_thread();
|
||||
}
|
||||
Timer(const Timer &) = delete;
|
||||
Timer &operator=(const Timer &) = delete;
|
||||
~Timer() { cbindgen_private::slint_timer_destroy(id); }
|
||||
~Timer()
|
||||
{
|
||||
private_api::assert_main_thread();
|
||||
cbindgen_private::slint_timer_destroy(id);
|
||||
}
|
||||
|
||||
/// Starts the timer with the given \a mode and \a interval, in order for the \a callback to
|
||||
/// called when the timer fires. If the timer has been started previously and not fired yet,
|
||||
|
|
@ -43,25 +78,39 @@ struct Timer
|
|||
template<std::invocable F>
|
||||
void start(TimerMode mode, std::chrono::milliseconds interval, F callback)
|
||||
{
|
||||
private_api::assert_main_thread();
|
||||
id = cbindgen_private::slint_timer_start(
|
||||
id, mode, interval.count(), [](void *data) { (*reinterpret_cast<F *>(data))(); },
|
||||
new F(std::move(callback)), [](void *data) { delete reinterpret_cast<F *>(data); });
|
||||
}
|
||||
/// Stops the previously started timer. Does nothing if the timer has never been started. A
|
||||
/// stopped timer cannot be restarted with restart(). Use start() instead.
|
||||
void stop() { cbindgen_private::slint_timer_stop(id); }
|
||||
void stop()
|
||||
{
|
||||
private_api::assert_main_thread();
|
||||
cbindgen_private::slint_timer_stop(id);
|
||||
}
|
||||
/// Restarts the timer. If the timer was previously started by calling [`Self::start()`]
|
||||
/// with a duration and callback, then the time when the callback will be next invoked
|
||||
/// is re-calculated to be in the specified duration relative to when this function is called.
|
||||
///
|
||||
/// Does nothing if the timer was never started.
|
||||
void restart() { cbindgen_private::slint_timer_restart(id); }
|
||||
void restart()
|
||||
{
|
||||
private_api::assert_main_thread();
|
||||
cbindgen_private::slint_timer_restart(id);
|
||||
}
|
||||
/// Returns true if the timer is running; false otherwise.
|
||||
bool running() const { return cbindgen_private::slint_timer_running(id); }
|
||||
bool running() const
|
||||
{
|
||||
private_api::assert_main_thread();
|
||||
return cbindgen_private::slint_timer_running(id);
|
||||
}
|
||||
/// Returns the interval of the timer.
|
||||
/// Returns 0 if the timer was never started.
|
||||
std::chrono::milliseconds interval() const
|
||||
{
|
||||
private_api::assert_main_thread();
|
||||
return std::chrono::milliseconds(cbindgen_private::slint_timer_interval(id));
|
||||
}
|
||||
|
||||
|
|
@ -69,6 +118,7 @@ struct Timer
|
|||
template<std::invocable F>
|
||||
static void single_shot(std::chrono::milliseconds duration, F callback)
|
||||
{
|
||||
private_api::assert_main_thread();
|
||||
cbindgen_private::slint_timer_singleshot(
|
||||
duration.count(), [](void *data) { (*reinterpret_cast<F *>(data))(); },
|
||||
new F(std::move(callback)), [](void *data) { delete reinterpret_cast<F *>(data); });
|
||||
|
|
|
|||
|
|
@ -5,11 +5,6 @@
|
|||
|
||||
#include "slint_internal.h"
|
||||
|
||||
#ifndef SLINT_FEATURE_FREESTANDING
|
||||
# include <thread>
|
||||
# include <iostream>
|
||||
#endif
|
||||
|
||||
namespace slint {
|
||||
#if !defined(DOXYGEN)
|
||||
namespace platform {
|
||||
|
|
@ -19,29 +14,6 @@ class SoftwareRenderer;
|
|||
#endif
|
||||
|
||||
namespace private_api {
|
||||
/// Internal function that checks that the API that must be called from the main
|
||||
/// thread is indeed called from the main thread, or abort the program otherwise
|
||||
///
|
||||
/// Most API should be called from the main thread. When using thread one must
|
||||
/// use slint::invoke_from_event_loop
|
||||
inline void assert_main_thread()
|
||||
{
|
||||
#ifndef SLINT_FEATURE_FREESTANDING
|
||||
# ifndef NDEBUG
|
||||
static auto main_thread_id = std::this_thread::get_id();
|
||||
if (main_thread_id != std::this_thread::get_id()) {
|
||||
std::cerr << "A function that should be only called from the main thread was called from a "
|
||||
"thread."
|
||||
<< std::endl;
|
||||
std::cerr << "Most API should be called from the main thread. When using thread one must "
|
||||
"use slint::invoke_from_event_loop."
|
||||
<< std::endl;
|
||||
std::abort();
|
||||
}
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
using ItemTreeRc = vtable::VRc<cbindgen_private::ItemTreeVTable>;
|
||||
using slint::LogicalPosition;
|
||||
|
||||
|
|
|
|||
|
|
@ -2740,6 +2740,7 @@ fn generate_public_api_for_properties(
|
|||
let param_types =
|
||||
callback.args.iter().map(|t| t.cpp_type().unwrap()).collect::<Vec<_>>();
|
||||
let callback_emitter = vec![
|
||||
"slint::private_api::assert_main_thread();".into(),
|
||||
"[[maybe_unused]] auto self = this;".into(),
|
||||
format!(
|
||||
"return {}.call({});",
|
||||
|
|
@ -2774,6 +2775,7 @@ fn generate_public_api_for_properties(
|
|||
)),
|
||||
signature: "(Functor && callback_handler) const".into(),
|
||||
statements: Some(vec![
|
||||
"slint::private_api::assert_main_thread();".into(),
|
||||
"[[maybe_unused]] auto self = this;".into(),
|
||||
format!("{}.set_handler(std::forward<Functor>(callback_handler));", access),
|
||||
]),
|
||||
|
|
@ -2811,6 +2813,7 @@ fn generate_public_api_for_properties(
|
|||
} else {
|
||||
let cpp_property_type = p.ty.cpp_type().expect("Invalid type in public properties");
|
||||
let prop_getter: Vec<String> = vec![
|
||||
"slint::private_api::assert_main_thread();".into(),
|
||||
"[[maybe_unused]] auto self = this;".into(),
|
||||
format!("return {}.get();", access),
|
||||
];
|
||||
|
|
@ -2826,6 +2829,7 @@ fn generate_public_api_for_properties(
|
|||
|
||||
if !p.read_only {
|
||||
let prop_setter: Vec<String> = vec![
|
||||
"slint::private_api::assert_main_thread();".into(),
|
||||
"[[maybe_unused]] auto self = this;".into(),
|
||||
property_set_value_code(&p.prop, "value", ctx) + ";",
|
||||
];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue