From 92250949ca4adcc14d89bfed8f2b634802806281 Mon Sep 17 00:00:00 2001 From: Desuwa Date: Wed, 18 Oct 2023 13:38:04 -0700 Subject: [PATCH] Add _full and _local_full methods for idle and timeout callbacks. --- glib/src/source.rs | 120 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) diff --git a/glib/src/source.rs b/glib/src/source.rs index e75c7d693ec8..04704f842351 100644 --- a/glib/src/source.rs +++ b/glib/src/source.rs @@ -278,6 +278,29 @@ where } } +// rustdoc-stripper-ignore-next +/// Adds a closure to be called by the default main loop when it's idle. +/// +/// `func` will be called repeatedly with `priority` until it returns +/// `ControlFlow::Break`. +/// +/// The default main loop almost always is the main loop of the main thread. +/// Thus, the closure is called on the main thread. +#[doc(alias = "g_idle_add_full")] +pub fn idle_add_full(priority: Priority, func: F) -> SourceId +where + F: FnMut() -> ControlFlow + Send + 'static, +{ + unsafe { + from_glib(ffi::g_idle_add_full( + priority.into_glib(), + Some(trampoline::), + into_raw(func), + Some(destroy_closure::), + )) + } +} + // rustdoc-stripper-ignore-next /// Adds a closure to be called by the default main loop when it's idle. /// @@ -329,6 +352,39 @@ where } } +// rustdoc-stripper-ignore-next +/// Adds a closure to be called by the default main loop when it's idle. +/// +/// `func` will be called repeatedly with `priority` until it returns +/// `ControlFlow::Break`. +/// +/// The default main loop almost always is the main loop of the main thread. +/// Thus, the closure is called on the main thread. +/// +/// Different to `idle_add()`, this does not require `func` to be +/// `Send` but can only be called from the thread that owns the main context. +/// +/// This function panics if called from a different thread than the one that +/// owns the default main context. +#[doc(alias = "g_idle_add_full")] +pub fn idle_add_local_full(priority: Priority, func: F) -> SourceId +where + F: FnMut() -> ControlFlow + 'static, +{ + unsafe { + let context = MainContext::default(); + let _acquire = context + .acquire() + .expect("default main context already acquired by another thread"); + from_glib(ffi::g_idle_add_full( + priority.into_glib(), + Some(trampoline_local::), + into_raw_local(func), + Some(destroy_closure_local::), + )) + } +} + // rustdoc-stripper-ignore-next /// Adds a closure to be called by the default main loop when it's idle. /// @@ -380,6 +436,33 @@ where } } +// rustdoc-stripper-ignore-next +/// Adds a closure to be called by the default main loop at regular intervals +/// with millisecond granularity. +/// +/// `func` will be called repeatedly every `interval` milliseconds with `priority` +/// until it returns `ControlFlow::Break`. Precise timing is not guaranteed, the +/// timeout may be delayed by other events. Prefer `timeout_add_seconds` when +/// millisecond precision is not necessary. +/// +/// The default main loop almost always is the main loop of the main thread. +/// Thus, the closure is called on the main thread. +#[doc(alias = "g_timeout_add_full")] +pub fn timeout_add_full(interval: Duration, priority: Priority, func: F) -> SourceId +where + F: FnMut() -> ControlFlow + Send + 'static, +{ + unsafe { + from_glib(ffi::g_timeout_add_full( + priority.into_glib(), + interval.as_millis() as _, + Some(trampoline::), + into_raw(func), + Some(destroy_closure::), + )) + } +} + // rustdoc-stripper-ignore-next /// Adds a closure to be called by the default main loop at regular intervals /// with millisecond granularity. @@ -440,6 +523,43 @@ where } } +// rustdoc-stripper-ignore-next +/// Adds a closure to be called by the default main loop at regular intervals +/// with millisecond granularity. +/// +/// `func` will be called repeatedly every `interval` milliseconds with `priority` +/// until it returns `ControlFlow::Break`. Precise timing is not guaranteed, the +/// timeout may be delayed by other events. Prefer `timeout_add_seconds` when +/// millisecond precision is not necessary. +/// +/// The default main loop almost always is the main loop of the main thread. +/// Thus, the closure is called on the main thread. +/// +/// Different to `timeout_add()`, this does not require `func` to be +/// `Send` but can only be called from the thread that owns the main context. +/// +/// This function panics if called from a different thread than the one that +/// owns the main context. +#[doc(alias = "g_timeout_add_full")] +pub fn timeout_add_local_full(interval: Duration, priority: Priority, func: F) -> SourceId +where + F: FnMut() -> ControlFlow + 'static, +{ + unsafe { + let context = MainContext::default(); + let _acquire = context + .acquire() + .expect("default main context already acquired by another thread"); + from_glib(ffi::g_timeout_add_full( + priority.into_glib(), + interval.as_millis() as _, + Some(trampoline_local::), + into_raw_local(func), + Some(destroy_closure_local::), + )) + } +} + // rustdoc-stripper-ignore-next /// Adds a closure to be called by the default main loop at regular intervals /// with millisecond granularity.