1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
// 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 {
/// Creates a [`UriClipAsset`][crate::UriClipAsset] for `uri`
///
/// Example of request of a GESUriClipAsset:
///
/// ```text
/// // The request callback
/// static void
/// filesource_asset_loaded_cb (GESAsset * source, GAsyncResult * res, gpointer user_data)
/// {
/// GError *error = NULL;
/// GESUriClipAsset *filesource_asset;
///
/// filesource_asset = ges_uri_clip_asset_finish (res, &error);
/// if (filesource_asset) {
/// gst_print ("The file: %s is usable as a FileSource, it is%s an image and lasts %" GST_TIME_FORMAT,
/// ges_asset_get_id (GES_ASSET (filesource_asset))
/// ges_uri_clip_asset_is_image (filesource_asset) ? "" : " not",
/// GST_TIME_ARGS (ges_uri_clip_asset_get_duration (filesource_asset));
/// } else {
/// gst_print ("The file: %s is *not* usable as a FileSource because: %s",
/// ges_asset_get_id (source), error->message);
/// }
///
/// gst_object_unref (mfs);
/// }
///
/// // The request:
/// ges_uri_clip_asset_new (uri, (GAsyncReadyCallback) filesource_asset_loaded_cb, user_data);
/// ```
/// ## `uri`
/// The URI of the file for which to create a [`UriClipAsset`][crate::UriClipAsset]
/// ## `cancellable`
/// optional `GCancellable` object, [`None`] to ignore.
/// ## `callback`
/// a `GAsyncReadyCallback` to call when the initialization is finished
#[doc(alias = "ges_uri_clip_asset_new")]
#[allow(clippy::new_ret_no_self)]
pub fn new<P: FnOnce(Result<UriClipAsset, glib::Error>) + 'static>(
uri: &str,
cancellable: Option<&impl IsA<gio::Cancellable>>,
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_<glib::thread_guard::ThreadGuard<P>> =
Box_::new(glib::thread_guard::ThreadGuard::new(callback));
unsafe extern "C" fn new_trampoline<
P: FnOnce(Result<UriClipAsset, glib::Error>) + '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_<glib::thread_guard::ThreadGuard<P>> =
Box_::from_raw(user_data as *mut _);
let callback: P = callback.into_inner();
callback(result);
}
let callback = new_trampoline::<P>;
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<Box_<dyn std::future::Future<Output = Result<UriClipAsset, glib::Error>> + '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);
});
}))
}
}