gstreamer/subclass/
child_proxy.rs

1// Take a look at the license at the top of the repository in the LICENSE file.
2
3use glib::{prelude::*, subclass::prelude::*, translate::*};
4
5use super::prelude::*;
6use crate::{ffi, ChildProxy};
7
8pub trait ChildProxyImpl: GstObjectImpl + Send + Sync {
9    fn child_by_name(&self, name: &str) -> Option<glib::Object> {
10        self.parent_child_by_name(name)
11    }
12
13    fn child_by_index(&self, index: u32) -> Option<glib::Object>;
14    fn children_count(&self) -> u32;
15
16    fn child_added(&self, child: &glib::Object, name: &str) {
17        self.parent_child_added(child, name);
18    }
19    fn child_removed(&self, child: &glib::Object, name: &str) {
20        self.parent_child_removed(child, name);
21    }
22}
23
24mod sealed {
25    pub trait Sealed {}
26    impl<T: super::ChildProxyImplExt> Sealed for T {}
27}
28
29pub trait ChildProxyImplExt: sealed::Sealed + ObjectSubclass {
30    fn parent_child_by_name(&self, name: &str) -> Option<glib::Object> {
31        unsafe {
32            let type_data = Self::type_data();
33            let parent_iface = type_data.as_ref().parent_interface::<ChildProxy>()
34                as *const ffi::GstChildProxyInterface;
35
36            let func = (*parent_iface)
37                .get_child_by_name
38                .expect("no parent \"child_by_name\" implementation");
39            let ret = func(
40                self.obj().unsafe_cast_ref::<ChildProxy>().to_glib_none().0,
41                name.to_glib_none().0,
42            );
43            from_glib_full(ret)
44        }
45    }
46
47    fn parent_child_by_index(&self, index: u32) -> Option<glib::Object> {
48        unsafe {
49            let type_data = Self::type_data();
50            let parent_iface = type_data.as_ref().parent_interface::<ChildProxy>()
51                as *const ffi::GstChildProxyInterface;
52
53            let func = (*parent_iface)
54                .get_child_by_index
55                .expect("no parent \"child_by_index\" implementation");
56            let ret = func(
57                self.obj().unsafe_cast_ref::<ChildProxy>().to_glib_none().0,
58                index,
59            );
60            from_glib_full(ret)
61        }
62    }
63
64    fn parent_children_count(&self) -> u32 {
65        unsafe {
66            let type_data = Self::type_data();
67            let parent_iface = type_data.as_ref().parent_interface::<ChildProxy>()
68                as *const ffi::GstChildProxyInterface;
69
70            let func = (*parent_iface)
71                .get_children_count
72                .expect("no parent \"children_count\" implementation");
73            func(self.obj().unsafe_cast_ref::<ChildProxy>().to_glib_none().0)
74        }
75    }
76
77    fn parent_child_added(&self, child: &glib::Object, name: &str) {
78        unsafe {
79            let type_data = Self::type_data();
80            let parent_iface = type_data.as_ref().parent_interface::<ChildProxy>()
81                as *const ffi::GstChildProxyInterface;
82
83            if let Some(func) = (*parent_iface).child_added {
84                func(
85                    self.obj().unsafe_cast_ref::<ChildProxy>().to_glib_none().0,
86                    child.to_glib_none().0,
87                    name.to_glib_none().0,
88                );
89            }
90        }
91    }
92
93    fn parent_child_removed(&self, child: &glib::Object, name: &str) {
94        unsafe {
95            let type_data = Self::type_data();
96            let parent_iface = type_data.as_ref().parent_interface::<ChildProxy>()
97                as *const ffi::GstChildProxyInterface;
98
99            if let Some(func) = (*parent_iface).child_removed {
100                func(
101                    self.obj().unsafe_cast_ref::<ChildProxy>().to_glib_none().0,
102                    child.to_glib_none().0,
103                    name.to_glib_none().0,
104                );
105            }
106        }
107    }
108}
109
110impl<T: ChildProxyImpl> ChildProxyImplExt for T {}
111
112unsafe impl<T: ChildProxyImpl> IsImplementable<T> for ChildProxy {
113    fn interface_init(iface: &mut glib::Interface<Self>) {
114        let iface = iface.as_mut();
115
116        iface.get_child_by_name = Some(child_proxy_get_child_by_name::<T>);
117        iface.get_child_by_index = Some(child_proxy_get_child_by_index::<T>);
118        iface.get_children_count = Some(child_proxy_get_children_count::<T>);
119        iface.child_added = Some(child_proxy_child_added::<T>);
120        iface.child_removed = Some(child_proxy_child_removed::<T>);
121    }
122}
123
124unsafe extern "C" fn child_proxy_get_child_by_name<T: ChildProxyImpl>(
125    child_proxy: *mut ffi::GstChildProxy,
126    name: *const libc::c_char,
127) -> *mut glib::gobject_ffi::GObject {
128    let instance = &*(child_proxy as *mut T::Instance);
129    let imp = instance.imp();
130
131    imp.child_by_name(&glib::GString::from_glib_borrow(name))
132        .into_glib_ptr()
133}
134
135unsafe extern "C" fn child_proxy_get_child_by_index<T: ChildProxyImpl>(
136    child_proxy: *mut ffi::GstChildProxy,
137    index: u32,
138) -> *mut glib::gobject_ffi::GObject {
139    let instance = &*(child_proxy as *mut T::Instance);
140    let imp = instance.imp();
141
142    imp.child_by_index(index).into_glib_ptr()
143}
144
145unsafe extern "C" fn child_proxy_get_children_count<T: ChildProxyImpl>(
146    child_proxy: *mut ffi::GstChildProxy,
147) -> u32 {
148    let instance = &*(child_proxy as *mut T::Instance);
149    let imp = instance.imp();
150
151    imp.children_count()
152}
153
154unsafe extern "C" fn child_proxy_child_added<T: ChildProxyImpl>(
155    child_proxy: *mut ffi::GstChildProxy,
156    child: *mut glib::gobject_ffi::GObject,
157    name: *const libc::c_char,
158) {
159    let instance = &*(child_proxy as *mut T::Instance);
160    let imp = instance.imp();
161
162    imp.child_added(
163        &from_glib_borrow(child),
164        &glib::GString::from_glib_borrow(name),
165    )
166}
167
168unsafe extern "C" fn child_proxy_child_removed<T: ChildProxyImpl>(
169    child_proxy: *mut ffi::GstChildProxy,
170    child: *mut glib::gobject_ffi::GObject,
171    name: *const libc::c_char,
172) {
173    let instance = &*(child_proxy as *mut T::Instance);
174    let imp = instance.imp();
175
176    imp.child_removed(
177        &from_glib_borrow(child),
178        &glib::GString::from_glib_borrow(name),
179    )
180}