libpanel/
save_delegate.rs1use crate::{prelude::*, SaveDelegate};
2use futures_core::future::Future;
3use glib::{signal::connect_raw, translate::*, SignalHandlerId};
4use std::mem::transmute;
5
6pub trait SaveDelegateExtManual {
7 fn connect_save<F, R>(&self, f: F) -> SignalHandlerId
8 where
9 F: Fn(&Self, &gio::Task<bool>) -> R + 'static,
10 R: Future<Output = Result<(), glib::Error>> + 'static;
11}
12
13impl<O: IsA<SaveDelegate>> SaveDelegateExtManual for O {
14 fn connect_save<F, R>(&self, f: F) -> SignalHandlerId
15 where
16 F: Fn(&Self, &gio::Task<bool>) -> R + 'static,
17 R: Future<Output = Result<(), glib::Error>> + 'static,
18 {
19 unsafe extern "C" fn save_trampoline<
20 P: IsA<SaveDelegate>,
21 F: Fn(&P, &gio::Task<bool>) -> R + 'static,
22 R: Future<Output = Result<(), glib::Error>> + 'static,
23 >(
24 this: *mut ffi::PanelSaveDelegate,
25 task: *mut gio::ffi::GTask,
26 f: glib::ffi::gpointer,
27 ) -> glib::ffi::gboolean {
28 let f: &F = &*(f as *const F);
29 let task: gio::Task<bool> = from_glib_none(task);
30 let delegate = SaveDelegate::from_glib_borrow(this);
31 let fut = f(delegate.unsafe_cast_ref(), &task);
32 task.context().spawn_local(async move {
33 task.return_result(fut.await.map(|_| true));
34 });
35 true.into_glib()
36 }
37 unsafe {
38 let f: Box<F> = Box::new(f);
39 connect_raw(
40 self.as_ptr() as *mut _,
41 b"save\0".as_ptr() as *const _,
42 Some(transmute::<*const (), unsafe extern "C" fn()>(
43 save_trampoline::<Self, F, R> as *const (),
44 )),
45 Box::into_raw(f),
46 )
47 }
48 }
49}