From 7dc7f3c0cdcc34447bdca065dcabaae9e27b2c04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Mon, 8 Jul 2024 10:30:03 +0300 Subject: [PATCH] ges: Implement `UriClipAsset::new()` manually The proper finish function is only available since 1.16 so work around this for the time being. Part-of: --- gstreamer-editing-services/Gir.toml | 4 + .../src/auto/uri_clip_asset.rs | 65 +-------------- gstreamer-editing-services/src/lib.rs | 1 + .../src/uri_clip_asset.rs | 79 +++++++++++++++++++ 4 files changed, 85 insertions(+), 64 deletions(-) create mode 100644 gstreamer-editing-services/src/uri_clip_asset.rs diff --git a/gstreamer-editing-services/Gir.toml b/gstreamer-editing-services/Gir.toml index 5034d3638..d0c43b9a2 100644 --- a/gstreamer-editing-services/Gir.toml +++ b/gstreamer-editing-services/Gir.toml @@ -494,6 +494,10 @@ status = "generate" name = "GES.UriClipAsset" status = "generate" concurrency = "send+sync" + [[object.function]] + name = "new" + # broken finish function in < 1.16 + manual = true [[object]] name = "GES.UriSourceAsset" diff --git a/gstreamer-editing-services/src/auto/uri_clip_asset.rs b/gstreamer-editing-services/src/auto/uri_clip_asset.rs index 54b41f966..cc173f3c1 100644 --- a/gstreamer-editing-services/src/auto/uri_clip_asset.rs +++ b/gstreamer-editing-services/src/auto/uri_clip_asset.rs @@ -12,7 +12,7 @@ use glib::{ signal::{connect_raw, SignalHandlerId}, translate::*, }; -use std::{boxed::Box as Box_, pin::Pin}; +use std::boxed::Box as Box_; #[cfg(feature = "v1_18")] #[cfg_attr(docsrs, doc(cfg(feature = "v1_18")))] @@ -45,69 +45,6 @@ impl UriClipAsset { // unsafe { TODO: call ffi:ges_uri_clip_asset_finish() } //} - #[doc(alias = "ges_uri_clip_asset_new")] - pub fn new) + 'static>( - uri: &str, - cancellable: Option<&impl IsA>, - callback: P, - ) { - assert_initialized_main_thread!(); - - 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_> = - Box_::new(glib::thread_guard::ThreadGuard::new(callback)); - unsafe extern "C" fn new_trampoline< - P: FnOnce(Result) + 'static, - >( - _source_object: *mut glib::gobject_ffi::GObject, - res: *mut gio::ffi::GAsyncResult, - user_data: glib::ffi::gpointer, - ) { - let mut error = std::ptr::null_mut(); - let ret = ffi::ges_uri_clip_asset_finish(res, &mut error); - let result = if error.is_null() { - Ok(from_glib_full(ret)) - } else { - Err(from_glib_full(error)) - }; - let callback: Box_> = - Box_::from_raw(user_data as *mut _); - let callback: P = callback.into_inner(); - callback(result); - } - let callback = new_trampoline::

; - unsafe { - ffi::ges_uri_clip_asset_new( - uri.to_glib_none().0, - cancellable.map(|p| p.as_ref()).to_glib_none().0, - Some(callback), - Box_::into_raw(user_data) as *mut _, - ); - } - } - - pub fn new_future( - uri: &str, - ) -> Pin> + 'static>> - { - skip_assert_initialized!(); - let uri = String::from(uri); - Box_::pin(gio::GioFuture::new(&(), move |_obj, cancellable, send| { - Self::new(&uri, Some(cancellable), move |res| { - send.resolve(res); - }); - })) - } - #[doc(alias = "ges_uri_clip_asset_request_sync")] pub fn request_sync(uri: &str) -> Result { assert_initialized_main_thread!(); diff --git a/gstreamer-editing-services/src/lib.rs b/gstreamer-editing-services/src/lib.rs index fdc61c276..5015ecc84 100644 --- a/gstreamer-editing-services/src/lib.rs +++ b/gstreamer-editing-services/src/lib.rs @@ -60,6 +60,7 @@ pub use crate::auto::*; #[cfg_attr(docsrs, doc(cfg(feature = "v1_24")))] mod composition_meta; pub mod subclass; +mod uri_clip_asset; #[cfg(feature = "serde")] mod flag_serde; diff --git a/gstreamer-editing-services/src/uri_clip_asset.rs b/gstreamer-editing-services/src/uri_clip_asset.rs new file mode 100644 index 000000000..0ef7874f3 --- /dev/null +++ b/gstreamer-editing-services/src/uri_clip_asset.rs @@ -0,0 +1,79 @@ +// Take a look at the license at the top of the repository in the LICENSE file. +use crate::{ffi, UriClipAsset}; +use glib::{prelude::*, translate::*}; +use std::{boxed::Box as Box_, pin::Pin}; + +impl UriClipAsset { + #[doc(alias = "ges_uri_clip_asset_new")] + #[allow(clippy::new_ret_no_self)] + pub fn new) + 'static>( + uri: &str, + cancellable: Option<&impl IsA>, + callback: P, + ) { + assert_initialized_main_thread!(); + + 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_> = + Box_::new(glib::thread_guard::ThreadGuard::new(callback)); + unsafe extern "C" fn new_trampoline< + P: FnOnce(Result) + 'static, + >( + _source_object: *mut glib::gobject_ffi::GObject, + res: *mut gio::ffi::GAsyncResult, + user_data: glib::ffi::gpointer, + ) { + let mut error = std::ptr::null_mut(); + let ret = { + #[cfg(feature = "v1_16")] + { + ffi::ges_uri_clip_asset_finish(res, &mut error) + } + #[cfg(not(feature = "v1_16"))] + { + ffi::ges_asset_request_finish(res, &mut error) as *mut ffi::GESUriClipAsset + } + }; + let result = if error.is_null() { + Ok(from_glib_full(ret)) + } else { + Err(from_glib_full(error)) + }; + let callback: Box_> = + Box_::from_raw(user_data as *mut _); + let callback: P = callback.into_inner(); + callback(result); + } + let callback = new_trampoline::

; + unsafe { + ffi::ges_uri_clip_asset_new( + uri.to_glib_none().0, + cancellable.map(|p| p.as_ref()).to_glib_none().0, + Some(callback), + Box_::into_raw(user_data) as *mut _, + ); + } + } + + pub fn new_future( + uri: &str, + ) -> Pin> + 'static>> + { + skip_assert_initialized!(); + let uri = String::from(uri); + Box_::pin(gio::GioFuture::new(&(), move |_obj, cancellable, send| { + Self::new(&uri, Some(cancellable), move |res| { + send.resolve(res); + }); + })) + } +}