Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add _full and _local_full methods for idle and timeout callbacks that take priority #1207

Merged
merged 1 commit into from
Oct 23, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
120 changes: 120 additions & 0 deletions glib/src/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<F>(priority: Priority, func: F) -> SourceId
where
F: FnMut() -> ControlFlow + Send + 'static,
{
unsafe {
from_glib(ffi::g_idle_add_full(
priority.into_glib(),
Some(trampoline::<F>),
into_raw(func),
Some(destroy_closure::<F>),
))
}
}

// rustdoc-stripper-ignore-next
/// Adds a closure to be called by the default main loop when it's idle.
///
Expand Down Expand Up @@ -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<F>(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::<F>),
into_raw_local(func),
Some(destroy_closure_local::<F>),
))
}
}

// rustdoc-stripper-ignore-next
/// Adds a closure to be called by the default main loop when it's idle.
///
Expand Down Expand Up @@ -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<F>(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::<F>),
into_raw(func),
Some(destroy_closure::<F>),
))
}
}

// rustdoc-stripper-ignore-next
/// Adds a closure to be called by the default main loop at regular intervals
/// with millisecond granularity.
Expand Down Expand Up @@ -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<F>(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::<F>),
into_raw_local(func),
Some(destroy_closure_local::<F>),
))
}
}

// rustdoc-stripper-ignore-next
/// Adds a closure to be called by the default main loop at regular intervals
/// with millisecond granularity.
Expand Down