From 31a48c4baad7d1daf45971bd069d613870af3df9 Mon Sep 17 00:00:00 2001 From: Dirk Van Haerenborgh Date: Wed, 25 Apr 2018 13:38:32 +0200 Subject: [PATCH] Split out base object traits This allows using this independent from GStreamer for subclassing e.g. GIO or GTK GObjects. Fixes https://github.com/sdroege/gst-plugin-rs/issues/28 Fixes https://github.com/sdroege/gst-plugin-rs/pull/32 --- Cargo.toml | 1 + gobject-subclass/Cargo.toml | 18 + .../src/anyimpl.rs | 12 +- gobject-subclass/src/guard.rs | 49 ++ gobject-subclass/src/lib.rs | 29 + gobject-subclass/src/object.rs | 524 ++++++++++++++++++ .../src/properties.rs | 0 gst-plugin/Cargo.toml | 1 + gst-plugin/src/base_sink.rs | 135 +++-- gst-plugin/src/base_src.rs | 153 ++--- gst-plugin/src/base_transform.rs | 139 +++-- gst-plugin/src/bin.rs | 48 +- gst-plugin/src/element.rs | 101 ++-- gst-plugin/src/lib.rs | 48 +- gst-plugin/src/object.rs | 517 +---------------- gst-plugin/src/pipeline.rs | 22 +- gst-plugin/src/uri_handler.rs | 4 +- 17 files changed, 1028 insertions(+), 773 deletions(-) create mode 100644 gobject-subclass/Cargo.toml rename {gst-plugin => gobject-subclass}/src/anyimpl.rs (86%) create mode 100644 gobject-subclass/src/guard.rs create mode 100644 gobject-subclass/src/lib.rs create mode 100644 gobject-subclass/src/object.rs rename {gst-plugin => gobject-subclass}/src/properties.rs (100%) diff --git a/Cargo.toml b/Cargo.toml index 98caf511..53c88e2d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,7 @@ [workspace] members = [ + "gobject-subclass", "gst-plugin", "gst-plugin-simple", "gst-plugin-file", diff --git a/gobject-subclass/Cargo.toml b/gobject-subclass/Cargo.toml new file mode 100644 index 00000000..ea579b42 --- /dev/null +++ b/gobject-subclass/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "gobject-subclass" +version = "0.1.0" +authors = ["Sebastian Dröge "] +repository = "https://github.com/sdroege/gst-plugin-rs/tree/master/gobject-subclass" +license = "MIT/Apache-2.0" + +[dependencies] +libc = "0.2" +lazy_static = "1.0" +byteorder = "1.0" +glib-sys = { git = "https://github.com/gtk-rs/sys" } +gobject-sys = { git = "https://github.com/gtk-rs/sys" } +glib = { git = "https://github.com/gtk-rs/glib" } + +[lib] +name = "gobject_subclass" +path = "src/lib.rs" diff --git a/gst-plugin/src/anyimpl.rs b/gobject-subclass/src/anyimpl.rs similarity index 86% rename from gst-plugin/src/anyimpl.rs rename to gobject-subclass/src/anyimpl.rs index b3452575..ab8eef87 100644 --- a/gst-plugin/src/anyimpl.rs +++ b/gobject-subclass/src/anyimpl.rs @@ -20,9 +20,17 @@ impl AnyImpl for T { } } +// warning: constraints is defined as a repetition to minimize code duplication. +// multiple items will generate invalide code. +#[macro_export] macro_rules! any_impl { - ($bound:ident, $trait:ident) => { - impl $trait { + + ($bound:ident, $trait:ident $(, $constraint:ident)*) => { + impl $trait + $( + where T::InstanceStructType: $constraint + )* + { #[inline] pub fn downcast_ref>(&self) -> Option<&U> { if self.is::() { diff --git a/gobject-subclass/src/guard.rs b/gobject-subclass/src/guard.rs new file mode 100644 index 00000000..ead6a6d2 --- /dev/null +++ b/gobject-subclass/src/guard.rs @@ -0,0 +1,49 @@ +// Copyright (C) 2016-2017 Sebastian Dröge +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::ptr; + +use glib_ffi; +use gobject_ffi; +use glib; + +#[macro_export] +macro_rules! callback_guard { + () => { + let _guard = ::glib::CallbackGuard::new(); + }; +} + +#[macro_export] +macro_rules! floating_reference_guard { + ($obj:ident) => { + let _guard = $crate::FloatingReferenceGuard::new($obj as *mut _); + }; +} + +pub struct FloatingReferenceGuard(ptr::NonNull); + +impl FloatingReferenceGuard { + pub unsafe fn new(obj: *mut gobject_ffi::GObject) -> Option { + assert!(!obj.is_null()); + if gobject_ffi::g_object_is_floating(obj) != glib_ffi::GFALSE { + gobject_ffi::g_object_ref_sink(obj); + Some(FloatingReferenceGuard(ptr::NonNull::new_unchecked(obj))) + } else { + None + } + } +} + +impl Drop for FloatingReferenceGuard { + fn drop(&mut self) { + unsafe { + gobject_ffi::g_object_force_floating(self.0.as_ptr()); + } + } +} diff --git a/gobject-subclass/src/lib.rs b/gobject-subclass/src/lib.rs new file mode 100644 index 00000000..4cc337e1 --- /dev/null +++ b/gobject-subclass/src/lib.rs @@ -0,0 +1,29 @@ +// Copyright (C) 2016-2017 Sebastian Dröge +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +extern crate byteorder; +pub extern crate glib_sys as glib_ffi; +pub extern crate gobject_sys as gobject_ffi; + +#[macro_use] +extern crate lazy_static; +extern crate libc; + +#[macro_use] +pub extern crate glib; + +#[macro_use] +pub mod anyimpl; + +#[macro_use] +pub mod guard; +pub use guard::FloatingReferenceGuard; + +pub mod properties; +#[macro_use] +pub mod object; diff --git a/gobject-subclass/src/object.rs b/gobject-subclass/src/object.rs new file mode 100644 index 00000000..6578b716 --- /dev/null +++ b/gobject-subclass/src/object.rs @@ -0,0 +1,524 @@ +// Copyright (C) 2017 Sebastian Dröge +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::any::TypeId; +use std::collections::BTreeMap; +use std::ffi::CString; +use std::mem; +use std::ptr; +use std::sync::Mutex; + +use glib_ffi; +use gobject_ffi; + +use glib; +use glib::translate::*; + +use properties::*; + +pub trait ObjectImpl: Send + Sync + 'static { + fn set_property(&self, _obj: &glib::Object, _id: u32, _value: &glib::Value) { + unimplemented!() + } + + fn get_property(&self, _obj: &glib::Object, _id: u32) -> Result { + unimplemented!() + } + + fn notify(&self, obj: &glib::Object, name: &str) { + unsafe { + gobject_ffi::g_object_notify(obj.to_glib_none().0, name.to_glib_none().0); + } + } +} + +// warning: constraints is defined as a repetition to minimize code duplication. +// multiple items will generate invalide code. +#[macro_export] +macro_rules! box_object_impl( + ($name:ident $(, $constraint:ident)*) => { + impl ObjectImpl for Box<$name> + $( + where T::InstanceStructType: $constraint + )* + { + fn set_property(&self, obj: &glib::Object, id: u32, value: &glib::Value) { + let imp: &$name = self.as_ref(); + imp.set_property(obj, id, value); + } + + fn get_property(&self, obj: &glib::Object, id: u32) -> Result { + let imp: &$name = self.as_ref(); + imp.get_property(obj, id) + } + } + }; +); + +pub trait ImplTypeStatic: Send + Sync + 'static { + fn get_name(&self) -> &str; + fn new(&self, &T) -> T::ImplType; + fn class_init(&self, &mut ClassStruct); + fn type_init(&self, _: &TypeInitToken, _type_: glib::Type) {} +} + +pub struct ClassInitToken(()); +pub struct TypeInitToken(()); + + +pub trait ObjectType: FromGlibPtrBorrow<*mut ::InstanceStructType> +where Self: Sized + 'static, + Self::InstanceStructType: Instance +{ + const NAME: &'static str; + type InstanceStructType: Instance + 'static; + type GlibType; + type GlibClassType; + type ImplType: ObjectImpl; + + + fn glib_type() -> glib::Type; + + fn class_init(token: &ClassInitToken, klass: &mut ClassStruct); + + fn set_property(_obj: &Self, _id: u32, _value: &glib::Value) { + unimplemented!() + } + + fn get_property(_obj: &Self, _id: u32) -> Result { + unimplemented!() + } + + unsafe fn get_instance(&self) -> *mut Self::InstanceStructType; + + + fn get_impl(&self) -> &Self::ImplType{ + unsafe { (*self.get_instance()).get_impl() } + } + + unsafe fn get_class(&self) -> *const ClassStruct{ + (*self.get_instance()).get_class() + } +} + +#[macro_export] +macro_rules! object_type_fns( + () => { + unsafe fn get_instance(&self) -> *mut Self::InstanceStructType { + self.to_glib_none().0 + } + } +); + + +pub trait Instance +{ + fn parent(&self) -> &T::GlibType; + + fn get_impl(&self) -> &T::ImplType; + + unsafe fn set_impl(&mut self, imp:ptr::NonNull); + + unsafe fn get_class(&self) -> *const ClassStruct; +} + +#[repr(C)] +pub struct InstanceStruct +{ + _parent: T::GlibType, + _imp: ptr::NonNull, +} + + +#[repr(C)] +pub struct ClassStruct { + pub parent: T::GlibClassType, + pub imp_static: ptr::NonNull>>, + pub parent_class: ptr::NonNull, + pub interfaces_static: *const Vec<(glib_ffi::GType, glib_ffi::gpointer)>, +} + +impl ClassStruct { + pub fn get_parent_class(&self) -> *const T::GlibClassType { + self.parent_class.as_ptr() + } +} + +impl ClassStruct { + pub fn get_interface_static(&self, type_: glib_ffi::GType) -> glib_ffi::gpointer { + unsafe { + if self.interfaces_static.is_null() { + return ptr::null_mut(); + } + + for &(t, p) in &(*self.interfaces_static) { + if t == type_ { + return p; + } + } + + ptr::null_mut() + } + } +} + +pub unsafe trait ObjectClass { + fn install_properties(&mut self, properties: &[Property]) { + if properties.is_empty() { + return; + } + + let mut pspecs = Vec::with_capacity(properties.len()); + + pspecs.push(ptr::null_mut()); + + for property in properties { + pspecs.push(property.into()); + } + + unsafe { + gobject_ffi::g_object_class_install_properties( + self as *mut _ as *mut gobject_ffi::GObjectClass, + pspecs.len() as u32, + pspecs.as_mut_ptr(), + ); + } + } + + fn add_signal(&mut self, name: &str, arg_types: &[glib::Type], ret_type: glib::Type) { + let arg_types = arg_types.iter().map(|t| t.to_glib()).collect::>(); + unsafe { + gobject_ffi::g_signal_newv( + name.to_glib_none().0, + *(self as *mut _ as *mut glib_ffi::GType), + gobject_ffi::G_SIGNAL_RUN_LAST, + ptr::null_mut(), + None, + ptr::null_mut(), + None, + ret_type.to_glib(), + arg_types.len() as u32, + arg_types.as_ptr() as *mut _, + ); + } + } + + fn add_signal_with_accumulator( + &mut self, + name: &str, + arg_types: &[glib::Type], + ret_type: glib::Type, + accumulator: F, + ) where + F: Fn(&mut glib::Value, &glib::Value) -> bool + Send + Sync + 'static, + { + let arg_types = arg_types.iter().map(|t| t.to_glib()).collect::>(); + + let accumulator: Box< + Box bool + Send + Sync + 'static>, + > = Box::new(Box::new(accumulator)); + + unsafe extern "C" fn accumulator_trampoline( + _ihint: *mut gobject_ffi::GSignalInvocationHint, + return_accu: *mut gobject_ffi::GValue, + handler_return: *const gobject_ffi::GValue, + data: glib_ffi::gpointer, + ) -> glib_ffi::gboolean { + callback_guard!(); + let accumulator: &&(Fn(&mut glib::Value, &glib::Value) -> bool + + Send + + Sync + + 'static) = mem::transmute(data); + accumulator( + &mut *(return_accu as *mut glib::Value), + &*(handler_return as *const glib::Value), + ).to_glib() + } + + unsafe { + gobject_ffi::g_signal_newv( + name.to_glib_none().0, + *(self as *mut _ as *mut glib_ffi::GType), + gobject_ffi::G_SIGNAL_RUN_LAST, + ptr::null_mut(), + Some(accumulator_trampoline), + Box::into_raw(accumulator) as glib_ffi::gpointer, + None, + ret_type.to_glib(), + arg_types.len() as u32, + arg_types.as_ptr() as *mut _, + ); + } + } + + fn add_action_signal( + &mut self, + name: &str, + arg_types: &[glib::Type], + ret_type: glib::Type, + handler: F, + ) where + F: Fn(&[glib::Value]) -> Option + Send + Sync + 'static, + { + let arg_types = arg_types.iter().map(|t| t.to_glib()).collect::>(); + let handler = glib::Closure::new(handler); + unsafe { + gobject_ffi::g_signal_newv( + name.to_glib_none().0, + *(self as *mut _ as *mut glib_ffi::GType), + gobject_ffi::G_SIGNAL_RUN_LAST | gobject_ffi::G_SIGNAL_ACTION, + handler.to_glib_none().0, + None, + ptr::null_mut(), + None, + ret_type.to_glib(), + arg_types.len() as u32, + arg_types.as_ptr() as *mut _, + ); + } + } +} + +unsafe impl ObjectClass for ClassStruct {} + +unsafe extern "C" fn class_init( + klass: glib_ffi::gpointer, + _klass_data: glib_ffi::gpointer, +) +{ + callback_guard!(); + { + let gobject_klass = &mut *(klass as *mut gobject_ffi::GObjectClass); + + gobject_klass.finalize = Some(finalize::); + gobject_klass.set_property = Some(set_property::); + gobject_klass.get_property = Some(get_property::); + } + + { + let klass = &mut *(klass as *mut ClassStruct); + let parent_class = gobject_ffi::g_type_class_peek_parent( + klass as *mut _ as glib_ffi::gpointer, + ) as *mut T::GlibClassType; + assert!(!parent_class.is_null()); + klass.parent_class = ptr::NonNull::new_unchecked(parent_class); + T::class_init(&ClassInitToken(()), klass); + } +} + +unsafe extern "C" fn finalize(obj: *mut gobject_ffi::GObject) { + callback_guard!(); + let instance = &mut *(obj as *mut T::InstanceStructType); + + drop(Box::from_raw(instance.get_impl() as *const _ as *mut T::ImplType)); + instance.set_impl(ptr::NonNull::dangling()); + + let klass = *(obj as *const glib_ffi::gpointer); + let parent_klass = gobject_ffi::g_type_class_peek_parent(klass); + let parent_klass = + &*(gobject_ffi::g_type_class_peek_parent(parent_klass) as *const gobject_ffi::GObjectClass); + parent_klass.finalize.map(|f| f(obj)); +} + +unsafe extern "C" fn get_property( + obj: *mut gobject_ffi::GObject, + id: u32, + value: *mut gobject_ffi::GValue, + _pspec: *mut gobject_ffi::GParamSpec, +) +{ + callback_guard!(); + floating_reference_guard!(obj); + match T::get_property(&from_glib_borrow(obj as *mut T::InstanceStructType), id - 1) { + Ok(v) => { + gobject_ffi::g_value_unset(value); + ptr::write(value, ptr::read(v.to_glib_none().0)); + mem::forget(v); + } + Err(()) => eprintln!("Failed to get property"), + } +} + +unsafe extern "C" fn set_property( + obj: *mut gobject_ffi::GObject, + id: u32, + value: *mut gobject_ffi::GValue, + _pspec: *mut gobject_ffi::GParamSpec, +) +{ + callback_guard!(); + floating_reference_guard!(obj); + T::set_property( + &from_glib_borrow(obj as *mut T::InstanceStructType), + id - 1, + &*(value as *mut glib::Value), + ); +} + +static mut TYPES: *mut Mutex> = 0 as *mut _; + +pub unsafe fn get_type() -> glib_ffi::GType +{ + use std::sync::{Once, ONCE_INIT}; + + static ONCE: Once = ONCE_INIT; + + ONCE.call_once(|| { + TYPES = Box::into_raw(Box::new(Mutex::new(BTreeMap::new()))); + }); + + let mut types = (*TYPES).lock().unwrap(); + types + .entry(TypeId::of::()) + .or_insert_with(|| { + let type_info = gobject_ffi::GTypeInfo { + class_size: mem::size_of::>() as u16, + base_init: None, + base_finalize: None, + class_init: Some(class_init::), + class_finalize: None, + class_data: ptr::null_mut(), + instance_size: mem::size_of::() as u16, + n_preallocs: 0, + instance_init: None, + value_table: ptr::null(), + }; + + let type_name = { + let mut idx = 0; + + loop { + let type_name = CString::new(format!("{}-{}", T::NAME, idx)).unwrap(); + if gobject_ffi::g_type_from_name(type_name.as_ptr()) + == gobject_ffi::G_TYPE_INVALID + { + break type_name; + } + idx += 1; + } + }; + + from_glib(gobject_ffi::g_type_register_static( + T::glib_type().to_glib(), + type_name.as_ptr(), + &type_info, + gobject_ffi::G_TYPE_FLAG_ABSTRACT, + )) + }) + .to_glib() +} + +unsafe extern "C" fn sub_class_init( + klass: glib_ffi::gpointer, + klass_data: glib_ffi::gpointer, +) { + callback_guard!(); + { + let gobject_klass = &mut *(klass as *mut gobject_ffi::GObjectClass); + + gobject_klass.set_property = Some(sub_set_property::); + gobject_klass.get_property = Some(sub_get_property::); + } + { + assert!(!klass_data.is_null()); + let klass = &mut *(klass as *mut ClassStruct); + let imp_static = klass_data as *mut Box>; + klass.imp_static = ptr::NonNull::new_unchecked(imp_static); + klass.interfaces_static = Box::into_raw(Box::new(Vec::new())); + + (*imp_static).class_init(klass); + } +} + +unsafe extern "C" fn sub_get_property( + obj: *mut gobject_ffi::GObject, + id: u32, + value: *mut gobject_ffi::GValue, + _pspec: *mut gobject_ffi::GParamSpec, +) { + callback_guard!(); + floating_reference_guard!(obj); + let instance = &*(obj as *mut T::InstanceStructType); + let imp = instance.get_impl(); + + match imp.get_property(&from_glib_borrow(obj), id - 1) { + Ok(v) => { + gobject_ffi::g_value_unset(value); + ptr::write(value, ptr::read(v.to_glib_none().0)); + mem::forget(v); + } + Err(()) => eprintln!("Failed to get property"), + } +} + +unsafe extern "C" fn sub_set_property( + obj: *mut gobject_ffi::GObject, + id: u32, + value: *mut gobject_ffi::GValue, + _pspec: *mut gobject_ffi::GParamSpec, +) { + callback_guard!(); + floating_reference_guard!(obj); + let instance = &*(obj as *mut T::InstanceStructType); + let imp = instance.get_impl(); + imp.set_property( + &from_glib_borrow(obj), + id - 1, + &*(value as *mut glib::Value), + ); +} + +unsafe extern "C" fn sub_init( + obj: *mut gobject_ffi::GTypeInstance, + _klass: glib_ffi::gpointer, +) +{ + callback_guard!(); + floating_reference_guard!(obj); + let instance = &mut *(obj as *mut T::InstanceStructType); + let klass = &**(obj as *const *const ClassStruct); + let rs_instance: T = from_glib_borrow(obj as *mut T::InstanceStructType); + + let imp = klass.imp_static.as_ref().new(&rs_instance); + instance.set_impl(ptr::NonNull::new_unchecked(Box::into_raw(Box::new(imp)))); +} + +pub fn register_type>(imp: I) -> glib::Type +{ + unsafe { + let parent_type = get_type::(); + let type_name = format!("{}-{}", T::NAME, imp.get_name()); + + let imp: Box> = Box::new(imp); + let imp_ptr = Box::into_raw(Box::new(imp)); + + let type_info = gobject_ffi::GTypeInfo { + class_size: mem::size_of::>() as u16, + base_init: None, + base_finalize: None, + class_init: Some(sub_class_init::), + class_finalize: None, + class_data: imp_ptr as glib_ffi::gpointer, + instance_size: mem::size_of::() as u16, + n_preallocs: 0, + instance_init: Some(sub_init::), + value_table: ptr::null(), + }; + + let type_ = from_glib(gobject_ffi::g_type_register_static( + parent_type, + type_name.to_glib_none().0, + &type_info, + 0, + )); + + (*imp_ptr).type_init(&TypeInitToken(()), type_); + + type_ + } +} diff --git a/gst-plugin/src/properties.rs b/gobject-subclass/src/properties.rs similarity index 100% rename from gst-plugin/src/properties.rs rename to gobject-subclass/src/properties.rs diff --git a/gst-plugin/Cargo.toml b/gst-plugin/Cargo.toml index cb45f402..45172074 100644 --- a/gst-plugin/Cargo.toml +++ b/gst-plugin/Cargo.toml @@ -15,6 +15,7 @@ keywords = ["gstreamer", "multimedia", "audio", "video", "gnome"] libc = "0.2" lazy_static = "1.0" byteorder = "1.0" +gobject-subclass = { path="../gobject-subclass" } glib-sys = { git = "https://github.com/gtk-rs/sys" } gobject-sys = { git = "https://github.com/gtk-rs/sys" } gstreamer-sys = { git = "https://github.com/sdroege/gstreamer-sys" } diff --git a/gst-plugin/src/base_sink.rs b/gst-plugin/src/base_sink.rs index a82004ba..f637a1a6 100644 --- a/gst-plugin/src/base_sink.rs +++ b/gst-plugin/src/base_sink.rs @@ -26,6 +26,8 @@ use object::*; pub trait BaseSinkImpl: AnyImpl + ObjectImpl + ElementImpl + Send + Sync + 'static +where + T::InstanceStructType: PanicPoison { fn start(&self, _element: &T) -> bool { true @@ -92,7 +94,7 @@ pub trait BaseSinkImpl: } } -any_impl!(BaseSinkBase, BaseSinkImpl); +any_impl!(BaseSinkBase, BaseSinkImpl, PanicPoison); pub unsafe trait BaseSinkBase: IsA + IsA + ObjectType @@ -163,6 +165,7 @@ pub unsafe trait BaseSinkBase: pub unsafe trait BaseSinkClassExt where T::ImplType: BaseSinkImpl, + T::InstanceStructType: PanicPoison { fn override_vfuncs(&mut self, _: &ClassInitToken) { unsafe { @@ -185,9 +188,10 @@ where } glib_wrapper! { - pub struct BaseSink(Object>): [gst_base::BaseSink => gst_base_ffi::GstBaseSink, - gst::Element => gst_ffi::GstElement, - gst::Object => gst_ffi::GstObject]; + pub struct BaseSink(Object>): + [gst_base::BaseSink => gst_base_ffi::GstBaseSink, + gst::Element => gst_ffi::GstElement, + gst::Object => gst_ffi::GstObject]; match fn { get_type => || get_type::(), @@ -209,7 +213,10 @@ macro_rules! box_base_sink_impl( ($name:ident) => { box_element_impl!($name); - impl BaseSinkImpl for Box<$name> { + impl BaseSinkImpl for Box<$name> + where + T::InstanceStructType: PanicPoison + { fn start(&self, element: &T) -> bool { let imp: &$name = self.as_ref(); imp.start(element) @@ -285,6 +292,7 @@ impl ObjectType for BaseSink { type GlibType = gst_base_ffi::GstBaseSink; type GlibClassType = gst_base_ffi::GstBaseSinkClass; type ImplType = Box>; + type InstanceStructType = ElementInstanceStruct; fn glib_type() -> glib::Type { unsafe { from_glib(gst_base_ffi::gst_base_sink_get_type()) } @@ -303,14 +311,15 @@ unsafe extern "C" fn base_sink_start( ) -> glib_ffi::gboolean where T::ImplType: BaseSinkImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, false, { imp.start(&wrap) }).to_glib() + panic_to_error!(&wrap, &element.panicked(), false, { imp.start(&wrap) }).to_glib() } unsafe extern "C" fn base_sink_stop( @@ -318,14 +327,15 @@ unsafe extern "C" fn base_sink_stop( ) -> glib_ffi::gboolean where T::ImplType: BaseSinkImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, false, { imp.stop(&wrap) }).to_glib() + panic_to_error!(&wrap, &element.panicked(), false, { imp.stop(&wrap) }).to_glib() } unsafe extern "C" fn base_sink_render( @@ -334,15 +344,16 @@ unsafe extern "C" fn base_sink_render( ) -> gst_ffi::GstFlowReturn where T::ImplType: BaseSinkImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); let buffer = gst::BufferRef::from_ptr(buffer); - panic_to_error!(&wrap, &element.panicked, gst::FlowReturn::Error, { + panic_to_error!(&wrap, &element.panicked(), gst::FlowReturn::Error, { imp.render(&wrap, buffer) }).to_glib() } @@ -353,15 +364,16 @@ unsafe extern "C" fn base_sink_prepare( ) -> gst_ffi::GstFlowReturn where T::ImplType: BaseSinkImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); let buffer = gst::BufferRef::from_ptr(buffer); - panic_to_error!(&wrap, &element.panicked, gst::FlowReturn::Error, { + panic_to_error!(&wrap, &element.panicked(), gst::FlowReturn::Error, { imp.prepare(&wrap, buffer) }).to_glib() } @@ -372,15 +384,16 @@ unsafe extern "C" fn base_sink_render_list( ) -> gst_ffi::GstFlowReturn where T::ImplType: BaseSinkImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); let list = gst::BufferListRef::from_ptr(list); - panic_to_error!(&wrap, &element.panicked, gst::FlowReturn::Error, { + panic_to_error!(&wrap, &element.panicked(), gst::FlowReturn::Error, { imp.render_list(&wrap, list) }).to_glib() } @@ -391,15 +404,16 @@ unsafe extern "C" fn base_sink_prepare_list( ) -> gst_ffi::GstFlowReturn where T::ImplType: BaseSinkImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); let list = gst::BufferListRef::from_ptr(list); - panic_to_error!(&wrap, &element.panicked, gst::FlowReturn::Error, { + panic_to_error!(&wrap, &element.panicked(), gst::FlowReturn::Error, { imp.prepare_list(&wrap, list) }).to_glib() } @@ -410,15 +424,16 @@ unsafe extern "C" fn base_sink_query( ) -> glib_ffi::gboolean where T::ImplType: BaseSinkImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); let query = gst::QueryRef::from_mut_ptr(query_ptr); - panic_to_error!(&wrap, &element.panicked, false, { + panic_to_error!(&wrap, &element.panicked(), false, { BaseSinkImpl::query(imp, &wrap, query) }).to_glib() } @@ -429,14 +444,15 @@ unsafe extern "C" fn base_sink_event( ) -> glib_ffi::gboolean where T::ImplType: BaseSinkImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, false, { + panic_to_error!(&wrap, &element.panicked(), false, { imp.event(&wrap, from_glib_full(event_ptr)) }).to_glib() } @@ -447,19 +463,20 @@ unsafe extern "C" fn base_sink_get_caps( ) -> *mut gst_ffi::GstCaps where T::ImplType: BaseSinkImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); let filter = if filter.is_null() { None } else { Some(gst::CapsRef::from_ptr(filter)) }; - panic_to_error!(&wrap, &element.panicked, None, { + panic_to_error!(&wrap, &element.panicked(), None, { imp.get_caps(&wrap, filter) }).map(|caps| caps.into_ptr()) .unwrap_or(ptr::null_mut()) @@ -471,15 +488,16 @@ unsafe extern "C" fn base_sink_set_caps( ) -> glib_ffi::gboolean where T::ImplType: BaseSinkImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); let caps = gst::CapsRef::from_ptr(caps); - panic_to_error!(&wrap, &element.panicked, false, { + panic_to_error!(&wrap, &element.panicked(), false, { imp.set_caps(&wrap, caps) }).to_glib() } @@ -490,15 +508,16 @@ unsafe extern "C" fn base_sink_fixate( ) -> *mut gst_ffi::GstCaps where T::ImplType: BaseSinkImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); let caps = from_glib_full(caps); - panic_to_error!(&wrap, &element.panicked, gst::Caps::new_empty(), { + panic_to_error!(&wrap, &element.panicked(), gst::Caps::new_empty(), { imp.fixate(&wrap, caps) }).into_ptr() } @@ -508,14 +527,15 @@ unsafe extern "C" fn base_sink_unlock( ) -> glib_ffi::gboolean where T::ImplType: BaseSinkImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, false, { imp.unlock(&wrap) }).to_glib() + panic_to_error!(&wrap, &element.panicked(), false, { imp.unlock(&wrap) }).to_glib() } unsafe extern "C" fn base_sink_unlock_stop( @@ -523,12 +543,13 @@ unsafe extern "C" fn base_sink_unlock_stop( ) -> glib_ffi::gboolean where T::ImplType: BaseSinkImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, false, { imp.unlock_stop(&wrap) }).to_glib() + panic_to_error!(&wrap, &element.panicked(), false, { imp.unlock_stop(&wrap) }).to_glib() } diff --git a/gst-plugin/src/base_src.rs b/gst-plugin/src/base_src.rs index 9594f3bb..e945a223 100644 --- a/gst-plugin/src/base_src.rs +++ b/gst-plugin/src/base_src.rs @@ -26,6 +26,8 @@ use object::*; pub trait BaseSrcImpl: AnyImpl + ObjectImpl + ElementImpl + Send + Sync + 'static +where + T::InstanceStructType: PanicPoison { fn start(&self, _element: &T) -> bool { true @@ -99,7 +101,7 @@ pub trait BaseSrcImpl: } } -any_impl!(BaseSrcBase, BaseSrcImpl); +any_impl!(BaseSrcBase, BaseSrcImpl, PanicPoison); pub unsafe trait BaseSrcBase: IsA + IsA + ObjectType @@ -212,6 +214,7 @@ pub unsafe trait BaseSrcBase: pub unsafe trait BaseSrcClassExt where T::ImplType: BaseSrcImpl, + T::InstanceStructType: PanicPoison { fn override_vfuncs(&mut self, _: &ClassInitToken) { unsafe { @@ -236,9 +239,10 @@ where } glib_wrapper! { - pub struct BaseSrc(Object>): [gst_base::BaseSrc => gst_base_ffi::GstBaseSrc, - gst::Element => gst_ffi::GstElement, - gst::Object => gst_ffi::GstObject]; + pub struct BaseSrc(Object>): + [gst_base::BaseSrc => gst_base_ffi::GstBaseSrc, + gst::Element => gst_ffi::GstElement, + gst::Object => gst_ffi::GstObject]; match fn { get_type => || get_type::(), @@ -260,7 +264,10 @@ macro_rules! box_base_src_impl( ($name:ident) => { box_element_impl!($name); - impl BaseSrcImpl for Box<$name> { + impl BaseSrcImpl for Box<$name> + where + T::InstanceStructType: PanicPoison + { fn start(&self, element: &T) -> bool { let imp: &$name = self.as_ref(); imp.start(element) @@ -356,6 +363,7 @@ impl ObjectType for BaseSrc { type GlibType = gst_base_ffi::GstBaseSrc; type GlibClassType = gst_base_ffi::GstBaseSrcClass; type ImplType = Box>; + type InstanceStructType = ElementInstanceStruct; fn glib_type() -> glib::Type { unsafe { from_glib(gst_base_ffi::gst_base_src_get_type()) } @@ -374,14 +382,15 @@ unsafe extern "C" fn base_src_start( ) -> glib_ffi::gboolean where T::ImplType: BaseSrcImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, false, { imp.start(&wrap) }).to_glib() + panic_to_error!(&wrap, &element.panicked(), false, { imp.start(&wrap) }).to_glib() } unsafe extern "C" fn base_src_stop( @@ -389,14 +398,15 @@ unsafe extern "C" fn base_src_stop( ) -> glib_ffi::gboolean where T::ImplType: BaseSrcImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, false, { imp.stop(&wrap) }).to_glib() + panic_to_error!(&wrap, &element.panicked(), false, { imp.stop(&wrap) }).to_glib() } unsafe extern "C" fn base_src_is_seekable( @@ -404,14 +414,15 @@ unsafe extern "C" fn base_src_is_seekable( ) -> glib_ffi::gboolean where T::ImplType: BaseSrcImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, false, { imp.is_seekable(&wrap) }).to_glib() + panic_to_error!(&wrap, &element.panicked(), false, { imp.is_seekable(&wrap) }).to_glib() } unsafe extern "C" fn base_src_get_size( @@ -420,14 +431,15 @@ unsafe extern "C" fn base_src_get_size( ) -> glib_ffi::gboolean where T::ImplType: BaseSrcImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, false, { + panic_to_error!(&wrap, &element.panicked(), false, { match imp.get_size(&wrap) { Some(s) => { *size = s; @@ -446,15 +458,16 @@ unsafe extern "C" fn base_src_fill( ) -> gst_ffi::GstFlowReturn where T::ImplType: BaseSrcImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); let buffer = gst::BufferRef::from_mut_ptr(buffer); - panic_to_error!(&wrap, &element.panicked, gst::FlowReturn::Error, { + panic_to_error!(&wrap, &element.panicked(), gst::FlowReturn::Error, { imp.fill(&wrap, offset, length, buffer) }).to_glib() } @@ -467,17 +480,18 @@ unsafe extern "C" fn base_src_create( ) -> gst_ffi::GstFlowReturn where T::ImplType: BaseSrcImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); // FIXME: Wrong signature in -sys bindings // https://github.com/sdroege/gstreamer-sys/issues/3 let buffer_ptr = buffer_ptr as *mut *mut gst_ffi::GstBuffer; - panic_to_error!(&wrap, &element.panicked, gst::FlowReturn::Error, { + panic_to_error!(&wrap, &element.panicked(), gst::FlowReturn::Error, { match imp.create(&wrap, offset, length) { Ok(buffer) => { *buffer_ptr = buffer.into_ptr(); @@ -494,14 +508,15 @@ unsafe extern "C" fn base_src_do_seek( ) -> glib_ffi::gboolean where T::ImplType: BaseSrcImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, false, { + panic_to_error!(&wrap, &element.panicked(), false, { imp.do_seek(&wrap, &mut from_glib_borrow(segment)) }).to_glib() } @@ -512,15 +527,16 @@ unsafe extern "C" fn base_src_query( ) -> glib_ffi::gboolean where T::ImplType: BaseSrcImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); let query = gst::QueryRef::from_mut_ptr(query_ptr); - panic_to_error!(&wrap, &element.panicked, false, { + panic_to_error!(&wrap, &element.panicked(), false, { BaseSrcImpl::query(imp, &wrap, query) }).to_glib() } @@ -531,14 +547,15 @@ unsafe extern "C" fn base_src_event( ) -> glib_ffi::gboolean where T::ImplType: BaseSrcImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, false, { + panic_to_error!(&wrap, &element.panicked(), false, { imp.event(&wrap, &from_glib_none(event_ptr)) }).to_glib() } @@ -549,19 +566,20 @@ unsafe extern "C" fn base_src_get_caps( ) -> *mut gst_ffi::GstCaps where T::ImplType: BaseSrcImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); let filter = if filter.is_null() { None } else { Some(gst::CapsRef::from_ptr(filter)) }; - panic_to_error!(&wrap, &element.panicked, None, { + panic_to_error!(&wrap, &element.panicked(), None, { imp.get_caps(&wrap, filter) }).map(|caps| caps.into_ptr()) .unwrap_or(ptr::null_mut()) @@ -572,14 +590,15 @@ unsafe extern "C" fn base_src_negotiate( ) -> glib_ffi::gboolean where T::ImplType: BaseSrcImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, false, { imp.negotiate(&wrap) }).to_glib() + panic_to_error!(&wrap, &element.panicked(), false, { imp.negotiate(&wrap) }).to_glib() } unsafe extern "C" fn base_src_set_caps( @@ -588,15 +607,16 @@ unsafe extern "C" fn base_src_set_caps( ) -> glib_ffi::gboolean where T::ImplType: BaseSrcImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); let caps = gst::CapsRef::from_ptr(caps); - panic_to_error!(&wrap, &element.panicked, false, { + panic_to_error!(&wrap, &element.panicked(), false, { imp.set_caps(&wrap, caps) }).to_glib() } @@ -607,15 +627,16 @@ unsafe extern "C" fn base_src_fixate( ) -> *mut gst_ffi::GstCaps where T::ImplType: BaseSrcImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); let caps = from_glib_full(caps); - panic_to_error!(&wrap, &element.panicked, gst::Caps::new_empty(), { + panic_to_error!(&wrap, &element.panicked(), gst::Caps::new_empty(), { imp.fixate(&wrap, caps) }).into_ptr() } @@ -625,14 +646,15 @@ unsafe extern "C" fn base_src_unlock( ) -> glib_ffi::gboolean where T::ImplType: BaseSrcImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, false, { imp.unlock(&wrap) }).to_glib() + panic_to_error!(&wrap, &element.panicked(), false, { imp.unlock(&wrap) }).to_glib() } unsafe extern "C" fn base_src_unlock_stop( @@ -640,12 +662,13 @@ unsafe extern "C" fn base_src_unlock_stop( ) -> glib_ffi::gboolean where T::ImplType: BaseSrcImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, false, { imp.unlock_stop(&wrap) }).to_glib() + panic_to_error!(&wrap, &element.panicked(), false, { imp.unlock_stop(&wrap) }).to_glib() } diff --git a/gst-plugin/src/base_transform.rs b/gst-plugin/src/base_transform.rs index 4cb9c3a2..66afaf85 100644 --- a/gst-plugin/src/base_transform.rs +++ b/gst-plugin/src/base_transform.rs @@ -26,6 +26,8 @@ use object::*; pub trait BaseTransformImpl: AnyImpl + ObjectImpl + ElementImpl + Send + Sync + 'static +where + T::InstanceStructType: PanicPoison { fn start(&self, _element: &T) -> bool { true @@ -108,10 +110,12 @@ pub trait BaseTransformImpl: } } -any_impl!(BaseTransformBase, BaseTransformImpl); +any_impl!(BaseTransformBase, BaseTransformImpl, PanicPoison); pub unsafe trait BaseTransformBase: IsA + IsA + ObjectType +where + Self::InstanceStructType: PanicPoison { fn parent_transform_caps( &self, @@ -260,6 +264,7 @@ pub enum BaseTransformMode { pub unsafe trait BaseTransformClassExt where T::ImplType: BaseTransformImpl, + T::InstanceStructType: PanicPoison { fn configure( &mut self, @@ -307,9 +312,10 @@ where } glib_wrapper! { - pub struct BaseTransform(Object>): [gst_base::BaseTransform => gst_base_ffi::GstBaseTransform, - gst::Element => gst_ffi::GstElement, - gst::Object => gst_ffi::GstObject]; + pub struct BaseTransform(Object>): + [gst_base::BaseTransform => gst_base_ffi::GstBaseTransform, + gst::Element => gst_ffi::GstElement, + gst::Object => gst_ffi::GstObject]; match fn { get_type => || get_type::(), @@ -318,6 +324,8 @@ glib_wrapper! { unsafe impl + IsA + ObjectType> BaseTransformBase for T +where + T::InstanceStructType: PanicPoison { } pub type BaseTransformClass = ClassStruct; @@ -334,7 +342,10 @@ macro_rules! box_base_transform_impl( ($name:ident) => { box_element_impl!($name); - impl BaseTransformImpl for Box<$name> { + impl BaseTransformImpl for Box<$name> + where + T::InstanceStructType: PanicPoison + { fn start(&self, element: &T) -> bool { let imp: &$name = self.as_ref(); imp.start(element) @@ -414,6 +425,7 @@ impl ObjectType for BaseTransform { type GlibType = gst_base_ffi::GstBaseTransform; type GlibClassType = gst_base_ffi::GstBaseTransformClass; type ImplType = Box>; + type InstanceStructType = ElementInstanceStruct; fn glib_type() -> glib::Type { unsafe { from_glib(gst_base_ffi::gst_base_transform_get_type()) } @@ -432,14 +444,15 @@ unsafe extern "C" fn base_transform_start( ) -> glib_ffi::gboolean where T::ImplType: BaseTransformImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, false, { imp.start(&wrap) }).to_glib() + panic_to_error!(&wrap, &element.panicked(), false, { imp.start(&wrap) }).to_glib() } unsafe extern "C" fn base_transform_stop( @@ -447,14 +460,15 @@ unsafe extern "C" fn base_transform_stop( ) -> glib_ffi::gboolean where T::ImplType: BaseTransformImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, false, { imp.stop(&wrap) }).to_glib() + panic_to_error!(&wrap, &element.panicked(), false, { imp.stop(&wrap) }).to_glib() } unsafe extern "C" fn base_transform_transform_caps( @@ -465,14 +479,15 @@ unsafe extern "C" fn base_transform_transform_caps( ) -> *mut gst_ffi::GstCaps where T::ImplType: BaseTransformImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, gst::Caps::new_empty(), { + panic_to_error!(&wrap, &element.panicked(), gst::Caps::new_empty(), { let filter = if filter.is_null() { None } else { @@ -496,14 +511,15 @@ unsafe extern "C" fn base_transform_fixate_caps( ) -> *mut gst_ffi::GstCaps where T::ImplType: BaseTransformImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, gst::Caps::new_empty(), { + panic_to_error!(&wrap, &element.panicked(), gst::Caps::new_empty(), { imp.fixate_caps( &wrap, from_glib(direction), @@ -520,14 +536,15 @@ unsafe extern "C" fn base_transform_set_caps( ) -> glib_ffi::gboolean where T::ImplType: BaseTransformImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, false, { + panic_to_error!(&wrap, &element.panicked(), false, { imp.set_caps(&wrap, &from_glib_borrow(incaps), &from_glib_borrow(outcaps)) }).to_glib() } @@ -539,14 +556,15 @@ unsafe extern "C" fn base_transform_accept_caps( ) -> glib_ffi::gboolean where T::ImplType: BaseTransformImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, false, { + panic_to_error!(&wrap, &element.panicked(), false, { imp.accept_caps(&wrap, from_glib(direction), &from_glib_borrow(caps)) }).to_glib() } @@ -558,14 +576,15 @@ unsafe extern "C" fn base_transform_query( ) -> glib_ffi::gboolean where T::ImplType: BaseTransformImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, false, { + panic_to_error!(&wrap, &element.panicked(), false, { BaseTransformImpl::query( imp, &wrap, @@ -585,14 +604,15 @@ unsafe extern "C" fn base_transform_transform_size( ) -> glib_ffi::gboolean where T::ImplType: BaseTransformImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, false, { + panic_to_error!(&wrap, &element.panicked(), false, { match imp.transform_size( &wrap, from_glib(direction), @@ -616,14 +636,15 @@ unsafe extern "C" fn base_transform_get_unit_size( ) -> glib_ffi::gboolean where T::ImplType: BaseTransformImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, false, { + panic_to_error!(&wrap, &element.panicked(), false, { match imp.get_unit_size(&wrap, &from_glib_borrow(caps)) { Some(s) => { *size = s; @@ -640,14 +661,15 @@ unsafe extern "C" fn base_transform_sink_event( ) -> glib_ffi::gboolean where T::ImplType: BaseTransformImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, false, { + panic_to_error!(&wrap, &element.panicked(), false, { imp.sink_event(&wrap, from_glib_full(event)) }).to_glib() } @@ -658,14 +680,15 @@ unsafe extern "C" fn base_transform_src_event( ) -> glib_ffi::gboolean where T::ImplType: BaseTransformImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, false, { + panic_to_error!(&wrap, &element.panicked(), false, { imp.src_event(&wrap, from_glib_full(event)) }).to_glib() } @@ -677,14 +700,15 @@ unsafe extern "C" fn base_transform_transform( ) -> gst_ffi::GstFlowReturn where T::ImplType: BaseTransformImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, gst::FlowReturn::Error, { + panic_to_error!(&wrap, &element.panicked(), gst::FlowReturn::Error, { imp.transform( &wrap, &from_glib_borrow(inbuf), @@ -699,17 +723,18 @@ unsafe extern "C" fn base_transform_transform_ip( ) -> gst_ffi::GstFlowReturn where T::ImplType: BaseTransformImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); // FIXME: Wrong signature in FFI let buf = buf as *mut gst_ffi::GstBuffer; - panic_to_error!(&wrap, &element.panicked, gst::FlowReturn::Error, { + panic_to_error!(&wrap, &element.panicked(), gst::FlowReturn::Error, { if from_glib(gst_base_ffi::gst_base_transform_is_passthrough(ptr)) { imp.transform_ip_passthrough(&wrap, gst::BufferRef::from_ptr(buf)) } else { diff --git a/gst-plugin/src/bin.rs b/gst-plugin/src/bin.rs index 20993527..68c92c9f 100644 --- a/gst-plugin/src/bin.rs +++ b/gst-plugin/src/bin.rs @@ -24,6 +24,8 @@ use object::*; pub trait BinImpl: AnyImpl + ObjectImpl + ElementImpl + Send + Sync + 'static +where + T::InstanceStructType: PanicPoison { fn add_element(&self, bin: &T, element: &gst::Element) -> bool { bin.parent_add_element(element) @@ -38,7 +40,7 @@ pub trait BinImpl: } } -any_impl!(BinBase, BinImpl); +any_impl!(BinBase, BinImpl, PanicPoison); pub unsafe trait BinBase: IsA + IsA + ObjectType { fn parent_add_element(&self, element: &gst::Element) -> bool { @@ -77,6 +79,8 @@ pub unsafe trait BinBase: IsA + IsA + ObjectType { pub unsafe trait BinClassExt where T::ImplType: BinImpl, + T::InstanceStructType: PanicPoison + { fn override_vfuncs(&mut self, _: &ClassInitToken) { unsafe { @@ -89,10 +93,11 @@ where } glib_wrapper! { - pub struct Bin(Object>): [gst::Bin => gst_ffi::GstBin, - gst::Element => gst_ffi::GstElement, - gst::Object => gst_ffi::GstObject, - gst::ChildProxy => gst_ffi::GstChildProxy]; + pub struct Bin(Object>): + [gst::Bin => gst_ffi::GstBin, + gst::Element => gst_ffi::GstElement, + gst::Object => gst_ffi::GstObject, + gst::ChildProxy => gst_ffi::GstChildProxy]; match fn { get_type => || get_type::(), @@ -114,7 +119,10 @@ macro_rules! box_bin_impl( ($name:ident) => { box_element_impl!($name); - impl BinImpl for Box<$name> { + impl BinImpl for Box<$name> + where + T::InstanceStructType: PanicPoison + { fn add_element(&self, bin: &T, element: &gst::Element) -> bool { let imp: &$name = self.as_ref(); imp.add_element(bin, element) @@ -139,6 +147,7 @@ impl ObjectType for Bin { type GlibType = gst_ffi::GstBin; type GlibClassType = gst_ffi::GstBinClass; type ImplType = Box>; + type InstanceStructType = ElementInstanceStruct; fn glib_type() -> glib::Type { unsafe { from_glib(gst_ffi::gst_bin_get_type()) } @@ -158,14 +167,15 @@ unsafe extern "C" fn bin_add_element( ) -> glib_ffi::gboolean where T::ImplType: BinImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let bin = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = bin.imp.as_ref(); + let bin = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = bin.get_impl(); - panic_to_error!(&wrap, &bin.panicked, false, { + panic_to_error!(&wrap, &bin.panicked(), false, { imp.add_element(&wrap, &from_glib_none(element)) }).to_glib() } @@ -176,14 +186,15 @@ unsafe extern "C" fn bin_remove_element( ) -> glib_ffi::gboolean where T::ImplType: BinImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let bin = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = bin.imp.as_ref(); + let bin = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = bin.get_impl(); - panic_to_error!(&wrap, &bin.panicked, false, { + panic_to_error!(&wrap, &bin.panicked(), false, { imp.remove_element(&wrap, &from_glib_none(element)) }).to_glib() } @@ -193,14 +204,15 @@ unsafe extern "C" fn bin_handle_message( message: *mut gst_ffi::GstMessage, ) where T::ImplType: BinImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let bin = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = bin.imp.as_ref(); + let bin = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = bin.get_impl(); - panic_to_error!(&wrap, &bin.panicked, (), { + panic_to_error!(&wrap, &bin.panicked(), (), { imp.handle_message(&wrap, from_glib_full(message)) }); } diff --git a/gst-plugin/src/element.rs b/gst-plugin/src/element.rs index 99dc26ef..aeeb274f 100644 --- a/gst-plugin/src/element.rs +++ b/gst-plugin/src/element.rs @@ -24,7 +24,10 @@ use gst::prelude::*; use anyimpl::*; use object::*; -pub trait ElementImpl: ObjectImpl + AnyImpl + Send + Sync + 'static { +pub trait ElementImpl: ObjectImpl + AnyImpl + Send + Sync + 'static +where + T::InstanceStructType: PanicPoison +{ fn change_state(&self, element: &T, transition: gst::StateChange) -> gst::StateChangeReturn { element.parent_change_state(transition) } @@ -64,6 +67,8 @@ pub trait ElementImplExt { impl, T: ObjectType + glib::IsA + glib::IsA> ElementImplExt for S +where + T::InstanceStructType: PanicPoison { fn catch_panic_pad_function R, G: FnOnce() -> R>( parent: &Option, @@ -79,9 +84,12 @@ impl, T: ObjectType + glib::IsA + glib::IsA + ObjectType { +pub unsafe trait ElementBase: IsA + ObjectType +where + Self::InstanceStructType: PanicPoison +{ fn parent_change_state(&self, transition: gst::StateChange) -> gst::StateChangeReturn { unsafe { let klass = self.get_class(); @@ -126,8 +134,9 @@ pub unsafe trait ElementBase: IsA + ObjectType { } } - fn catch_panic T, G: FnOnce() -> T>(&self, fallback: G, f: F) -> T { - let panicked = unsafe { &(*self.get_instance()).panicked }; + fn catch_panic T, G: FnOnce() -> T>(&self, fallback: G, f: F) -> T + { + let panicked = unsafe { &(*self.get_instance()).panicked() }; panic_to_error!(self, panicked, fallback(), { f(self) }) } } @@ -135,6 +144,7 @@ pub unsafe trait ElementBase: IsA + ObjectType { pub unsafe trait ElementClassExt where T::ImplType: ElementImpl, + T::InstanceStructType: PanicPoison { fn add_pad_template(&mut self, pad_template: gst::PadTemplate) { unsafe { @@ -163,7 +173,8 @@ where } } - fn override_vfuncs(&mut self, _: &ClassInitToken) { + fn override_vfuncs(&mut self, _: &ClassInitToken) + { unsafe { let klass = &mut *(self as *const Self as *mut gst_ffi::GstElementClass); klass.change_state = Some(element_change_state::); @@ -177,15 +188,18 @@ where } glib_wrapper! { - pub struct Element(Object>): [gst::Element => gst_ffi::GstElement, - gst::Object => gst_ffi::GstObject]; + pub struct Element(Object>): + [gst::Element => gst_ffi::GstElement, + gst::Object => gst_ffi::GstObject]; match fn { get_type => || get_type::(), } } -unsafe impl + ObjectType> ElementBase for T {} +unsafe impl + ObjectType> ElementBase for T +where Self::InstanceStructType: PanicPoison{} + pub type ElementClass = ClassStruct; // FIXME: Boilerplate @@ -197,9 +211,12 @@ unsafe impl Sync for Element {} #[macro_export] macro_rules! box_element_impl( ($name:ident) => { - box_object_impl!($name); + box_object_impl!($name, PanicPoison); - impl ElementImpl for Box<$name> { + impl ElementImpl for Box<$name> + where + T::InstanceStructType: PanicPoison + { fn change_state( &self, element: &T, @@ -239,11 +256,13 @@ macro_rules! box_element_impl( box_element_impl!(ElementImpl); -impl ObjectType for Element { +impl ObjectType for Element +{ const NAME: &'static str = "RsElement"; type GlibType = gst_ffi::GstElement; type GlibClassType = gst_ffi::GstElementClass; type ImplType = Box>; + type InstanceStructType = ElementInstanceStruct; fn glib_type() -> glib::Type { unsafe { from_glib(gst_ffi::gst_element_get_type()) } @@ -262,12 +281,13 @@ unsafe extern "C" fn element_change_state( ) -> gst_ffi::GstStateChangeReturn where T::ImplType: ElementImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); // *Never* fail downwards state changes, this causes bugs in GStreamer // and leads to crashes and deadlocks. @@ -279,7 +299,7 @@ where _ => gst::StateChangeReturn::Failure, }; - panic_to_error!(&wrap, &element.panicked, fallback, { + panic_to_error!(&wrap, &element.panicked(), fallback, { imp.change_state(&wrap, transition) }).to_glib() } @@ -292,12 +312,13 @@ unsafe extern "C" fn element_request_new_pad( ) -> *mut gst_ffi::GstPad where T::ImplType: ElementImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); let caps = if caps.is_null() { None } else { @@ -306,7 +327,7 @@ where // XXX: This is effectively unsafe but the best we can do // See https://bugzilla.gnome.org/show_bug.cgi?id=791193 - let pad = panic_to_error!(&wrap, &element.panicked, None, { + let pad = panic_to_error!(&wrap, &element.panicked(), None, { imp.request_new_pad(&wrap, &from_glib_borrow(templ), from_glib_none(name), caps) }); @@ -326,16 +347,17 @@ where unsafe extern "C" fn element_release_pad( ptr: *mut gst_ffi::GstElement, pad: *mut gst_ffi::GstPad, -) where +)where T::ImplType: ElementImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, (), { + panic_to_error!(&wrap, &element.panicked(), (), { imp.release_pad(&wrap, &from_glib_borrow(pad)) }) } @@ -346,14 +368,15 @@ unsafe extern "C" fn element_send_event( ) -> glib_ffi::gboolean where T::ImplType: ElementImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, false, { + panic_to_error!(&wrap, &element.panicked(), false, { imp.send_event(&wrap, from_glib_full(event)) }).to_glib() } @@ -364,30 +387,32 @@ unsafe extern "C" fn element_query( ) -> glib_ffi::gboolean where T::ImplType: ElementImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); let query = gst::QueryRef::from_mut_ptr(query); - panic_to_error!(&wrap, &element.panicked, false, { imp.query(&wrap, query) }).to_glib() + panic_to_error!(&wrap, &element.panicked(), false, { imp.query(&wrap, query) }).to_glib() } unsafe extern "C" fn element_set_context( ptr: *mut gst_ffi::GstElement, context: *mut gst_ffi::GstContext, -) where +)where T::ImplType: ElementImpl, + T::InstanceStructType: PanicPoison { callback_guard!(); floating_reference_guard!(ptr); - let element = &*(ptr as *mut InstanceStruct); - let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct); - let imp = element.imp.as_ref(); + let element = &*(ptr as *mut T::InstanceStructType); + let wrap: T = from_glib_borrow(ptr as *mut T::InstanceStructType); + let imp = element.get_impl(); - panic_to_error!(&wrap, &element.panicked, (), { + panic_to_error!(&wrap, &element.panicked(), (), { imp.set_context(&wrap, &from_glib_borrow(context)) }) } diff --git a/gst-plugin/src/lib.rs b/gst-plugin/src/lib.rs index a297d6bf..86ef42b9 100644 --- a/gst-plugin/src/lib.rs +++ b/gst-plugin/src/lib.rs @@ -22,44 +22,17 @@ pub extern crate glib; pub extern crate gstreamer as gst; extern crate gstreamer_base as gst_base; -use std::ptr; - -macro_rules! callback_guard { - () => { - let _guard = ::glib::CallbackGuard::new(); - }; -} - -macro_rules! floating_reference_guard { - ($obj:ident) => { - let _guard = $crate::FloatingReferenceGuard::new($obj as *mut _); - }; -} - -pub struct FloatingReferenceGuard(ptr::NonNull); - -impl FloatingReferenceGuard { - pub unsafe fn new(obj: *mut gobject_ffi::GObject) -> Option { - assert!(!obj.is_null()); - if gobject_ffi::g_object_is_floating(obj) != glib_ffi::GFALSE { - gobject_ffi::g_object_ref_sink(obj); - Some(FloatingReferenceGuard(ptr::NonNull::new_unchecked(obj))) - } else { - None - } - } -} - -impl Drop for FloatingReferenceGuard { - fn drop(&mut self) { - unsafe { - gobject_ffi::g_object_force_floating(self.0.as_ptr()); - } - } -} +#[macro_use] +extern crate gobject_subclass; #[macro_use] -pub mod anyimpl; +pub use gobject_subclass::anyimpl; +pub use gobject_subclass::properties; + +#[macro_use] +pub use gobject_subclass::guard; + +pub mod object; #[macro_use] pub mod error; @@ -68,9 +41,6 @@ pub mod adapter; pub mod plugin; pub mod bytes; -pub mod properties; -#[macro_use] -pub mod object; #[macro_use] pub mod element; #[macro_use] diff --git a/gst-plugin/src/object.rs b/gst-plugin/src/object.rs index ab20e397..01703857 100644 --- a/gst-plugin/src/object.rs +++ b/gst-plugin/src/object.rs @@ -1,506 +1,47 @@ -// Copyright (C) 2017 Sebastian Dröge -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use std::any::TypeId; -use std::collections::BTreeMap; -use std::ffi::CString; -use std::mem; use std::ptr; -use std::sync::Mutex; use std::sync::atomic::AtomicBool; -use glib_ffi; -use gobject_ffi; +pub use gobject_subclass::object::*; -use glib; -use glib::translate::*; - -use properties::*; - -pub trait ObjectImpl: Send + Sync + 'static { - fn set_property(&self, _obj: &glib::Object, _id: u32, _value: &glib::Value) { - unimplemented!() - } - - fn get_property(&self, _obj: &glib::Object, _id: u32) -> Result { - unimplemented!() - } - - fn notify(&self, obj: &glib::Object, name: &str) { - unsafe { - gobject_ffi::g_object_notify(obj.to_glib_none().0, name.to_glib_none().0); - } - } -} - -#[macro_export] -macro_rules! box_object_impl( - ($name:ident) => { - impl ObjectImpl for Box<$name> { - fn set_property(&self, obj: &glib::Object, id: u32, value: &glib::Value) { - let imp: &$name = self.as_ref(); - imp.set_property(obj, id, value); - } - - fn get_property(&self, obj: &glib::Object, id: u32) -> Result { - let imp: &$name = self.as_ref(); - imp.get_property(obj, id) - } - } - }; -); - -pub trait ImplTypeStatic: Send + Sync + 'static { - fn get_name(&self) -> &str; - fn new(&self, &T) -> T::ImplType; - fn class_init(&self, &mut ClassStruct); - fn type_init(&self, _: &TypeInitToken, _type_: glib::Type) {} -} - -pub struct ClassInitToken(()); -pub struct TypeInitToken(()); - -pub trait ObjectType: FromGlibPtrBorrow<*mut InstanceStruct> + 'static -where - Self: Sized, -{ - const NAME: &'static str; - type GlibType; - type GlibClassType; - type ImplType: ObjectImpl; - - fn glib_type() -> glib::Type; - - fn class_init(token: &ClassInitToken, klass: &mut ClassStruct); - - fn set_property(_obj: &Self, _id: u32, _value: &glib::Value) { - unimplemented!() - } - - fn get_property(_obj: &Self, _id: u32) -> Result { - unimplemented!() - } - - unsafe fn get_instance(&self) -> *mut InstanceStruct; - - fn get_impl(&self) -> &Self::ImplType { - unsafe { (*self.get_instance()).get_impl() } - } - - unsafe fn get_class(&self) -> *const ClassStruct { - (*self.get_instance()).get_class() - } -} - -#[macro_export] -macro_rules! object_type_fns( - () => { - unsafe fn get_instance(&self) -> *mut InstanceStruct { - self.to_glib_none().0 - } - } -); #[repr(C)] -pub struct InstanceStruct { - pub parent: T::GlibType, - pub imp: ptr::NonNull, - pub panicked: AtomicBool, +pub struct ElementInstanceStruct +{ + _parent: T::GlibType, + _imp: ptr::NonNull, + + _panicked: AtomicBool, } -impl InstanceStruct { - pub fn get_impl(&self) -> &T::ImplType { - unsafe { self.imp.as_ref() } +pub trait PanicPoison{ + fn panicked(&self) -> &AtomicBool; +} + + +impl Instance for ElementInstanceStruct +{ + fn parent(&self) -> &T::GlibType{ + &self._parent } - pub unsafe fn get_class(&self) -> *const ClassStruct { + fn get_impl(&self) -> &T::ImplType { + unsafe { self._imp.as_ref() } + } + + unsafe fn set_impl(&mut self, imp:ptr::NonNull){ + self._imp = imp; + } + + unsafe fn get_class(&self) -> *const ClassStruct { *(self as *const _ as *const *const ClassStruct) } } -#[repr(C)] -pub struct ClassStruct { - pub parent: T::GlibClassType, - pub imp_static: ptr::NonNull>>, - pub parent_class: ptr::NonNull, - pub interfaces_static: *const Vec<(glib_ffi::GType, glib_ffi::gpointer)>, -} -impl ClassStruct { - pub fn get_parent_class(&self) -> *const T::GlibClassType { - self.parent_class.as_ptr() - } -} - -impl ClassStruct { - pub fn get_interface_static(&self, type_: glib_ffi::GType) -> glib_ffi::gpointer { - unsafe { - if self.interfaces_static.is_null() { - return ptr::null_mut(); - } - - for &(t, p) in &(*self.interfaces_static) { - if t == type_ { - return p; - } - } - - ptr::null_mut() - } - } -} - -pub unsafe trait ObjectClass { - fn install_properties(&mut self, properties: &[Property]) { - if properties.is_empty() { - return; - } - - let mut pspecs = Vec::with_capacity(properties.len()); - - pspecs.push(ptr::null_mut()); - - for property in properties { - pspecs.push(property.into()); - } - - unsafe { - gobject_ffi::g_object_class_install_properties( - self as *mut _ as *mut gobject_ffi::GObjectClass, - pspecs.len() as u32, - pspecs.as_mut_ptr(), - ); - } +impl PanicPoison for ElementInstanceStruct +{ + fn panicked(&self) -> &AtomicBool{ + &self._panicked } - fn add_signal(&mut self, name: &str, arg_types: &[glib::Type], ret_type: glib::Type) { - let arg_types = arg_types.iter().map(|t| t.to_glib()).collect::>(); - unsafe { - gobject_ffi::g_signal_newv( - name.to_glib_none().0, - *(self as *mut _ as *mut glib_ffi::GType), - gobject_ffi::G_SIGNAL_RUN_LAST, - ptr::null_mut(), - None, - ptr::null_mut(), - None, - ret_type.to_glib(), - arg_types.len() as u32, - arg_types.as_ptr() as *mut _, - ); - } - } - - fn add_signal_with_accumulator( - &mut self, - name: &str, - arg_types: &[glib::Type], - ret_type: glib::Type, - accumulator: F, - ) where - F: Fn(&mut glib::Value, &glib::Value) -> bool + Send + Sync + 'static, - { - let arg_types = arg_types.iter().map(|t| t.to_glib()).collect::>(); - - let accumulator: Box< - Box bool + Send + Sync + 'static>, - > = Box::new(Box::new(accumulator)); - - unsafe extern "C" fn accumulator_trampoline( - _ihint: *mut gobject_ffi::GSignalInvocationHint, - return_accu: *mut gobject_ffi::GValue, - handler_return: *const gobject_ffi::GValue, - data: glib_ffi::gpointer, - ) -> glib_ffi::gboolean { - callback_guard!(); - let accumulator: &&(Fn(&mut glib::Value, &glib::Value) -> bool - + Send - + Sync - + 'static) = mem::transmute(data); - accumulator( - &mut *(return_accu as *mut glib::Value), - &*(handler_return as *const glib::Value), - ).to_glib() - } - - unsafe { - gobject_ffi::g_signal_newv( - name.to_glib_none().0, - *(self as *mut _ as *mut glib_ffi::GType), - gobject_ffi::G_SIGNAL_RUN_LAST, - ptr::null_mut(), - Some(accumulator_trampoline), - Box::into_raw(accumulator) as glib_ffi::gpointer, - None, - ret_type.to_glib(), - arg_types.len() as u32, - arg_types.as_ptr() as *mut _, - ); - } - } - - fn add_action_signal( - &mut self, - name: &str, - arg_types: &[glib::Type], - ret_type: glib::Type, - handler: F, - ) where - F: Fn(&[glib::Value]) -> Option + Send + Sync + 'static, - { - let arg_types = arg_types.iter().map(|t| t.to_glib()).collect::>(); - let handler = glib::Closure::new(handler); - unsafe { - gobject_ffi::g_signal_newv( - name.to_glib_none().0, - *(self as *mut _ as *mut glib_ffi::GType), - gobject_ffi::G_SIGNAL_RUN_LAST | gobject_ffi::G_SIGNAL_ACTION, - handler.to_glib_none().0, - None, - ptr::null_mut(), - None, - ret_type.to_glib(), - arg_types.len() as u32, - arg_types.as_ptr() as *mut _, - ); - } - } -} - -unsafe impl ObjectClass for ClassStruct {} - -unsafe extern "C" fn class_init( - klass: glib_ffi::gpointer, - _klass_data: glib_ffi::gpointer, -) { - callback_guard!(); - { - let gobject_klass = &mut *(klass as *mut gobject_ffi::GObjectClass); - - gobject_klass.finalize = Some(finalize::); - gobject_klass.set_property = Some(set_property::); - gobject_klass.get_property = Some(get_property::); - } - - { - let klass = &mut *(klass as *mut ClassStruct); - let parent_class = gobject_ffi::g_type_class_peek_parent( - klass as *mut _ as glib_ffi::gpointer, - ) as *mut T::GlibClassType; - assert!(!parent_class.is_null()); - klass.parent_class = ptr::NonNull::new_unchecked(parent_class); - T::class_init(&ClassInitToken(()), klass); - } -} - -unsafe extern "C" fn finalize(obj: *mut gobject_ffi::GObject) { - callback_guard!(); - let instance = &mut *(obj as *mut InstanceStruct); - - drop(Box::from_raw(instance.imp.as_ptr())); - instance.imp = ptr::NonNull::dangling(); - - let klass = *(obj as *const glib_ffi::gpointer); - let parent_klass = gobject_ffi::g_type_class_peek_parent(klass); - let parent_klass = - &*(gobject_ffi::g_type_class_peek_parent(parent_klass) as *const gobject_ffi::GObjectClass); - parent_klass.finalize.map(|f| f(obj)); -} - -unsafe extern "C" fn get_property( - obj: *mut gobject_ffi::GObject, - id: u32, - value: *mut gobject_ffi::GValue, - _pspec: *mut gobject_ffi::GParamSpec, -) { - callback_guard!(); - floating_reference_guard!(obj); - match T::get_property(&from_glib_borrow(obj as *mut InstanceStruct), id - 1) { - Ok(v) => { - gobject_ffi::g_value_unset(value); - ptr::write(value, ptr::read(v.to_glib_none().0)); - mem::forget(v); - } - Err(()) => eprintln!("Failed to get property"), - } -} - -unsafe extern "C" fn set_property( - obj: *mut gobject_ffi::GObject, - id: u32, - value: *mut gobject_ffi::GValue, - _pspec: *mut gobject_ffi::GParamSpec, -) { - callback_guard!(); - floating_reference_guard!(obj); - T::set_property( - &from_glib_borrow(obj as *mut InstanceStruct), - id - 1, - &*(value as *mut glib::Value), - ); -} - -static mut TYPES: *mut Mutex> = 0 as *mut _; - -pub unsafe fn get_type() -> glib_ffi::GType { - use std::sync::{Once, ONCE_INIT}; - - static ONCE: Once = ONCE_INIT; - - ONCE.call_once(|| { - TYPES = Box::into_raw(Box::new(Mutex::new(BTreeMap::new()))); - }); - - let mut types = (*TYPES).lock().unwrap(); - types - .entry(TypeId::of::()) - .or_insert_with(|| { - let type_info = gobject_ffi::GTypeInfo { - class_size: mem::size_of::>() as u16, - base_init: None, - base_finalize: None, - class_init: Some(class_init::), - class_finalize: None, - class_data: ptr::null_mut(), - instance_size: mem::size_of::>() as u16, - n_preallocs: 0, - instance_init: None, - value_table: ptr::null(), - }; - - let type_name = { - let mut idx = 0; - - loop { - let type_name = CString::new(format!("{}-{}", T::NAME, idx)).unwrap(); - if gobject_ffi::g_type_from_name(type_name.as_ptr()) - == gobject_ffi::G_TYPE_INVALID - { - break type_name; - } - idx += 1; - } - }; - - from_glib(gobject_ffi::g_type_register_static( - T::glib_type().to_glib(), - type_name.as_ptr(), - &type_info, - gobject_ffi::G_TYPE_FLAG_ABSTRACT, - )) - }) - .to_glib() -} - -unsafe extern "C" fn sub_class_init( - klass: glib_ffi::gpointer, - klass_data: glib_ffi::gpointer, -) { - callback_guard!(); - { - let gobject_klass = &mut *(klass as *mut gobject_ffi::GObjectClass); - - gobject_klass.set_property = Some(sub_set_property::); - gobject_klass.get_property = Some(sub_get_property::); - } - { - assert!(!klass_data.is_null()); - let klass = &mut *(klass as *mut ClassStruct); - let imp_static = klass_data as *mut Box>; - klass.imp_static = ptr::NonNull::new_unchecked(imp_static); - klass.interfaces_static = Box::into_raw(Box::new(Vec::new())); - - (*imp_static).class_init(klass); - } -} - -unsafe extern "C" fn sub_get_property( - obj: *mut gobject_ffi::GObject, - id: u32, - value: *mut gobject_ffi::GValue, - _pspec: *mut gobject_ffi::GParamSpec, -) { - callback_guard!(); - floating_reference_guard!(obj); - let instance = &*(obj as *mut InstanceStruct); - let imp = instance.get_impl(); - - match imp.get_property(&from_glib_borrow(obj), id - 1) { - Ok(v) => { - gobject_ffi::g_value_unset(value); - ptr::write(value, ptr::read(v.to_glib_none().0)); - mem::forget(v); - } - Err(()) => eprintln!("Failed to get property"), - } -} - -unsafe extern "C" fn sub_set_property( - obj: *mut gobject_ffi::GObject, - id: u32, - value: *mut gobject_ffi::GValue, - _pspec: *mut gobject_ffi::GParamSpec, -) { - callback_guard!(); - floating_reference_guard!(obj); - let instance = &*(obj as *mut InstanceStruct); - let imp = instance.get_impl(); - imp.set_property( - &from_glib_borrow(obj), - id - 1, - &*(value as *mut glib::Value), - ); -} - -unsafe extern "C" fn sub_init( - obj: *mut gobject_ffi::GTypeInstance, - _klass: glib_ffi::gpointer, -) { - callback_guard!(); - floating_reference_guard!(obj); - let instance = &mut *(obj as *mut InstanceStruct); - let klass = &**(obj as *const *const ClassStruct); - let rs_instance: T = from_glib_borrow(obj as *mut InstanceStruct); - - let imp = klass.imp_static.as_ref().new(&rs_instance); - instance.imp = ptr::NonNull::new_unchecked(Box::into_raw(Box::new(imp))); -} - -pub fn register_type>(imp: I) -> glib::Type { - unsafe { - let parent_type = get_type::(); - let type_name = format!("{}-{}", T::NAME, imp.get_name()); - - let imp: Box> = Box::new(imp); - let imp_ptr = Box::into_raw(Box::new(imp)); - - let type_info = gobject_ffi::GTypeInfo { - class_size: mem::size_of::>() as u16, - base_init: None, - base_finalize: None, - class_init: Some(sub_class_init::), - class_finalize: None, - class_data: imp_ptr as glib_ffi::gpointer, - instance_size: mem::size_of::>() as u16, - n_preallocs: 0, - instance_init: Some(sub_init::), - value_table: ptr::null(), - }; - - let type_ = from_glib(gobject_ffi::g_type_register_static( - parent_type, - type_name.to_glib_none().0, - &type_info, - 0, - )); - - (*imp_ptr).type_init(&TypeInitToken(()), type_); - - type_ - } } diff --git a/gst-plugin/src/pipeline.rs b/gst-plugin/src/pipeline.rs index c6473a3c..e1ebd46f 100644 --- a/gst-plugin/src/pipeline.rs +++ b/gst-plugin/src/pipeline.rs @@ -25,10 +25,12 @@ use object::*; pub trait PipelineImpl: AnyImpl + ObjectImpl + ElementImpl + BinImpl + Send + Sync + 'static +where + T::InstanceStructType: PanicPoison { } -any_impl!(PipelineBase, PipelineImpl); +any_impl!(PipelineBase, PipelineImpl, PanicPoison); pub unsafe trait PipelineBase: IsA + IsA + IsA + ObjectType @@ -38,16 +40,18 @@ pub unsafe trait PipelineBase: pub unsafe trait PipelineClassExt where T::ImplType: PipelineImpl, + T::InstanceStructType: PanicPoison { fn override_vfuncs(&mut self, _: &ClassInitToken) {} } glib_wrapper! { - pub struct Pipeline(Object>): [gst::Pipeline => gst_ffi::GstPipeline, - gst::Bin => gst_ffi::GstBin, - gst::Element => gst_ffi::GstElement, - gst::Object => gst_ffi::GstObject, - gst::ChildProxy => gst_ffi::GstChildProxy]; + pub struct Pipeline(Object>): + [gst::Pipeline => gst_ffi::GstPipeline, + gst::Bin => gst_ffi::GstBin, + gst::Element => gst_ffi::GstElement, + gst::Object => gst_ffi::GstObject, + gst::ChildProxy => gst_ffi::GstChildProxy]; match fn { get_type => || get_type::(), @@ -73,7 +77,10 @@ macro_rules! box_pipeline_impl( ($name:ident) => { box_bin_impl!($name); - impl PipelineImpl for Box<$name> { + impl PipelineImpl for Box<$name> + where + T::InstanceStructType: PanicPoison + { } }; ); @@ -84,6 +91,7 @@ impl ObjectType for Pipeline { type GlibType = gst_ffi::GstPipeline; type GlibClassType = gst_ffi::GstPipelineClass; type ImplType = Box>; + type InstanceStructType = ElementInstanceStruct; fn glib_type() -> glib::Type { unsafe { from_glib(gst_ffi::gst_pipeline_get_type()) } diff --git a/gst-plugin/src/uri_handler.rs b/gst-plugin/src/uri_handler.rs index 281af4ff..4702ea11 100644 --- a/gst-plugin/src/uri_handler.rs +++ b/gst-plugin/src/uri_handler.rs @@ -69,7 +69,7 @@ unsafe extern "C" fn uri_handler_get_uri( let interface_static = klass.get_interface_static(gst_ffi::gst_uri_handler_get_type()) as *const URIHandlerStatic; - let instance = &*(uri_handler as *const InstanceStruct); + let instance = &*(uri_handler as *const T::InstanceStructType); let imp = instance.get_impl(); let imp = (*(*interface_static).imp_static).get_impl(imp); @@ -88,7 +88,7 @@ unsafe extern "C" fn uri_handler_set_uri( let interface_static = klass.get_interface_static(gst_ffi::gst_uri_handler_get_type()) as *const URIHandlerStatic; - let instance = &*(uri_handler as *const InstanceStruct); + let instance = &*(uri_handler as *const T::InstanceStructType); let imp = instance.get_impl(); let imp = (*(*interface_static).imp_static).get_impl(imp);