gstreamer_editing_services/auto/
asset.rs

1// This file was generated by gir (https://github.com/gtk-rs/gir)
2// from gir-files (https://github.com/gtk-rs/gir-files)
3// from gst-gir-files (https://gitlab.freedesktop.org/gstreamer/gir-files-rs.git)
4// DO NOT EDIT
5
6use crate::{ffi, Extractable, MetaContainer};
7use glib::{
8    prelude::*,
9    signal::{connect_raw, SignalHandlerId},
10    translate::*,
11};
12use std::{boxed::Box as Box_, pin::Pin};
13
14glib::wrapper! {
15    /// A [`Asset`][crate::Asset] in the GStreamer Editing Services represents a resources
16    /// that can be used. In particular, any class that implements the
17    /// [`Extractable`][crate::Extractable] interface may have some associated assets with a
18    /// corresponding [`extractable-type`][struct@crate::Asset#extractable-type], from which its objects can be
19    /// extracted using [`AssetExt::extract()`][crate::prelude::AssetExt::extract()]. Some examples would be
20    /// [`Clip`][crate::Clip], [`Formatter`][crate::Formatter] and [`TrackElement`][crate::TrackElement].
21    ///
22    /// All assets that are created within GES are stored in a cache; one per
23    /// each [`id`][struct@crate::Asset#id] and [`extractable-type`][struct@crate::Asset#extractable-type] pair. These assets can
24    /// be fetched, and initialized if they do not yet exist in the cache,
25    /// using [`request_with_type()`][Self::request_with_type()].
26    ///
27    /// **⚠️ The following code is in  c ⚠️**
28    ///
29    /// ``` c
30    /// GESAsset *effect_asset;
31    /// GESEffect *effect;
32    ///
33    /// // You create an asset for an effect
34    /// effect_asset = ges_asset_request (GES_TYPE_EFFECT, "agingtv", NULL);
35    ///
36    /// // And now you can extract an instance of GESEffect from that asset
37    /// effect = GES_EFFECT (ges_asset_extract (effect_asset));
38    ///
39    /// ```
40    ///
41    /// The advantage of using assets, rather than simply creating the object
42    /// directly, is that the currently loaded resources can be listed with
43    /// `ges_list_assets()` and displayed to an end user. For example, to show
44    /// which media files have been loaded, and a standard list of effects. In
45    /// fact, the GES library already creates assets for [`TransitionClip`][crate::TransitionClip] and
46    /// [`Formatter`][crate::Formatter], which you can use to list all the available transition
47    /// types and supported formats.
48    ///
49    /// The other advantage is that [`Asset`][crate::Asset] implements [`MetaContainer`][crate::MetaContainer], so
50    /// metadata can be set on the asset, with some subclasses automatically
51    /// creating this metadata on initiation.
52    ///
53    /// For example, to display information about the supported formats, you
54    /// could do the following:
55    ///
56    /// ```text
57    ///    GList *formatter_assets, *tmp;
58    ///
59    ///    //  List all  the transitions
60    ///    formatter_assets = ges_list_assets (GES_TYPE_FORMATTER);
61    ///
62    ///    // Print some infos about the formatter GESAsset
63    ///    for (tmp = formatter_assets; tmp; tmp = tmp->next) {
64    ///      gst_print ("Name of the formatter: %s, file extension it produces: %s",
65    ///        ges_meta_container_get_string (
66    ///          GES_META_CONTAINER (tmp->data), GES_META_FORMATTER_NAME),
67    ///        ges_meta_container_get_string (
68    ///          GES_META_CONTAINER (tmp->data), GES_META_FORMATTER_EXTENSION));
69    ///    }
70    ///
71    ///    g_list_free (transition_assets);
72    ///
73    /// ```
74    ///
75    /// ## ID
76    ///
77    /// Each asset is uniquely defined in the cache by its
78    /// [`extractable-type`][struct@crate::Asset#extractable-type] and [`id`][struct@crate::Asset#id]. Depending on the
79    /// [`extractable-type`][struct@crate::Asset#extractable-type], the [`id`][struct@crate::Asset#id] can be used to parametrise
80    /// the creation of the object upon extraction. By default, a class that
81    /// implements [`Extractable`][crate::Extractable] will only have a single associated asset,
82    /// with an [`id`][struct@crate::Asset#id] set to the type name of its objects. However, this
83    /// is overwritten by some implementations, which allow a class to have
84    /// multiple associated assets. For example, for [`TransitionClip`][crate::TransitionClip] the
85    /// [`id`][struct@crate::Asset#id] will be a nickname of the [`vtype`][struct@crate::TransitionClip#vtype]. You
86    /// should check the documentation for each extractable type to see if they
87    /// differ from the default.
88    ///
89    /// Moreover, each [`extractable-type`][struct@crate::Asset#extractable-type] may also associate itself
90    /// with a specific asset subclass. In such cases, when their asset is
91    /// requested, an asset of this subclass will be returned instead.
92    ///
93    /// ## Managing
94    ///
95    /// You can use a [`Project`][crate::Project] to easily manage the assets of a
96    /// [`Timeline`][crate::Timeline].
97    ///
98    /// ## Proxies
99    ///
100    /// Some assets can (temporarily) act as the [`proxy`][struct@crate::Asset#proxy] of another
101    /// asset. When the original asset is requested from the cache, the proxy
102    /// will be returned in its place. This can be useful if, say, you want
103    /// to substitute a [`UriClipAsset`][crate::UriClipAsset] corresponding to a high resolution
104    /// media file with the asset of a lower resolution stand in.
105    ///
106    /// An asset may even have several proxies, the first of which will act as
107    /// its default and be returned on requests, but the others will be ordered
108    /// to take its place once it is removed. You can add a proxy to an asset,
109    /// or set its default, using [`AssetExt::set_proxy()`][crate::prelude::AssetExt::set_proxy()], and you can remove
110    /// them with [`AssetExt::unproxy()`][crate::prelude::AssetExt::unproxy()].
111    ///
112    /// ## Properties
113    ///
114    ///
115    /// #### `extractable-type`
116    ///  The [`Extractable`][crate::Extractable] object type that can be extracted from the asset.
117    ///
118    /// Readable | Writeable | Construct Only
119    ///
120    ///
121    /// #### `id`
122    ///  The ID of the asset. This should be unique amongst all assets with
123    /// the same [`extractable-type`][struct@crate::Asset#extractable-type]. Depending on the associated
124    /// [`Extractable`][crate::Extractable] implementation, this id may convey some information
125    /// about the [`glib::Object`][crate::glib::Object] that should be extracted. Note that, as such, the
126    /// ID will have an expected format, and you can not choose this value
127    /// arbitrarily. By default, this will be set to the type name of the
128    /// [`extractable-type`][struct@crate::Asset#extractable-type], but you should check the documentation
129    /// of the extractable type to see whether they differ from the
130    /// default behaviour.
131    ///
132    /// Readable | Writeable | Construct Only
133    ///
134    ///
135    /// #### `proxy`
136    ///  The default proxy for this asset, or [`None`] if it has no proxy. A
137    /// proxy will act as a substitute for the original asset when the
138    /// original is requested (see [`Asset::request_with_type()`][crate::Asset::request_with_type()]).
139    ///
140    /// Setting this property will not usually remove the existing proxy, but
141    /// will replace it as the default (see [`AssetExt::set_proxy()`][crate::prelude::AssetExt::set_proxy()]).
142    ///
143    /// Readable | Writeable
144    ///
145    ///
146    /// #### `proxy-target`
147    ///  The asset that this asset is a proxy for, or [`None`] if it is not a
148    /// proxy for another asset.
149    ///
150    /// Note that even if this asset is acting as a proxy for another asset,
151    /// but this asset is not the default [`proxy`][struct@crate::Asset#proxy], then `proxy`-target
152    /// will *still* point to this other asset. So you should check the
153    /// [`proxy`][struct@crate::Asset#proxy] property of `target`-proxy before assuming it is the
154    /// current default proxy for the target.
155    ///
156    /// Note that the [`notify`][struct@crate::glib::Object#notify] for this property is emitted after
157    /// the [`proxy`][struct@crate::Asset#proxy] [`notify`][struct@crate::glib::Object#notify] for the corresponding (if any)
158    /// asset it is now the proxy of/no longer the proxy of.
159    ///
160    /// Readable
161    ///
162    /// # Implements
163    ///
164    /// [`AssetExt`][trait@crate::prelude::AssetExt], [`trait@glib::ObjectExt`], [`MetaContainerExt`][trait@crate::prelude::MetaContainerExt]
165    #[doc(alias = "GESAsset")]
166    pub struct Asset(Object<ffi::GESAsset, ffi::GESAssetClass>) @implements MetaContainer;
167
168    match fn {
169        type_ => || ffi::ges_asset_get_type(),
170    }
171}
172
173impl Asset {
174    pub const NONE: Option<&'static Asset> = None;
175
176    /// Indicate that an existing [`Asset`][crate::Asset] in the cache should be reloaded
177    /// upon the next request. This can be used when some condition has
178    /// changed, which may require that an existing asset should be updated.
179    /// For example, if an external resource has changed or now become
180    /// available.
181    ///
182    /// Note, the asset is not immediately changed, but will only actually
183    /// reload on the next call to [`request_with_type()`][Self::request_with_type()] or
184    /// [`request_async_with_type()`][Self::request_async_with_type()].
185    /// ## `extractable_type`
186    /// The [`extractable-type`][struct@crate::Asset#extractable-type] of the asset that
187    /// needs reloading
188    /// ## `id`
189    /// The [`id`][struct@crate::Asset#id] of the asset asset that needs
190    /// reloading
191    ///
192    /// # Returns
193    ///
194    /// [`true`] if the specified asset exists in the cache and could be
195    /// marked for reloading.
196    #[doc(alias = "ges_asset_needs_reload")]
197    #[doc(alias = "needs_reload")]
198    pub fn needs_reload_with_type(extractable_type: glib::types::Type, id: Option<&str>) -> bool {
199        assert_initialized_main_thread!();
200        unsafe {
201            from_glib(ffi::ges_asset_needs_reload(
202                extractable_type.into_glib(),
203                id.to_glib_none().0,
204            ))
205        }
206    }
207
208    /// Returns an asset with the given properties. If such an asset already
209    /// exists in the cache (it has been previously created in GES), then a
210    /// reference to the existing asset is returned. Otherwise, a newly created
211    /// asset is returned, and also added to the cache.
212    ///
213    /// If the requested asset has been loaded with an error, then `error` is
214    /// set, if given, and [`None`] will be returned instead.
215    ///
216    /// Note that the given `id` may not be exactly the [`id`][struct@crate::Asset#id] that is
217    /// set on the returned asset. For instance, it may be adjusted into a
218    /// standard format. Or, if a [`Extractable`][crate::Extractable] type does not have its
219    /// extraction parametrised, as is the case by default, then the given `id`
220    /// may be ignored entirely and the [`id`][struct@crate::Asset#id] set to some standard, in
221    /// which case a [`None`] `id` can be given.
222    ///
223    /// Similarly, the given `extractable_type` may not be exactly the
224    /// [`extractable-type`][struct@crate::Asset#extractable-type] that is set on the returned asset. Instead,
225    /// the actual extractable type may correspond to a subclass of the given
226    /// `extractable_type`, depending on the given `id`.
227    ///
228    /// Moreover, depending on the given `extractable_type`, the returned asset
229    /// may belong to a subclass of [`Asset`][crate::Asset].
230    ///
231    /// Finally, if the requested asset has a [`proxy`][struct@crate::Asset#proxy], then the proxy
232    /// that is found at the end of the chain of proxies is returned (a proxy's
233    /// proxy will take its place, and so on, unless it has no proxy).
234    ///
235    /// Some asset subclasses only support asynchronous construction of its
236    /// assets, such as [`UriClip`][crate::UriClip]. For such assets this method will fail, and
237    /// you should use [`request_async_with_type()`][Self::request_async_with_type()] instead. In the case of
238    /// [`UriClip`][crate::UriClip], you can use [`UriClipAsset::request_sync()`][crate::UriClipAsset::request_sync()] if you only
239    /// want to wait for the request to finish.
240    /// ## `extractable_type`
241    /// The [`extractable-type`][struct@crate::Asset#extractable-type] of the asset
242    /// ## `id`
243    /// The [`id`][struct@crate::Asset#id] of the asset
244    ///
245    /// # Returns
246    ///
247    /// A reference to the requested
248    /// asset, or [`None`] if an error occurred.
249    #[doc(alias = "ges_asset_request")]
250    #[doc(alias = "request")]
251    pub fn request_with_type(
252        extractable_type: glib::types::Type,
253        id: Option<&str>,
254    ) -> Result<Option<Asset>, glib::Error> {
255        assert_initialized_main_thread!();
256        unsafe {
257            let mut error = std::ptr::null_mut();
258            let ret = ffi::ges_asset_request(
259                extractable_type.into_glib(),
260                id.to_glib_none().0,
261                &mut error,
262            );
263            if error.is_null() {
264                Ok(from_glib_full(ret))
265            } else {
266                Err(from_glib_full(error))
267            }
268        }
269    }
270
271    /// Requests an asset with the given properties asynchronously (see
272    /// [`request_with_type()`][Self::request_with_type()]). When the asset has been initialized or fetched
273    /// from the cache, the given callback function will be called. The
274    /// asset can then be retrieved in the callback using the
275    /// `ges_asset_request_finish()` method on the given `GAsyncResult`.
276    ///
277    /// Note that the source object passed to the callback will be the
278    /// [`Asset`][crate::Asset] corresponding to the request, but it may not have loaded
279    /// correctly and therefore can not be used as is. Instead,
280    /// `ges_asset_request_finish()` should be used to fetch a usable asset, or
281    /// indicate that an error occurred in the asset's creation.
282    ///
283    /// Note that the callback will be called in the `GMainLoop` running under
284    /// the same `GMainContext` that `ges_init()` was called in. So, if you wish
285    /// the callback to be invoked outside the default `GMainContext`, you can
286    /// call `g_main_context_push_thread_default()` in a new thread before
287    /// calling `ges_init()`.
288    ///
289    /// Example of an asynchronous asset request:
290    /// **⚠️ The following code is in  c ⚠️**
291    ///
292    /// ``` c
293    /// // The request callback
294    /// static void
295    /// asset_loaded_cb (GESAsset * source, GAsyncResult * res, gpointer user_data)
296    /// {
297    ///   GESAsset *asset;
298    ///   GError *error = NULL;
299    ///
300    ///   asset = ges_asset_request_finish (res, &error);
301    ///   if (asset) {
302    ///    gst_print ("The file: %s is usable as a GESUriClip",
303    ///        ges_asset_get_id (asset));
304    ///   } else {
305    ///    gst_print ("The file: %s is *not* usable as a GESUriClip because: %s",
306    ///        ges_asset_get_id (source), error->message);
307    ///   }
308    ///
309    ///   gst_object_unref (asset);
310    /// }
311    ///
312    /// // The request:
313    /// ges_asset_request_async (GES_TYPE_URI_CLIP, some_uri, NULL,
314    ///    (GAsyncReadyCallback) asset_loaded_cb, user_data);
315    /// ```
316    /// ## `extractable_type`
317    /// The [`extractable-type`][struct@crate::Asset#extractable-type] of the asset
318    /// ## `id`
319    /// The [`id`][struct@crate::Asset#id] of the asset
320    /// ## `cancellable`
321    /// An object to allow cancellation of the
322    /// asset request, or [`None`] to ignore
323    /// ## `callback`
324    /// A function to call when the initialization is finished
325    #[doc(alias = "ges_asset_request_async")]
326    #[doc(alias = "request_async")]
327    pub fn request_async_with_type<P: FnOnce(Result<Asset, glib::Error>) + 'static>(
328        extractable_type: glib::types::Type,
329        id: Option<&str>,
330        cancellable: Option<&impl IsA<gio::Cancellable>>,
331        callback: P,
332    ) {
333        assert_initialized_main_thread!();
334
335        let main_context = glib::MainContext::ref_thread_default();
336        let is_main_context_owner = main_context.is_owner();
337        let has_acquired_main_context = (!is_main_context_owner)
338            .then(|| main_context.acquire().ok())
339            .flatten();
340        assert!(
341            is_main_context_owner || has_acquired_main_context.is_some(),
342            "Async operations only allowed if the thread is owning the MainContext"
343        );
344
345        let user_data: Box_<glib::thread_guard::ThreadGuard<P>> =
346            Box_::new(glib::thread_guard::ThreadGuard::new(callback));
347        unsafe extern "C" fn request_async_with_type_trampoline<
348            P: FnOnce(Result<Asset, glib::Error>) + 'static,
349        >(
350            _source_object: *mut glib::gobject_ffi::GObject,
351            res: *mut gio::ffi::GAsyncResult,
352            user_data: glib::ffi::gpointer,
353        ) {
354            let mut error = std::ptr::null_mut();
355            let ret = ffi::ges_asset_request_finish(res, &mut error);
356            let result = if error.is_null() {
357                Ok(from_glib_full(ret))
358            } else {
359                Err(from_glib_full(error))
360            };
361            let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
362                Box_::from_raw(user_data as *mut _);
363            let callback: P = callback.into_inner();
364            callback(result);
365        }
366        let callback = request_async_with_type_trampoline::<P>;
367        unsafe {
368            ffi::ges_asset_request_async(
369                extractable_type.into_glib(),
370                id.to_glib_none().0,
371                cancellable.map(|p| p.as_ref()).to_glib_none().0,
372                Some(callback),
373                Box_::into_raw(user_data) as *mut _,
374            );
375        }
376    }
377
378    pub fn request_async_with_type_future(
379        extractable_type: glib::types::Type,
380        id: Option<&str>,
381    ) -> Pin<Box_<dyn std::future::Future<Output = Result<Asset, glib::Error>> + 'static>> {
382        skip_assert_initialized!();
383        let id = id.map(ToOwned::to_owned);
384        Box_::pin(gio::GioFuture::new(&(), move |_obj, cancellable, send| {
385            Self::request_async_with_type(
386                extractable_type,
387                id.as_ref().map(::std::borrow::Borrow::borrow),
388                Some(cancellable),
389                move |res| {
390                    send.resolve(res);
391                },
392            );
393        }))
394    }
395}
396
397unsafe impl Send for Asset {}
398unsafe impl Sync for Asset {}
399
400/// Trait containing all [`struct@Asset`] methods.
401///
402/// # Implementors
403///
404/// [`Asset`][struct@crate::Asset], [`ClipAsset`][struct@crate::ClipAsset], [`Project`][struct@crate::Project], [`TrackElementAsset`][struct@crate::TrackElementAsset]
405pub trait AssetExt: IsA<Asset> + 'static {
406    /// Extracts a new [`extractable-type`][struct@crate::Asset#extractable-type] object from the asset. The
407    /// [`id`][struct@crate::Asset#id] of the asset may determine the properties and state of the
408    /// newly created object.
409    ///
410    /// # Returns
411    ///
412    /// A newly created object, or [`None`] if an
413    /// error occurred.
414    #[doc(alias = "ges_asset_extract")]
415    fn extract(&self) -> Result<Extractable, glib::Error> {
416        unsafe {
417            let mut error = std::ptr::null_mut();
418            let ret = ffi::ges_asset_extract(self.as_ref().to_glib_none().0, &mut error);
419            if error.is_null() {
420                Ok(from_glib_none(ret))
421            } else {
422                Err(from_glib_full(error))
423            }
424        }
425    }
426
427    /// Retrieve the error that was set on the asset when it was loaded.
428    ///
429    /// # Returns
430    ///
431    /// The error set on `asset`, or
432    /// [`None`] if no error occurred when `asset` was loaded.
433    #[doc(alias = "ges_asset_get_error")]
434    #[doc(alias = "get_error")]
435    fn error(&self) -> Option<glib::Error> {
436        unsafe { from_glib_none(ffi::ges_asset_get_error(self.as_ref().to_glib_none().0)) }
437    }
438
439    /// Gets the [`extractable-type`][struct@crate::Asset#extractable-type] of the asset.
440    ///
441    /// # Returns
442    ///
443    /// The extractable type of `self`.
444    #[doc(alias = "ges_asset_get_extractable_type")]
445    #[doc(alias = "get_extractable_type")]
446    #[doc(alias = "extractable-type")]
447    fn extractable_type(&self) -> glib::types::Type {
448        unsafe {
449            from_glib(ffi::ges_asset_get_extractable_type(
450                self.as_ref().to_glib_none().0,
451            ))
452        }
453    }
454
455    /// Gets the [`id`][struct@crate::Asset#id] of the asset.
456    ///
457    /// # Returns
458    ///
459    /// The ID of `self`.
460    #[doc(alias = "ges_asset_get_id")]
461    #[doc(alias = "get_id")]
462    fn id(&self) -> glib::GString {
463        unsafe { from_glib_none(ffi::ges_asset_get_id(self.as_ref().to_glib_none().0)) }
464    }
465
466    /// Gets the default [`proxy`][struct@crate::Asset#proxy] of the asset.
467    ///
468    /// # Returns
469    ///
470    /// The default proxy of `self`.
471    #[doc(alias = "ges_asset_get_proxy")]
472    #[doc(alias = "get_proxy")]
473    #[must_use]
474    fn proxy(&self) -> Option<Asset> {
475        unsafe { from_glib_none(ffi::ges_asset_get_proxy(self.as_ref().to_glib_none().0)) }
476    }
477
478    /// Gets the [`proxy-target`][struct@crate::Asset#proxy-target] of the asset.
479    ///
480    /// Note that the proxy target may have loaded with an error, so you should
481    /// call [`error()`][Self::error()] on the returned target.
482    ///
483    /// # Returns
484    ///
485    /// The asset that `self` is a proxy
486    /// of.
487    #[doc(alias = "ges_asset_get_proxy_target")]
488    #[doc(alias = "get_proxy_target")]
489    #[doc(alias = "proxy-target")]
490    #[must_use]
491    fn proxy_target(&self) -> Option<Asset> {
492        unsafe {
493            from_glib_none(ffi::ges_asset_get_proxy_target(
494                self.as_ref().to_glib_none().0,
495            ))
496        }
497    }
498
499    /// Get all the proxies that the asset has. The first item of the list will
500    /// be the default [`proxy`][struct@crate::Asset#proxy]. The second will be the proxy that is
501    /// 'next in line' to be default, and so on.
502    ///
503    /// # Returns
504    ///
505    /// The list of proxies
506    /// that `self` has.
507    #[doc(alias = "ges_asset_list_proxies")]
508    fn list_proxies(&self) -> Vec<Asset> {
509        unsafe {
510            FromGlibPtrContainer::from_glib_none(ffi::ges_asset_list_proxies(
511                self.as_ref().to_glib_none().0,
512            ))
513        }
514    }
515
516    /// Sets the [`proxy`][struct@crate::Asset#proxy] for the asset.
517    ///
518    /// If `proxy` is among the existing proxies of the asset (see
519    /// [`list_proxies()`][Self::list_proxies()]) it will be moved to become the default
520    /// proxy. Otherwise, if `proxy` is not [`None`], it will be added to the list
521    /// of proxies, as the new default. The previous default proxy will become
522    /// 'next in line' for if the new one is removed, and so on. As such, this
523    /// will **not** actually remove the previous default proxy (use
524    /// [`unproxy()`][Self::unproxy()] for that).
525    ///
526    /// Note that an asset can only act as a proxy for one other asset.
527    ///
528    /// As a special case, if `proxy` is [`None`], then this method will actually
529    /// remove **all** proxies from the asset.
530    /// ## `proxy`
531    /// A new default proxy for `self`
532    ///
533    /// # Returns
534    ///
535    /// [`true`] if `proxy` was successfully set as the default for
536    /// `self`.
537    #[doc(alias = "ges_asset_set_proxy")]
538    #[doc(alias = "proxy")]
539    fn set_proxy(&self, proxy: Option<&impl IsA<Asset>>) -> Result<(), glib::error::BoolError> {
540        unsafe {
541            glib::result_from_gboolean!(
542                ffi::ges_asset_set_proxy(
543                    self.as_ref().to_glib_none().0,
544                    proxy.map(|p| p.as_ref()).to_glib_none().0
545                ),
546                "Failed to set proxy"
547            )
548        }
549    }
550
551    /// Removes the proxy from the available list of proxies for the asset. If
552    /// the given proxy is the default proxy of the list, then the next proxy
553    /// in the available list (see [`list_proxies()`][Self::list_proxies()]) will become the
554    /// default. If there are no other proxies, then the asset will no longer
555    /// have a default [`proxy`][struct@crate::Asset#proxy].
556    /// ## `proxy`
557    /// An existing proxy of `self`
558    ///
559    /// # Returns
560    ///
561    /// [`true`] if `proxy` was successfully removed from `self`'s proxy
562    /// list.
563    #[doc(alias = "ges_asset_unproxy")]
564    fn unproxy(&self, proxy: &impl IsA<Asset>) -> Result<(), glib::error::BoolError> {
565        unsafe {
566            glib::result_from_gboolean!(
567                ffi::ges_asset_unproxy(
568                    self.as_ref().to_glib_none().0,
569                    proxy.as_ref().to_glib_none().0
570                ),
571                "Failed to unproxy asset"
572            )
573        }
574    }
575
576    #[doc(alias = "proxy")]
577    fn connect_proxy_notify<F: Fn(&Self) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId {
578        unsafe extern "C" fn notify_proxy_trampoline<
579            P: IsA<Asset>,
580            F: Fn(&P) + Send + Sync + 'static,
581        >(
582            this: *mut ffi::GESAsset,
583            _param_spec: glib::ffi::gpointer,
584            f: glib::ffi::gpointer,
585        ) {
586            let f: &F = &*(f as *const F);
587            f(Asset::from_glib_borrow(this).unsafe_cast_ref())
588        }
589        unsafe {
590            let f: Box_<F> = Box_::new(f);
591            connect_raw(
592                self.as_ptr() as *mut _,
593                c"notify::proxy".as_ptr() as *const _,
594                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
595                    notify_proxy_trampoline::<Self, F> as *const (),
596                )),
597                Box_::into_raw(f),
598            )
599        }
600    }
601
602    #[doc(alias = "proxy-target")]
603    fn connect_proxy_target_notify<F: Fn(&Self) + Send + Sync + 'static>(
604        &self,
605        f: F,
606    ) -> SignalHandlerId {
607        unsafe extern "C" fn notify_proxy_target_trampoline<
608            P: IsA<Asset>,
609            F: Fn(&P) + Send + Sync + 'static,
610        >(
611            this: *mut ffi::GESAsset,
612            _param_spec: glib::ffi::gpointer,
613            f: glib::ffi::gpointer,
614        ) {
615            let f: &F = &*(f as *const F);
616            f(Asset::from_glib_borrow(this).unsafe_cast_ref())
617        }
618        unsafe {
619            let f: Box_<F> = Box_::new(f);
620            connect_raw(
621                self.as_ptr() as *mut _,
622                c"notify::proxy-target".as_ptr() as *const _,
623                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
624                    notify_proxy_target_trampoline::<Self, F> as *const (),
625                )),
626                Box_::into_raw(f),
627            )
628        }
629    }
630}
631
632impl<O: IsA<Asset>> AssetExt for O {}