1use std::mem;
10use std::ptr;
11
12use glib_ffi;
13use gobject_ffi;
14use gst_ffi;
15
16use glib;
17use glib::translate::*;
18use gst;
19use gst::prelude::*;
20
21use gobject_subclass::anyimpl::*;
22use gobject_subclass::object::*;
23
24pub trait PadImpl<T: PadBase>: AnyImpl + ObjectImpl<T> + Send + Sync + 'static {
25 fn linked(&self, pad: &T, peer: &gst::Pad) {
26 pad.parent_linked(peer)
27 }
28
29 fn unlinked(&self, pad: &T, peer: &gst::Pad) {
30 pad.parent_unlinked(peer)
31 }
32}
33
34any_impl!(PadBase, PadImpl);
35
36pub unsafe trait PadBase: IsA<gst::Pad> + ObjectType {
37 fn parent_linked(&self, peer: &gst::Pad) {
38 unsafe {
39 let klass = self.get_class();
40 let parent_klass = (*klass).get_parent_class() as *const gst_ffi::GstPadClass;
41 (*parent_klass)
42 .linked
43 .map(|f| f(self.to_glib_none().0, peer.to_glib_none().0))
44 .unwrap_or(())
45 }
46 }
47
48 fn parent_unlinked(&self, peer: &gst::Pad) {
49 unsafe {
50 let klass = self.get_class();
51 let parent_klass = (*klass).get_parent_class() as *const gst_ffi::GstPadClass;
52 (*parent_klass)
53 .unlinked
54 .map(|f| f(self.to_glib_none().0, peer.to_glib_none().0))
55 .unwrap_or(())
56 }
57 }
58}
59
60pub unsafe trait PadClassExt<T: PadBase>
61where
62 T::ImplType: PadImpl<T>,
63{
64 fn override_vfuncs(&mut self, _: &ClassInitToken) {
65 unsafe {
66 let klass = &mut *(self as *const Self as *mut gst_ffi::GstPadClass);
67 klass.linked = Some(pad_linked::<T>);
68 klass.unlinked = Some(pad_unlinked::<T>);
69 }
70 }
71}
72
73glib_wrapper! {
74 pub struct Pad(Object<InstanceStruct<Pad>>):
75 [gst::Pad => gst_ffi::GstPad,
76 gst::Object => gst_ffi::GstObject];
77
78 match fn {
79 get_type => || get_type::<Pad>(),
80 }
81}
82
83unsafe impl<T: IsA<gst::Pad> + ObjectType> PadBase for T {}
84pub type PadClass = ClassStruct<Pad>;
85
86unsafe impl PadClassExt<Pad> for PadClass {}
88unsafe impl ObjectClassExt<Pad> for PadClass {}
89
90unsafe impl Send for Pad {}
91unsafe impl Sync for Pad {}
92
93#[macro_export]
94macro_rules! box_pad_impl(
95 ($name:ident) => {
96 box_object_impl!($name);
97
98 impl<T: PadBase> PadImpl<T> for Box<$name<T>>
99 {
100 fn linked(&self, pad: &T, peer: &gst::Pad) {
101 let imp: &$name<T> = self.as_ref();
102 imp.linked(pad, peer)
103 }
104
105 fn unlinked(&self, pad: &T, peer: &gst::Pad) {
106 let imp: &$name<T> = self.as_ref();
107 imp.unlinked(pad, peer)
108 }
109 }
110 };
111);
112box_pad_impl!(PadImpl);
113
114impl ObjectType for Pad {
115 const NAME: &'static str = "RsPad";
116 type ParentType = gst::Pad;
117 type ImplType = Box<PadImpl<Self>>;
118 type InstanceStructType = InstanceStruct<Self>;
119
120 fn class_init(token: &ClassInitToken, klass: &mut PadClass) {
121 ObjectClassExt::override_vfuncs(klass, token);
122 PadClassExt::override_vfuncs(klass, token);
123 }
124
125 object_type_fns!();
126}
127
128unsafe extern "C" fn pad_linked<T: PadBase>(ptr: *mut gst_ffi::GstPad, peer: *mut gst_ffi::GstPad)
129where
130 T::ImplType: PadImpl<T>,
131{
132 floating_reference_guard!(ptr);
133 let pad = &*(ptr as *mut T::InstanceStructType);
134 let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
135 let imp = pad.get_impl();
136
137 imp.linked(&wrap, &from_glib_borrow(peer))
138}
139
140unsafe extern "C" fn pad_unlinked<T: PadBase>(ptr: *mut gst_ffi::GstPad, peer: *mut gst_ffi::GstPad)
141where
142 T::ImplType: PadImpl<T>,
143{
144 floating_reference_guard!(ptr);
145 let pad = &*(ptr as *mut T::InstanceStructType);
146 let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType);
147 let imp = pad.get_impl();
148
149 imp.unlinked(&wrap, &from_glib_borrow(peer))
150}