Skip to content

Commit

Permalink
Manually add typed & with_type methods
Browse files Browse the repository at this point in the history
Fixes #1384
Replaces #1386
  • Loading branch information
bilelmoussaoui committed Jul 6, 2023
1 parent af9f9ad commit f190069
Show file tree
Hide file tree
Showing 21 changed files with 444 additions and 283 deletions.
8 changes: 8 additions & 0 deletions gdk4/Gir.toml
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,9 @@ generate_builder = false
name = "read_async"
manual = true # mime_types are cloned instead of converting them to a Vec<String>
[[object.function]]
name = "read_value_async"
manual = true # To add a with_type variant
[[object.function]]
name = "set_content"
[object.function.return]
bool_return_is_error = "Can't set new clipboard content"
Expand Down Expand Up @@ -282,9 +285,11 @@ status = "generate"
[[object.function]]
name = "new_for_gtype"
rename = "for_type"
manual = true # To add a with_type variant
[[object.function]]
name = "contain_gtype"
rename = "contains_type"
manual = true # To add a with_type variant
[[object.function]]
name = "match_gtype"
rename = "match_type"
Expand Down Expand Up @@ -448,6 +453,9 @@ status = "generate"
[[object.function]]
name = "read_async"
manual = true # mime_types are cloned instead of converting them to a Vec<String>
[[object.function]]
name = "read_value_async"
manual = true # To add a with_type variant

[[object]]
name = "Gdk.EventType"
Expand Down
66 changes: 0 additions & 66 deletions gdk4/src/auto/clipboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,72 +166,6 @@ impl Clipboard {
}))
}

#[doc(alias = "gdk_clipboard_read_value_async")]
pub fn read_value_async<P: FnOnce(Result<glib::Value, glib::Error>) + 'static>(
&self,
type_: glib::types::Type,
io_priority: glib::Priority,
cancellable: Option<&impl IsA<gio::Cancellable>>,
callback: P,
) {
let main_context = glib::MainContext::ref_thread_default();
let is_main_context_owner = main_context.is_owner();
let has_acquired_main_context = (!is_main_context_owner)
.then(|| main_context.acquire().ok())
.flatten();
assert!(
is_main_context_owner || has_acquired_main_context.is_some(),
"Async operations only allowed if the thread is owning the MainContext"
);

let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
Box_::new(glib::thread_guard::ThreadGuard::new(callback));
unsafe extern "C" fn read_value_async_trampoline<
P: FnOnce(Result<glib::Value, glib::Error>) + 'static,
>(
_source_object: *mut glib::gobject_ffi::GObject,
res: *mut gio::ffi::GAsyncResult,
user_data: glib::ffi::gpointer,
) {
let mut error = ptr::null_mut();
let ret =
ffi::gdk_clipboard_read_value_finish(_source_object as *mut _, res, &mut error);
let result = if error.is_null() {
Ok(from_glib_none(ret))
} else {
Err(from_glib_full(error))
};
let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
Box_::from_raw(user_data as *mut _);
let callback: P = callback.into_inner();
callback(result);
}
let callback = read_value_async_trampoline::<P>;
unsafe {
ffi::gdk_clipboard_read_value_async(
self.to_glib_none().0,
type_.into_glib(),
io_priority.into_glib(),
cancellable.map(|p| p.as_ref()).to_glib_none().0,
Some(callback),
Box_::into_raw(user_data) as *mut _,
);
}
}

pub fn read_value_future(
&self,
type_: glib::types::Type,
io_priority: glib::Priority,
) -> Pin<Box_<dyn std::future::Future<Output = Result<glib::Value, glib::Error>> + 'static>>
{
Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
obj.read_value_async(type_, io_priority, Some(cancellable), move |res| {
send.resolve(res);
});
}))
}

#[doc(alias = "gdk_clipboard_set_content")]
pub fn set_content(
&self,
Expand Down
18 changes: 0 additions & 18 deletions gdk4/src/auto/content_formats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,24 +29,6 @@ impl ContentFormats {
}
}

#[doc(alias = "gdk_content_formats_new_for_gtype")]
#[doc(alias = "new_for_gtype")]
pub fn for_type(type_: glib::types::Type) -> ContentFormats {
assert_initialized_main_thread!();
unsafe { from_glib_full(ffi::gdk_content_formats_new_for_gtype(type_.into_glib())) }
}

#[doc(alias = "gdk_content_formats_contain_gtype")]
#[doc(alias = "contain_gtype")]
pub fn contains_type(&self, type_: glib::types::Type) -> bool {
unsafe {
from_glib(ffi::gdk_content_formats_contain_gtype(
self.to_glib_none().0,
type_.into_glib(),
))
}
}

#[doc(alias = "gdk_content_formats_contain_mime_type")]
pub fn contain_mime_type(&self, mime_type: &str) -> bool {
unsafe {
Expand Down
67 changes: 1 addition & 66 deletions gdk4/src/auto/drop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use glib::{
signal::{connect_raw, SignalHandlerId},
translate::*,
};
use std::{boxed::Box as Box_, fmt, mem::transmute, pin::Pin, ptr};
use std::{boxed::Box as Box_, fmt, mem::transmute};

glib::wrapper! {
#[doc(alias = "GdkDrop")]
Expand Down Expand Up @@ -63,71 +63,6 @@ impl Drop {
unsafe { from_glib_none(ffi::gdk_drop_get_surface(self.to_glib_none().0)) }
}

#[doc(alias = "gdk_drop_read_value_async")]
pub fn read_value_async<P: FnOnce(Result<glib::Value, glib::Error>) + 'static>(
&self,
type_: glib::types::Type,
io_priority: glib::Priority,
cancellable: Option<&impl IsA<gio::Cancellable>>,
callback: P,
) {
let main_context = glib::MainContext::ref_thread_default();
let is_main_context_owner = main_context.is_owner();
let has_acquired_main_context = (!is_main_context_owner)
.then(|| main_context.acquire().ok())
.flatten();
assert!(
is_main_context_owner || has_acquired_main_context.is_some(),
"Async operations only allowed if the thread is owning the MainContext"
);

let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
Box_::new(glib::thread_guard::ThreadGuard::new(callback));
unsafe extern "C" fn read_value_async_trampoline<
P: FnOnce(Result<glib::Value, glib::Error>) + 'static,
>(
_source_object: *mut glib::gobject_ffi::GObject,
res: *mut gio::ffi::GAsyncResult,
user_data: glib::ffi::gpointer,
) {
let mut error = ptr::null_mut();
let ret = ffi::gdk_drop_read_value_finish(_source_object as *mut _, res, &mut error);
let result = if error.is_null() {
Ok(from_glib_none(ret))
} else {
Err(from_glib_full(error))
};
let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
Box_::from_raw(user_data as *mut _);
let callback: P = callback.into_inner();
callback(result);
}
let callback = read_value_async_trampoline::<P>;
unsafe {
ffi::gdk_drop_read_value_async(
self.to_glib_none().0,
type_.into_glib(),
io_priority.into_glib(),
cancellable.map(|p| p.as_ref()).to_glib_none().0,
Some(callback),
Box_::into_raw(user_data) as *mut _,
);
}
}

pub fn read_value_future(
&self,
type_: glib::types::Type,
io_priority: glib::Priority,
) -> Pin<Box_<dyn std::future::Future<Output = Result<glib::Value, glib::Error>> + 'static>>
{
Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
obj.read_value_async(type_, io_priority, Some(cancellable), move |res| {
send.resolve(res);
});
}))
}

#[doc(alias = "gdk_drop_status")]
pub fn status(&self, actions: DragAction, preferred: DragAction) {
unsafe {
Expand Down
89 changes: 88 additions & 1 deletion gdk4/src/clipboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use crate::{prelude::*, Clipboard};
use glib::translate::*;
use glib::GString;
use std::{future, pin::Pin, ptr};
use std::{boxed::Box as Box_, future, pin::Pin, ptr};

impl Clipboard {
#[doc(alias = "gdk_clipboard_read_async")]
Expand Down Expand Up @@ -86,4 +86,91 @@ impl Clipboard {
});
}))
}

#[doc(alias = "gdk_clipboard_read_value_async")]
pub fn read_value_async<T: for<'a> glib::value::FromValue<'a> + glib::StaticType>(
&self,
io_priority: glib::Priority,
cancellable: Option<&impl IsA<gio::Cancellable>>,
callback: impl FnOnce(Result<T, glib::Error>) + 'static,
) {
let callback2 =
|t: Result<glib::Value, glib::Error>| callback(t.map(|v| v.get::<T>().unwrap()));
self.read_value_async_with_type(T::static_type(), io_priority, cancellable, callback2)
}

#[doc(alias = "gdk_clipboard_read_value_async")]
pub fn read_value_async_with_type<P: FnOnce(Result<glib::Value, glib::Error>) + 'static>(
&self,
type_: glib::types::Type,
io_priority: glib::Priority,
cancellable: Option<&impl IsA<gio::Cancellable>>,
callback: P,
) {
let main_context = glib::MainContext::ref_thread_default();
let is_main_context_owner = main_context.is_owner();
let has_acquired_main_context = (!is_main_context_owner)
.then(|| main_context.acquire().ok())
.flatten();
assert!(
is_main_context_owner || has_acquired_main_context.is_some(),
"Async operations only allowed if the thread is owning the MainContext"
);

let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
Box_::new(glib::thread_guard::ThreadGuard::new(callback));
unsafe extern "C" fn read_value_async_trampoline<
P: FnOnce(Result<glib::Value, glib::Error>) + 'static,
>(
_source_object: *mut glib::gobject_ffi::GObject,
res: *mut gio::ffi::GAsyncResult,
user_data: glib::ffi::gpointer,
) {
let mut error = ptr::null_mut();
let ret =
ffi::gdk_clipboard_read_value_finish(_source_object as *mut _, res, &mut error);
let result = if error.is_null() {
Ok(from_glib_none(ret))
} else {
Err(from_glib_full(error))
};
let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
Box_::from_raw(user_data as *mut _);
let callback: P = callback.into_inner();
callback(result);
}
let callback = read_value_async_trampoline::<P>;
unsafe {
ffi::gdk_clipboard_read_value_async(
self.to_glib_none().0,
type_.into_glib(),
io_priority.into_glib(),
cancellable.map(|p| p.as_ref()).to_glib_none().0,
Some(callback),
Box_::into_raw(user_data) as *mut _,
);
}
}

pub async fn read_value_future<T: for<'a> glib::value::FromValue<'a> + glib::StaticType>(
&self,
io_priority: glib::Priority,
) -> Result<T, glib::Error> {
self.read_value_future_with_type(T::static_type(), io_priority)
.await
.map(|v| v.get::<T>().unwrap())
}

pub fn read_value_future_with_type(
&self,
type_: glib::types::Type,
io_priority: glib::Priority,
) -> Pin<Box_<dyn std::future::Future<Output = Result<glib::Value, glib::Error>> + 'static>>
{
Box_::pin(gio::GioFuture::new(self, move |obj, cancellable, send| {
obj.read_value_async_with_type(type_, io_priority, Some(cancellable), move |res| {
send.resolve(res);
});
}))
}
}
33 changes: 32 additions & 1 deletion gdk4/src/content_formats.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,40 @@
// Take a look at the license at the top of the repository in the LICENSE file.

use crate::{ContentFormats, ContentFormatsBuilder};
use glib::{translate::*, Slice};
use glib::{translate::*, Slice, StaticType};

impl ContentFormats {
#[doc(alias = "gdk_content_formats_new_for_gtype")]
#[doc(alias = "new_for_gtype")]
pub fn for_type<T: StaticType>() -> Self {
assert_initialized_main_thread!();
Self::for_type_with_type(T::static_type())
}

#[doc(alias = "gdk_content_formats_new_for_gtype")]
#[doc(alias = "new_for_gtype")]
pub fn for_type_with_type(type_: glib::Type) -> Self {
assert_initialized_main_thread!();
unsafe { from_glib_full(ffi::gdk_content_formats_new_for_gtype(type_.into_glib())) }
}

#[doc(alias = "gdk_content_formats_contain_gtype")]
#[doc(alias = "contain_gtype")]
pub fn contains_type<T: StaticType>(&self) -> bool {
self.contains_type_with_type(T::static_type())
}

#[doc(alias = "gdk_content_formats_contain_gtype")]
#[doc(alias = "contain_gtype")]
pub fn contains_type_with_type(&self, type_: glib::types::Type) -> bool {
unsafe {
from_glib(ffi::gdk_content_formats_contain_gtype(
self.to_glib_none().0,
type_.into_glib(),
))
}
}

#[doc(alias = "gdk_content_formats_get_gtypes")]
#[doc(alias = "get_gtypes")]
pub fn types(&self) -> Slice<glib::Type> {
Expand Down
8 changes: 7 additions & 1 deletion gdk4/src/content_formats_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,13 @@ impl ContentFormatsBuilder {

#[doc(alias = "gdk_content_formats_builder_add_gtype")]
#[must_use]
pub fn add_type(self, type_: glib::types::Type) -> Self {
pub fn add_type<T: glib::StaticType>(self) -> Self {
self.add_with_type(T::static_type())
}

#[doc(alias = "gdk_content_formats_builder_add_gtype")]
#[must_use]
pub fn add_with_type(self, type_: glib::types::Type) -> Self {
unsafe {
ffi::gdk_content_formats_builder_add_gtype(self.to_glib_none().0, type_.into_glib());
}
Expand Down
9 changes: 8 additions & 1 deletion gdk4/src/content_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,15 @@ mod sealed {
// rustdoc-stripper-ignore-next
/// Trait containing manually implemented methods of [`ContentProvider`](crate::ContentProvider).
pub trait ContentProviderExtManual: sealed::Sealed + IsA<ContentProvider> {
fn value<T: for<'a> glib::value::FromValue<'a> + glib::StaticType>(
&self,
) -> Result<T, glib::Error> {
self.value_with_type(T::static_type())
.map(|v| v.get::<T>().unwrap())
}

#[doc(alias = "gdk_content_provider_get_value")]
fn value(&self, type_: glib::Type) -> Result<glib::Value, glib::Error> {
fn value_with_type(&self, type_: glib::Type) -> Result<glib::Value, glib::Error> {
unsafe {
let mut error = std::ptr::null_mut();
let mut value = glib::Value::from_type(type_);
Expand Down
Loading

0 comments on commit f190069

Please sign in to comment.