Skip to content

Commit 833080a

Browse files
authored
Merge pull request #1207 from awused/priority
Add _full and _local_full methods for idle and timeout callbacks that take priority
2 parents d6e3e68 + a5b5cdd commit 833080a

File tree

1 file changed

+120
-0
lines changed

1 file changed

+120
-0
lines changed

glib/src/source.rs

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,29 @@ where
278278
}
279279
}
280280

281+
// rustdoc-stripper-ignore-next
282+
/// Adds a closure to be called by the default main loop when it's idle.
283+
///
284+
/// `func` will be called repeatedly with `priority` until it returns
285+
/// `ControlFlow::Break`.
286+
///
287+
/// The default main loop almost always is the main loop of the main thread.
288+
/// Thus, the closure is called on the main thread.
289+
#[doc(alias = "g_idle_add_full")]
290+
pub fn idle_add_full<F>(priority: Priority, func: F) -> SourceId
291+
where
292+
F: FnMut() -> ControlFlow + Send + 'static,
293+
{
294+
unsafe {
295+
from_glib(ffi::g_idle_add_full(
296+
priority.into_glib(),
297+
Some(trampoline::<F>),
298+
into_raw(func),
299+
Some(destroy_closure::<F>),
300+
))
301+
}
302+
}
303+
281304
// rustdoc-stripper-ignore-next
282305
/// Adds a closure to be called by the default main loop when it's idle.
283306
///
@@ -329,6 +352,39 @@ where
329352
}
330353
}
331354

355+
// rustdoc-stripper-ignore-next
356+
/// Adds a closure to be called by the default main loop when it's idle.
357+
///
358+
/// `func` will be called repeatedly with `priority` until it returns
359+
/// `ControlFlow::Break`.
360+
///
361+
/// The default main loop almost always is the main loop of the main thread.
362+
/// Thus, the closure is called on the main thread.
363+
///
364+
/// Different to `idle_add()`, this does not require `func` to be
365+
/// `Send` but can only be called from the thread that owns the main context.
366+
///
367+
/// This function panics if called from a different thread than the one that
368+
/// owns the default main context.
369+
#[doc(alias = "g_idle_add_full")]
370+
pub fn idle_add_local_full<F>(priority: Priority, func: F) -> SourceId
371+
where
372+
F: FnMut() -> ControlFlow + 'static,
373+
{
374+
unsafe {
375+
let context = MainContext::default();
376+
let _acquire = context
377+
.acquire()
378+
.expect("default main context already acquired by another thread");
379+
from_glib(ffi::g_idle_add_full(
380+
priority.into_glib(),
381+
Some(trampoline_local::<F>),
382+
into_raw_local(func),
383+
Some(destroy_closure_local::<F>),
384+
))
385+
}
386+
}
387+
332388
// rustdoc-stripper-ignore-next
333389
/// Adds a closure to be called by the default main loop when it's idle.
334390
///
@@ -380,6 +436,33 @@ where
380436
}
381437
}
382438

439+
// rustdoc-stripper-ignore-next
440+
/// Adds a closure to be called by the default main loop at regular intervals
441+
/// with millisecond granularity.
442+
///
443+
/// `func` will be called repeatedly every `interval` milliseconds with `priority`
444+
/// until it returns `ControlFlow::Break`. Precise timing is not guaranteed, the
445+
/// timeout may be delayed by other events. Prefer `timeout_add_seconds` when
446+
/// millisecond precision is not necessary.
447+
///
448+
/// The default main loop almost always is the main loop of the main thread.
449+
/// Thus, the closure is called on the main thread.
450+
#[doc(alias = "g_timeout_add_full")]
451+
pub fn timeout_add_full<F>(interval: Duration, priority: Priority, func: F) -> SourceId
452+
where
453+
F: FnMut() -> ControlFlow + Send + 'static,
454+
{
455+
unsafe {
456+
from_glib(ffi::g_timeout_add_full(
457+
priority.into_glib(),
458+
interval.as_millis() as _,
459+
Some(trampoline::<F>),
460+
into_raw(func),
461+
Some(destroy_closure::<F>),
462+
))
463+
}
464+
}
465+
383466
// rustdoc-stripper-ignore-next
384467
/// Adds a closure to be called by the default main loop at regular intervals
385468
/// with millisecond granularity.
@@ -440,6 +523,43 @@ where
440523
}
441524
}
442525

526+
// rustdoc-stripper-ignore-next
527+
/// Adds a closure to be called by the default main loop at regular intervals
528+
/// with millisecond granularity.
529+
///
530+
/// `func` will be called repeatedly every `interval` milliseconds with `priority`
531+
/// until it returns `ControlFlow::Break`. Precise timing is not guaranteed, the
532+
/// timeout may be delayed by other events. Prefer `timeout_add_seconds` when
533+
/// millisecond precision is not necessary.
534+
///
535+
/// The default main loop almost always is the main loop of the main thread.
536+
/// Thus, the closure is called on the main thread.
537+
///
538+
/// Different to `timeout_add()`, this does not require `func` to be
539+
/// `Send` but can only be called from the thread that owns the main context.
540+
///
541+
/// This function panics if called from a different thread than the one that
542+
/// owns the main context.
543+
#[doc(alias = "g_timeout_add_full")]
544+
pub fn timeout_add_local_full<F>(interval: Duration, priority: Priority, func: F) -> SourceId
545+
where
546+
F: FnMut() -> ControlFlow + 'static,
547+
{
548+
unsafe {
549+
let context = MainContext::default();
550+
let _acquire = context
551+
.acquire()
552+
.expect("default main context already acquired by another thread");
553+
from_glib(ffi::g_timeout_add_full(
554+
priority.into_glib(),
555+
interval.as_millis() as _,
556+
Some(trampoline_local::<F>),
557+
into_raw_local(func),
558+
Some(destroy_closure_local::<F>),
559+
))
560+
}
561+
}
562+
443563
// rustdoc-stripper-ignore-next
444564
/// Adds a closure to be called by the default main loop at regular intervals
445565
/// with millisecond granularity.

0 commit comments

Comments
 (0)