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::{Extractable, MetaContainer, ffi};
7use glib::{
8 prelude::*,
9 signal::{SignalHandlerId, connect_raw},
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 unsafe {
355 let mut error = std::ptr::null_mut();
356 let ret = ffi::ges_asset_request_finish(res, &mut error);
357 let result = if error.is_null() {
358 Ok(from_glib_full(ret))
359 } else {
360 Err(from_glib_full(error))
361 };
362 let callback: Box_<glib::thread_guard::ThreadGuard<P>> =
363 Box_::from_raw(user_data as *mut _);
364 let callback: P = callback.into_inner();
365 callback(result);
366 }
367 }
368 let callback = request_async_with_type_trampoline::<P>;
369 unsafe {
370 ffi::ges_asset_request_async(
371 extractable_type.into_glib(),
372 id.to_glib_none().0,
373 cancellable.map(|p| p.as_ref()).to_glib_none().0,
374 Some(callback),
375 Box_::into_raw(user_data) as *mut _,
376 );
377 }
378 }
379
380 pub fn request_async_with_type_future(
381 extractable_type: glib::types::Type,
382 id: Option<&str>,
383 ) -> Pin<Box_<dyn std::future::Future<Output = Result<Asset, glib::Error>> + 'static>> {
384 skip_assert_initialized!();
385 let id = id.map(ToOwned::to_owned);
386 Box_::pin(gio::GioFuture::new(&(), move |_obj, cancellable, send| {
387 Self::request_async_with_type(
388 extractable_type,
389 id.as_ref().map(::std::borrow::Borrow::borrow),
390 Some(cancellable),
391 move |res| {
392 send.resolve(res);
393 },
394 );
395 }))
396 }
397}
398
399unsafe impl Send for Asset {}
400unsafe impl Sync for Asset {}
401
402/// Trait containing all [`struct@Asset`] methods.
403///
404/// # Implementors
405///
406/// [`Asset`][struct@crate::Asset], [`ClipAsset`][struct@crate::ClipAsset], [`Project`][struct@crate::Project], [`TrackElementAsset`][struct@crate::TrackElementAsset]
407pub trait AssetExt: IsA<Asset> + 'static {
408 /// Extracts a new [`extractable-type`][struct@crate::Asset#extractable-type] object from the asset. The
409 /// [`id`][struct@crate::Asset#id] of the asset may determine the properties and state of the
410 /// newly created object.
411 ///
412 /// # Returns
413 ///
414 /// A newly created object, or [`None`] if an
415 /// error occurred.
416 #[doc(alias = "ges_asset_extract")]
417 fn extract(&self) -> Result<Extractable, glib::Error> {
418 unsafe {
419 let mut error = std::ptr::null_mut();
420 let ret = ffi::ges_asset_extract(self.as_ref().to_glib_none().0, &mut error);
421 if error.is_null() {
422 Ok(from_glib_none(ret))
423 } else {
424 Err(from_glib_full(error))
425 }
426 }
427 }
428
429 /// Retrieve the error that was set on the asset when it was loaded.
430 ///
431 /// # Returns
432 ///
433 /// The error set on `asset`, or
434 /// [`None`] if no error occurred when `asset` was loaded.
435 #[doc(alias = "ges_asset_get_error")]
436 #[doc(alias = "get_error")]
437 fn error(&self) -> Option<glib::Error> {
438 unsafe { from_glib_none(ffi::ges_asset_get_error(self.as_ref().to_glib_none().0)) }
439 }
440
441 /// Gets the [`extractable-type`][struct@crate::Asset#extractable-type] of the asset.
442 ///
443 /// # Returns
444 ///
445 /// The extractable type of `self`.
446 #[doc(alias = "ges_asset_get_extractable_type")]
447 #[doc(alias = "get_extractable_type")]
448 #[doc(alias = "extractable-type")]
449 fn extractable_type(&self) -> glib::types::Type {
450 unsafe {
451 from_glib(ffi::ges_asset_get_extractable_type(
452 self.as_ref().to_glib_none().0,
453 ))
454 }
455 }
456
457 /// Gets the [`id`][struct@crate::Asset#id] of the asset.
458 ///
459 /// # Returns
460 ///
461 /// The ID of `self`.
462 #[doc(alias = "ges_asset_get_id")]
463 #[doc(alias = "get_id")]
464 fn id(&self) -> glib::GString {
465 unsafe { from_glib_none(ffi::ges_asset_get_id(self.as_ref().to_glib_none().0)) }
466 }
467
468 /// Gets the default [`proxy`][struct@crate::Asset#proxy] of the asset.
469 ///
470 /// # Returns
471 ///
472 /// The default proxy of `self`.
473 #[doc(alias = "ges_asset_get_proxy")]
474 #[doc(alias = "get_proxy")]
475 #[must_use]
476 fn proxy(&self) -> Option<Asset> {
477 unsafe { from_glib_none(ffi::ges_asset_get_proxy(self.as_ref().to_glib_none().0)) }
478 }
479
480 /// Gets the [`proxy-target`][struct@crate::Asset#proxy-target] of the asset.
481 ///
482 /// Note that the proxy target may have loaded with an error, so you should
483 /// call [`error()`][Self::error()] on the returned target.
484 ///
485 /// # Returns
486 ///
487 /// The asset that `self` is a proxy
488 /// of.
489 #[doc(alias = "ges_asset_get_proxy_target")]
490 #[doc(alias = "get_proxy_target")]
491 #[doc(alias = "proxy-target")]
492 #[must_use]
493 fn proxy_target(&self) -> Option<Asset> {
494 unsafe {
495 from_glib_none(ffi::ges_asset_get_proxy_target(
496 self.as_ref().to_glib_none().0,
497 ))
498 }
499 }
500
501 /// Get all the proxies that the asset has. The first item of the list will
502 /// be the default [`proxy`][struct@crate::Asset#proxy]. The second will be the proxy that is
503 /// 'next in line' to be default, and so on.
504 ///
505 /// # Returns
506 ///
507 /// The list of proxies
508 /// that `self` has.
509 #[doc(alias = "ges_asset_list_proxies")]
510 fn list_proxies(&self) -> Vec<Asset> {
511 unsafe {
512 FromGlibPtrContainer::from_glib_none(ffi::ges_asset_list_proxies(
513 self.as_ref().to_glib_none().0,
514 ))
515 }
516 }
517
518 /// Sets the [`proxy`][struct@crate::Asset#proxy] for the asset.
519 ///
520 /// If `proxy` is among the existing proxies of the asset (see
521 /// [`list_proxies()`][Self::list_proxies()]) it will be moved to become the default
522 /// proxy. Otherwise, if `proxy` is not [`None`], it will be added to the list
523 /// of proxies, as the new default. The previous default proxy will become
524 /// 'next in line' for if the new one is removed, and so on. As such, this
525 /// will **not** actually remove the previous default proxy (use
526 /// [`unproxy()`][Self::unproxy()] for that).
527 ///
528 /// Note that an asset can only act as a proxy for one other asset.
529 ///
530 /// As a special case, if `proxy` is [`None`], then this method will actually
531 /// remove **all** proxies from the asset.
532 /// ## `proxy`
533 /// A new default proxy for `self`
534 ///
535 /// # Returns
536 ///
537 /// [`true`] if `proxy` was successfully set as the default for
538 /// `self`.
539 #[doc(alias = "ges_asset_set_proxy")]
540 #[doc(alias = "proxy")]
541 fn set_proxy(&self, proxy: Option<&impl IsA<Asset>>) -> Result<(), glib::error::BoolError> {
542 unsafe {
543 glib::result_from_gboolean!(
544 ffi::ges_asset_set_proxy(
545 self.as_ref().to_glib_none().0,
546 proxy.map(|p| p.as_ref()).to_glib_none().0
547 ),
548 "Failed to set proxy"
549 )
550 }
551 }
552
553 /// Removes the proxy from the available list of proxies for the asset. If
554 /// the given proxy is the default proxy of the list, then the next proxy
555 /// in the available list (see [`list_proxies()`][Self::list_proxies()]) will become the
556 /// default. If there are no other proxies, then the asset will no longer
557 /// have a default [`proxy`][struct@crate::Asset#proxy].
558 /// ## `proxy`
559 /// An existing proxy of `self`
560 ///
561 /// # Returns
562 ///
563 /// [`true`] if `proxy` was successfully removed from `self`'s proxy
564 /// list.
565 #[doc(alias = "ges_asset_unproxy")]
566 fn unproxy(&self, proxy: &impl IsA<Asset>) -> Result<(), glib::error::BoolError> {
567 unsafe {
568 glib::result_from_gboolean!(
569 ffi::ges_asset_unproxy(
570 self.as_ref().to_glib_none().0,
571 proxy.as_ref().to_glib_none().0
572 ),
573 "Failed to unproxy asset"
574 )
575 }
576 }
577
578 #[doc(alias = "proxy")]
579 fn connect_proxy_notify<F: Fn(&Self) + Send + Sync + 'static>(&self, f: F) -> SignalHandlerId {
580 unsafe extern "C" fn notify_proxy_trampoline<
581 P: IsA<Asset>,
582 F: Fn(&P) + Send + Sync + 'static,
583 >(
584 this: *mut ffi::GESAsset,
585 _param_spec: glib::ffi::gpointer,
586 f: glib::ffi::gpointer,
587 ) {
588 unsafe {
589 let f: &F = &*(f as *const F);
590 f(Asset::from_glib_borrow(this).unsafe_cast_ref())
591 }
592 }
593 unsafe {
594 let f: Box_<F> = Box_::new(f);
595 connect_raw(
596 self.as_ptr() as *mut _,
597 c"notify::proxy".as_ptr(),
598 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
599 notify_proxy_trampoline::<Self, F> as *const (),
600 )),
601 Box_::into_raw(f),
602 )
603 }
604 }
605
606 #[doc(alias = "proxy-target")]
607 fn connect_proxy_target_notify<F: Fn(&Self) + Send + Sync + 'static>(
608 &self,
609 f: F,
610 ) -> SignalHandlerId {
611 unsafe extern "C" fn notify_proxy_target_trampoline<
612 P: IsA<Asset>,
613 F: Fn(&P) + Send + Sync + 'static,
614 >(
615 this: *mut ffi::GESAsset,
616 _param_spec: glib::ffi::gpointer,
617 f: glib::ffi::gpointer,
618 ) {
619 unsafe {
620 let f: &F = &*(f as *const F);
621 f(Asset::from_glib_borrow(this).unsafe_cast_ref())
622 }
623 }
624 unsafe {
625 let f: Box_<F> = Box_::new(f);
626 connect_raw(
627 self.as_ptr() as *mut _,
628 c"notify::proxy-target".as_ptr(),
629 Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
630 notify_proxy_target_trampoline::<Self, F> as *const (),
631 )),
632 Box_::into_raw(f),
633 )
634 }
635 }
636}
637
638impl<O: IsA<Asset>> AssetExt for O {}