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
This commit is contained in:
Dirk Van Haerenborgh 2018-04-25 13:38:32 +02:00 committed by Sebastian Dröge
parent f2f18ebb27
commit 31a48c4baa
17 changed files with 1028 additions and 773 deletions

View file

@ -1,6 +1,7 @@
[workspace]
members = [
"gobject-subclass",
"gst-plugin",
"gst-plugin-simple",
"gst-plugin-file",

View file

@ -0,0 +1,18 @@
[package]
name = "gobject-subclass"
version = "0.1.0"
authors = ["Sebastian Dröge <sebastian@centricular.com>"]
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"

View file

@ -20,9 +20,17 @@ impl<T: Any> 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<T: $bound> $trait<T> {
($bound:ident, $trait:ident $(, $constraint:ident)*) => {
impl<T: $bound> $trait<T>
$(
where T::InstanceStructType: $constraint
)*
{
#[inline]
pub fn downcast_ref<U: $trait<T>>(&self) -> Option<&U> {
if self.is::<U>() {

View file

@ -0,0 +1,49 @@
// Copyright (C) 2016-2017 Sebastian Dröge <sebastian@centricular.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<gobject_ffi::GObject>);
impl FloatingReferenceGuard {
pub unsafe fn new(obj: *mut gobject_ffi::GObject) -> Option<FloatingReferenceGuard> {
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());
}
}
}

View file

@ -0,0 +1,29 @@
// Copyright (C) 2016-2017 Sebastian Dröge <sebastian@centricular.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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;

View file

@ -0,0 +1,524 @@
// Copyright (C) 2017 Sebastian Dröge <sebastian@centricular.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<T: ObjectType>: 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<glib::Value, ()> {
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<T: ObjectType> ObjectImpl<T> for Box<$name<T>>
$(
where T::InstanceStructType: $constraint
)*
{
fn set_property(&self, obj: &glib::Object, id: u32, value: &glib::Value) {
let imp: &$name<T> = self.as_ref();
imp.set_property(obj, id, value);
}
fn get_property(&self, obj: &glib::Object, id: u32) -> Result<glib::Value, ()> {
let imp: &$name<T> = self.as_ref();
imp.get_property(obj, id)
}
}
};
);
pub trait ImplTypeStatic<T: ObjectType>: Send + Sync + 'static {
fn get_name(&self) -> &str;
fn new(&self, &T) -> T::ImplType;
fn class_init(&self, &mut ClassStruct<T>);
fn type_init(&self, _: &TypeInitToken, _type_: glib::Type) {}
}
pub struct ClassInitToken(());
pub struct TypeInitToken(());
pub trait ObjectType: FromGlibPtrBorrow<*mut <Self as ObjectType>::InstanceStructType>
where Self: Sized + 'static,
Self::InstanceStructType: Instance<Self>
{
const NAME: &'static str;
type InstanceStructType: Instance<Self> + 'static;
type GlibType;
type GlibClassType;
type ImplType: ObjectImpl<Self>;
fn glib_type() -> glib::Type;
fn class_init(token: &ClassInitToken, klass: &mut ClassStruct<Self>);
fn set_property(_obj: &Self, _id: u32, _value: &glib::Value) {
unimplemented!()
}
fn get_property(_obj: &Self, _id: u32) -> Result<glib::Value, ()> {
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>{
(*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<T: ObjectType>
{
fn parent(&self) -> &T::GlibType;
fn get_impl(&self) -> &T::ImplType;
unsafe fn set_impl(&mut self, imp:ptr::NonNull<T::ImplType>);
unsafe fn get_class(&self) -> *const ClassStruct<T>;
}
#[repr(C)]
pub struct InstanceStruct<T: ObjectType>
{
_parent: T::GlibType,
_imp: ptr::NonNull<T::ImplType>,
}
#[repr(C)]
pub struct ClassStruct<T: ObjectType> {
pub parent: T::GlibClassType,
pub imp_static: ptr::NonNull<Box<ImplTypeStatic<T>>>,
pub parent_class: ptr::NonNull<T::GlibClassType>,
pub interfaces_static: *const Vec<(glib_ffi::GType, glib_ffi::gpointer)>,
}
impl<T: ObjectType> ClassStruct<T> {
pub fn get_parent_class(&self) -> *const T::GlibClassType {
self.parent_class.as_ptr()
}
}
impl<T: ObjectType> ClassStruct<T> {
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::<Vec<_>>();
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<F>(
&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::<Vec<_>>();
let accumulator: Box<
Box<Fn(&mut glib::Value, &glib::Value) -> 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<F>(
&mut self,
name: &str,
arg_types: &[glib::Type],
ret_type: glib::Type,
handler: F,
) where
F: Fn(&[glib::Value]) -> Option<glib::Value> + Send + Sync + 'static,
{
let arg_types = arg_types.iter().map(|t| t.to_glib()).collect::<Vec<_>>();
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<T: ObjectType> ObjectClass for ClassStruct<T> {}
unsafe extern "C" fn class_init<T: ObjectType>(
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::<T>);
gobject_klass.set_property = Some(set_property::<T>);
gobject_klass.get_property = Some(get_property::<T>);
}
{
let klass = &mut *(klass as *mut ClassStruct<T>);
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<T: ObjectType>(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<T: ObjectType>(
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<T: ObjectType>(
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<BTreeMap<TypeId, glib::Type>> = 0 as *mut _;
pub unsafe fn get_type<T: ObjectType>() -> 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::<T>())
.or_insert_with(|| {
let type_info = gobject_ffi::GTypeInfo {
class_size: mem::size_of::<ClassStruct<T>>() as u16,
base_init: None,
base_finalize: None,
class_init: Some(class_init::<T>),
class_finalize: None,
class_data: ptr::null_mut(),
instance_size: mem::size_of::<T::InstanceStructType>() 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<T: ObjectType>(
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::<T>);
gobject_klass.get_property = Some(sub_get_property::<T>);
}
{
assert!(!klass_data.is_null());
let klass = &mut *(klass as *mut ClassStruct<T>);
let imp_static = klass_data as *mut Box<ImplTypeStatic<T>>;
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<T: ObjectType>(
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<T: ObjectType>(
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<T: ObjectType>(
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<T>);
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<T: ObjectType, I: ImplTypeStatic<T>>(imp: I) -> glib::Type
{
unsafe {
let parent_type = get_type::<T>();
let type_name = format!("{}-{}", T::NAME, imp.get_name());
let imp: Box<ImplTypeStatic<T>> = Box::new(imp);
let imp_ptr = Box::into_raw(Box::new(imp));
let type_info = gobject_ffi::GTypeInfo {
class_size: mem::size_of::<ClassStruct<T>>() as u16,
base_init: None,
base_finalize: None,
class_init: Some(sub_class_init::<T>),
class_finalize: None,
class_data: imp_ptr as glib_ffi::gpointer,
instance_size: mem::size_of::<T::InstanceStructType>() as u16,
n_preallocs: 0,
instance_init: Some(sub_init::<T>),
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_
}
}

View file

@ -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" }

View file

@ -26,6 +26,8 @@ use object::*;
pub trait BaseSinkImpl<T: BaseSinkBase>:
AnyImpl + ObjectImpl<T> + ElementImpl<T> + Send + Sync + 'static
where
T::InstanceStructType: PanicPoison
{
fn start(&self, _element: &T) -> bool {
true
@ -92,7 +94,7 @@ pub trait BaseSinkImpl<T: BaseSinkBase>:
}
}
any_impl!(BaseSinkBase, BaseSinkImpl);
any_impl!(BaseSinkBase, BaseSinkImpl, PanicPoison);
pub unsafe trait BaseSinkBase:
IsA<gst::Element> + IsA<gst_base::BaseSink> + ObjectType
@ -163,6 +165,7 @@ pub unsafe trait BaseSinkBase:
pub unsafe trait BaseSinkClassExt<T: BaseSinkBase>
where
T::ImplType: BaseSinkImpl<T>,
T::InstanceStructType: PanicPoison
{
fn override_vfuncs(&mut self, _: &ClassInitToken) {
unsafe {
@ -185,9 +188,10 @@ where
}
glib_wrapper! {
pub struct BaseSink(Object<InstanceStruct<BaseSink>>): [gst_base::BaseSink => gst_base_ffi::GstBaseSink,
gst::Element => gst_ffi::GstElement,
gst::Object => gst_ffi::GstObject];
pub struct BaseSink(Object<ElementInstanceStruct<BaseSink>>):
[gst_base::BaseSink => gst_base_ffi::GstBaseSink,
gst::Element => gst_ffi::GstElement,
gst::Object => gst_ffi::GstObject];
match fn {
get_type => || get_type::<BaseSink>(),
@ -209,7 +213,10 @@ macro_rules! box_base_sink_impl(
($name:ident) => {
box_element_impl!($name);
impl<T: BaseSinkBase> BaseSinkImpl<T> for Box<$name<T>> {
impl<T: BaseSinkBase> BaseSinkImpl<T> for Box<$name<T>>
where
T::InstanceStructType: PanicPoison
{
fn start(&self, element: &T) -> bool {
let imp: &$name<T> = 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<BaseSinkImpl<Self>>;
type InstanceStructType = ElementInstanceStruct<Self>;
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<T: BaseSinkBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseSinkImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSinkBase>(
@ -318,14 +327,15 @@ unsafe extern "C" fn base_sink_stop<T: BaseSinkBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseSinkImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSinkBase>(
@ -334,15 +344,16 @@ unsafe extern "C" fn base_sink_render<T: BaseSinkBase>(
) -> gst_ffi::GstFlowReturn
where
T::ImplType: BaseSinkImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSinkBase>(
) -> gst_ffi::GstFlowReturn
where
T::ImplType: BaseSinkImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSinkBase>(
) -> gst_ffi::GstFlowReturn
where
T::ImplType: BaseSinkImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSinkBase>(
) -> gst_ffi::GstFlowReturn
where
T::ImplType: BaseSinkImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSinkBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseSinkImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSinkBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseSinkImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSinkBase>(
) -> *mut gst_ffi::GstCaps
where
T::ImplType: BaseSinkImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSinkBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseSinkImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSinkBase>(
) -> *mut gst_ffi::GstCaps
where
T::ImplType: BaseSinkImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSinkBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseSinkImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSinkBase>(
@ -523,12 +543,13 @@ unsafe extern "C" fn base_sink_unlock_stop<T: BaseSinkBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseSinkImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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()
}

View file

@ -26,6 +26,8 @@ use object::*;
pub trait BaseSrcImpl<T: BaseSrcBase>:
AnyImpl + ObjectImpl<T> + ElementImpl<T> + Send + Sync + 'static
where
T::InstanceStructType: PanicPoison
{
fn start(&self, _element: &T) -> bool {
true
@ -99,7 +101,7 @@ pub trait BaseSrcImpl<T: BaseSrcBase>:
}
}
any_impl!(BaseSrcBase, BaseSrcImpl);
any_impl!(BaseSrcBase, BaseSrcImpl, PanicPoison);
pub unsafe trait BaseSrcBase:
IsA<gst::Element> + IsA<gst_base::BaseSrc> + ObjectType
@ -212,6 +214,7 @@ pub unsafe trait BaseSrcBase:
pub unsafe trait BaseSrcClassExt<T: BaseSrcBase>
where
T::ImplType: BaseSrcImpl<T>,
T::InstanceStructType: PanicPoison
{
fn override_vfuncs(&mut self, _: &ClassInitToken) {
unsafe {
@ -236,9 +239,10 @@ where
}
glib_wrapper! {
pub struct BaseSrc(Object<InstanceStruct<BaseSrc>>): [gst_base::BaseSrc => gst_base_ffi::GstBaseSrc,
gst::Element => gst_ffi::GstElement,
gst::Object => gst_ffi::GstObject];
pub struct BaseSrc(Object<ElementInstanceStruct<BaseSrc>>):
[gst_base::BaseSrc => gst_base_ffi::GstBaseSrc,
gst::Element => gst_ffi::GstElement,
gst::Object => gst_ffi::GstObject];
match fn {
get_type => || get_type::<BaseSrc>(),
@ -260,7 +264,10 @@ macro_rules! box_base_src_impl(
($name:ident) => {
box_element_impl!($name);
impl<T: BaseSrcBase> BaseSrcImpl<T> for Box<$name<T>> {
impl<T: BaseSrcBase> BaseSrcImpl<T> for Box<$name<T>>
where
T::InstanceStructType: PanicPoison
{
fn start(&self, element: &T) -> bool {
let imp: &$name<T> = 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<BaseSrcImpl<Self>>;
type InstanceStructType = ElementInstanceStruct<Self>;
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<T: BaseSrcBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseSrcImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSrcBase>(
@ -389,14 +398,15 @@ unsafe extern "C" fn base_src_stop<T: BaseSrcBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseSrcImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSrcBase>(
@ -404,14 +414,15 @@ unsafe extern "C" fn base_src_is_seekable<T: BaseSrcBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseSrcImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSrcBase>(
@ -420,14 +431,15 @@ unsafe extern "C" fn base_src_get_size<T: BaseSrcBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseSrcImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSrcBase>(
) -> gst_ffi::GstFlowReturn
where
T::ImplType: BaseSrcImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSrcBase>(
) -> gst_ffi::GstFlowReturn
where
T::ImplType: BaseSrcImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSrcBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseSrcImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSrcBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseSrcImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSrcBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseSrcImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSrcBase>(
) -> *mut gst_ffi::GstCaps
where
T::ImplType: BaseSrcImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSrcBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseSrcImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSrcBase>(
@ -588,15 +607,16 @@ unsafe extern "C" fn base_src_set_caps<T: BaseSrcBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseSrcImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSrcBase>(
) -> *mut gst_ffi::GstCaps
where
T::ImplType: BaseSrcImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSrcBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseSrcImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseSrcBase>(
@ -640,12 +662,13 @@ unsafe extern "C" fn base_src_unlock_stop<T: BaseSrcBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseSrcImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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()
}

View file

@ -26,6 +26,8 @@ use object::*;
pub trait BaseTransformImpl<T: BaseTransformBase>:
AnyImpl + ObjectImpl<T> + ElementImpl<T> + Send + Sync + 'static
where
T::InstanceStructType: PanicPoison
{
fn start(&self, _element: &T) -> bool {
true
@ -108,10 +110,12 @@ pub trait BaseTransformImpl<T: BaseTransformBase>:
}
}
any_impl!(BaseTransformBase, BaseTransformImpl);
any_impl!(BaseTransformBase, BaseTransformImpl, PanicPoison);
pub unsafe trait BaseTransformBase:
IsA<gst::Element> + IsA<gst_base::BaseTransform> + ObjectType
where
Self::InstanceStructType: PanicPoison
{
fn parent_transform_caps(
&self,
@ -260,6 +264,7 @@ pub enum BaseTransformMode {
pub unsafe trait BaseTransformClassExt<T: BaseTransformBase>
where
T::ImplType: BaseTransformImpl<T>,
T::InstanceStructType: PanicPoison
{
fn configure(
&mut self,
@ -307,9 +312,10 @@ where
}
glib_wrapper! {
pub struct BaseTransform(Object<InstanceStruct<BaseTransform>>): [gst_base::BaseTransform => gst_base_ffi::GstBaseTransform,
gst::Element => gst_ffi::GstElement,
gst::Object => gst_ffi::GstObject];
pub struct BaseTransform(Object<ElementInstanceStruct<BaseTransform>>):
[gst_base::BaseTransform => gst_base_ffi::GstBaseTransform,
gst::Element => gst_ffi::GstElement,
gst::Object => gst_ffi::GstObject];
match fn {
get_type => || get_type::<BaseTransform>(),
@ -318,6 +324,8 @@ glib_wrapper! {
unsafe impl<T: IsA<gst::Element> + IsA<gst_base::BaseTransform> + ObjectType> BaseTransformBase
for T
where
T::InstanceStructType: PanicPoison
{
}
pub type BaseTransformClass = ClassStruct<BaseTransform>;
@ -334,7 +342,10 @@ macro_rules! box_base_transform_impl(
($name:ident) => {
box_element_impl!($name);
impl<T: BaseTransformBase> BaseTransformImpl<T> for Box<$name<T>> {
impl<T: BaseTransformBase> BaseTransformImpl<T> for Box<$name<T>>
where
T::InstanceStructType: PanicPoison
{
fn start(&self, element: &T) -> bool {
let imp: &$name<T> = 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<BaseTransformImpl<Self>>;
type InstanceStructType = ElementInstanceStruct<Self>;
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<T: BaseTransformBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseTransformImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseTransformBase>(
@ -447,14 +460,15 @@ unsafe extern "C" fn base_transform_stop<T: BaseTransformBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseTransformImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseTransformBase>(
@ -465,14 +479,15 @@ unsafe extern "C" fn base_transform_transform_caps<T: BaseTransformBase>(
) -> *mut gst_ffi::GstCaps
where
T::ImplType: BaseTransformImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseTransformBase>(
) -> *mut gst_ffi::GstCaps
where
T::ImplType: BaseTransformImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseTransformBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseTransformImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseTransformBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseTransformImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseTransformBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseTransformImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseTransformBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseTransformImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseTransformBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseTransformImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseTransformBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseTransformImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseTransformBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BaseTransformImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseTransformBase>(
) -> gst_ffi::GstFlowReturn
where
T::ImplType: BaseTransformImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BaseTransformBase>(
) -> gst_ffi::GstFlowReturn
where
T::ImplType: BaseTransformImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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 {

View file

@ -24,6 +24,8 @@ use object::*;
pub trait BinImpl<T: BinBase>:
AnyImpl + ObjectImpl<T> + ElementImpl<T> + 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<T: BinBase>:
}
}
any_impl!(BinBase, BinImpl);
any_impl!(BinBase, BinImpl, PanicPoison);
pub unsafe trait BinBase: IsA<gst::Element> + IsA<gst::Bin> + ObjectType {
fn parent_add_element(&self, element: &gst::Element) -> bool {
@ -77,6 +79,8 @@ pub unsafe trait BinBase: IsA<gst::Element> + IsA<gst::Bin> + ObjectType {
pub unsafe trait BinClassExt<T: BinBase>
where
T::ImplType: BinImpl<T>,
T::InstanceStructType: PanicPoison
{
fn override_vfuncs(&mut self, _: &ClassInitToken) {
unsafe {
@ -89,10 +93,11 @@ where
}
glib_wrapper! {
pub struct Bin(Object<InstanceStruct<Bin>>): [gst::Bin => gst_ffi::GstBin,
gst::Element => gst_ffi::GstElement,
gst::Object => gst_ffi::GstObject,
gst::ChildProxy => gst_ffi::GstChildProxy];
pub struct Bin(Object<ElementInstanceStruct<Bin>>):
[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::<Bin>(),
@ -114,7 +119,10 @@ macro_rules! box_bin_impl(
($name:ident) => {
box_element_impl!($name);
impl<T: BinBase> BinImpl<T> for Box<$name<T>> {
impl<T: BinBase> BinImpl<T> for Box<$name<T>>
where
T::InstanceStructType: PanicPoison
{
fn add_element(&self, bin: &T, element: &gst::Element) -> bool {
let imp: &$name<T> = 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<BinImpl<Self>>;
type InstanceStructType = ElementInstanceStruct<Self>;
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<T: BinBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BinImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let bin = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BinBase>(
) -> glib_ffi::gboolean
where
T::ImplType: BinImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let bin = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: BinBase>(
message: *mut gst_ffi::GstMessage,
) where
T::ImplType: BinImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let bin = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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))
});
}

View file

@ -24,7 +24,10 @@ use gst::prelude::*;
use anyimpl::*;
use object::*;
pub trait ElementImpl<T: ElementBase>: ObjectImpl<T> + AnyImpl + Send + Sync + 'static {
pub trait ElementImpl<T: ElementBase>: ObjectImpl<T> + 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<T> {
impl<S: ElementImpl<T>, T: ObjectType + glib::IsA<gst::Element> + glib::IsA<gst::Object>>
ElementImplExt<T> for S
where
T::InstanceStructType: PanicPoison
{
fn catch_panic_pad_function<R, F: FnOnce(&Self, &T) -> R, G: FnOnce() -> R>(
parent: &Option<gst::Object>,
@ -79,9 +84,12 @@ impl<S: ElementImpl<T>, T: ObjectType + glib::IsA<gst::Element> + glib::IsA<gst:
}
}
any_impl!(ElementBase, ElementImpl);
any_impl!(ElementBase, ElementImpl, PanicPoison);
pub unsafe trait ElementBase: IsA<gst::Element> + ObjectType {
pub unsafe trait ElementBase: IsA<gst::Element> + 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<gst::Element> + ObjectType {
}
}
fn catch_panic<T, F: FnOnce(&Self) -> T, G: FnOnce() -> T>(&self, fallback: G, f: F) -> T {
let panicked = unsafe { &(*self.get_instance()).panicked };
fn catch_panic<T, F: FnOnce(&Self) -> 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<gst::Element> + ObjectType {
pub unsafe trait ElementClassExt<T: ElementBase>
where
T::ImplType: ElementImpl<T>,
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::<T>);
@ -177,15 +188,18 @@ where
}
glib_wrapper! {
pub struct Element(Object<InstanceStruct<Element>>): [gst::Element => gst_ffi::GstElement,
gst::Object => gst_ffi::GstObject];
pub struct Element(Object<ElementInstanceStruct<Element>>):
[gst::Element => gst_ffi::GstElement,
gst::Object => gst_ffi::GstObject];
match fn {
get_type => || get_type::<Element>(),
}
}
unsafe impl<T: IsA<gst::Element> + ObjectType> ElementBase for T {}
unsafe impl<T: IsA<gst::Element> + ObjectType> ElementBase for T
where Self::InstanceStructType: PanicPoison{}
pub type ElementClass = ClassStruct<Element>;
// 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<T: ElementBase> ElementImpl<T> for Box<$name<T>> {
impl<T: ElementBase> ElementImpl<T> for Box<$name<T>>
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<ElementImpl<Self>>;
type InstanceStructType = ElementInstanceStruct<Self>;
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<T: ElementBase>(
) -> gst_ffi::GstStateChangeReturn
where
T::ImplType: ElementImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: ElementBase>(
) -> *mut gst_ffi::GstPad
where
T::ImplType: ElementImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: ElementBase>(
ptr: *mut gst_ffi::GstElement,
pad: *mut gst_ffi::GstPad,
) where
)where
T::ImplType: ElementImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: ElementBase>(
) -> glib_ffi::gboolean
where
T::ImplType: ElementImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: ElementBase>(
) -> glib_ffi::gboolean
where
T::ImplType: ElementImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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<T: ElementBase>(
ptr: *mut gst_ffi::GstElement,
context: *mut gst_ffi::GstContext,
) where
)where
T::ImplType: ElementImpl<T>,
T::InstanceStructType: PanicPoison
{
callback_guard!();
floating_reference_guard!(ptr);
let element = &*(ptr as *mut InstanceStruct<T>);
let wrap: T = from_glib_borrow(ptr as *mut InstanceStruct<T>);
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))
})
}

View file

@ -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<gobject_ffi::GObject>);
impl FloatingReferenceGuard {
pub unsafe fn new(obj: *mut gobject_ffi::GObject) -> Option<FloatingReferenceGuard> {
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]

View file

@ -1,506 +1,47 @@
// Copyright (C) 2017 Sebastian Dröge <sebastian@centricular.com>
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<T: ObjectType>: 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<glib::Value, ()> {
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<T: ObjectType> ObjectImpl<T> for Box<$name<T>> {
fn set_property(&self, obj: &glib::Object, id: u32, value: &glib::Value) {
let imp: &$name<T> = self.as_ref();
imp.set_property(obj, id, value);
}
fn get_property(&self, obj: &glib::Object, id: u32) -> Result<glib::Value, ()> {
let imp: &$name<T> = self.as_ref();
imp.get_property(obj, id)
}
}
};
);
pub trait ImplTypeStatic<T: ObjectType>: Send + Sync + 'static {
fn get_name(&self) -> &str;
fn new(&self, &T) -> T::ImplType;
fn class_init(&self, &mut ClassStruct<T>);
fn type_init(&self, _: &TypeInitToken, _type_: glib::Type) {}
}
pub struct ClassInitToken(());
pub struct TypeInitToken(());
pub trait ObjectType: FromGlibPtrBorrow<*mut InstanceStruct<Self>> + 'static
where
Self: Sized,
{
const NAME: &'static str;
type GlibType;
type GlibClassType;
type ImplType: ObjectImpl<Self>;
fn glib_type() -> glib::Type;
fn class_init(token: &ClassInitToken, klass: &mut ClassStruct<Self>);
fn set_property(_obj: &Self, _id: u32, _value: &glib::Value) {
unimplemented!()
}
fn get_property(_obj: &Self, _id: u32) -> Result<glib::Value, ()> {
unimplemented!()
}
unsafe fn get_instance(&self) -> *mut InstanceStruct<Self>;
fn get_impl(&self) -> &Self::ImplType {
unsafe { (*self.get_instance()).get_impl() }
}
unsafe fn get_class(&self) -> *const ClassStruct<Self> {
(*self.get_instance()).get_class()
}
}
#[macro_export]
macro_rules! object_type_fns(
() => {
unsafe fn get_instance(&self) -> *mut InstanceStruct<Self> {
self.to_glib_none().0
}
}
);
#[repr(C)]
pub struct InstanceStruct<T: ObjectType> {
pub parent: T::GlibType,
pub imp: ptr::NonNull<T::ImplType>,
pub panicked: AtomicBool,
pub struct ElementInstanceStruct<T: ObjectType>
{
_parent: T::GlibType,
_imp: ptr::NonNull<T::ImplType>,
_panicked: AtomicBool,
}
impl<T: ObjectType> InstanceStruct<T> {
pub fn get_impl(&self) -> &T::ImplType {
unsafe { self.imp.as_ref() }
pub trait PanicPoison{
fn panicked(&self) -> &AtomicBool;
}
impl<T: ObjectType> Instance<T> for ElementInstanceStruct<T>
{
fn parent(&self) -> &T::GlibType{
&self._parent
}
pub unsafe fn get_class(&self) -> *const ClassStruct<T> {
fn get_impl(&self) -> &T::ImplType {
unsafe { self._imp.as_ref() }
}
unsafe fn set_impl(&mut self, imp:ptr::NonNull<T::ImplType>){
self._imp = imp;
}
unsafe fn get_class(&self) -> *const ClassStruct<T> {
*(self as *const _ as *const *const ClassStruct<T>)
}
}
#[repr(C)]
pub struct ClassStruct<T: ObjectType> {
pub parent: T::GlibClassType,
pub imp_static: ptr::NonNull<Box<ImplTypeStatic<T>>>,
pub parent_class: ptr::NonNull<T::GlibClassType>,
pub interfaces_static: *const Vec<(glib_ffi::GType, glib_ffi::gpointer)>,
}
impl<T: ObjectType> ClassStruct<T> {
pub fn get_parent_class(&self) -> *const T::GlibClassType {
self.parent_class.as_ptr()
}
}
impl<T: ObjectType> ClassStruct<T> {
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<T: ObjectType> PanicPoison for ElementInstanceStruct<T>
{
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::<Vec<_>>();
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<F>(
&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::<Vec<_>>();
let accumulator: Box<
Box<Fn(&mut glib::Value, &glib::Value) -> 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<F>(
&mut self,
name: &str,
arg_types: &[glib::Type],
ret_type: glib::Type,
handler: F,
) where
F: Fn(&[glib::Value]) -> Option<glib::Value> + Send + Sync + 'static,
{
let arg_types = arg_types.iter().map(|t| t.to_glib()).collect::<Vec<_>>();
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<T: ObjectType> ObjectClass for ClassStruct<T> {}
unsafe extern "C" fn class_init<T: ObjectType>(
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::<T>);
gobject_klass.set_property = Some(set_property::<T>);
gobject_klass.get_property = Some(get_property::<T>);
}
{
let klass = &mut *(klass as *mut ClassStruct<T>);
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<T: ObjectType>(obj: *mut gobject_ffi::GObject) {
callback_guard!();
let instance = &mut *(obj as *mut InstanceStruct<T>);
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<T: ObjectType>(
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<T>), 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<T: ObjectType>(
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<T>),
id - 1,
&*(value as *mut glib::Value),
);
}
static mut TYPES: *mut Mutex<BTreeMap<TypeId, glib::Type>> = 0 as *mut _;
pub unsafe fn get_type<T: ObjectType>() -> 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::<T>())
.or_insert_with(|| {
let type_info = gobject_ffi::GTypeInfo {
class_size: mem::size_of::<ClassStruct<T>>() as u16,
base_init: None,
base_finalize: None,
class_init: Some(class_init::<T>),
class_finalize: None,
class_data: ptr::null_mut(),
instance_size: mem::size_of::<InstanceStruct<T>>() 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<T: ObjectType>(
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::<T>);
gobject_klass.get_property = Some(sub_get_property::<T>);
}
{
assert!(!klass_data.is_null());
let klass = &mut *(klass as *mut ClassStruct<T>);
let imp_static = klass_data as *mut Box<ImplTypeStatic<T>>;
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<T: ObjectType>(
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<T>);
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<T: ObjectType>(
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<T>);
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<T: ObjectType>(
obj: *mut gobject_ffi::GTypeInstance,
_klass: glib_ffi::gpointer,
) {
callback_guard!();
floating_reference_guard!(obj);
let instance = &mut *(obj as *mut InstanceStruct<T>);
let klass = &**(obj as *const *const ClassStruct<T>);
let rs_instance: T = from_glib_borrow(obj as *mut InstanceStruct<T>);
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<T: ObjectType, I: ImplTypeStatic<T>>(imp: I) -> glib::Type {
unsafe {
let parent_type = get_type::<T>();
let type_name = format!("{}-{}", T::NAME, imp.get_name());
let imp: Box<ImplTypeStatic<T>> = Box::new(imp);
let imp_ptr = Box::into_raw(Box::new(imp));
let type_info = gobject_ffi::GTypeInfo {
class_size: mem::size_of::<ClassStruct<T>>() as u16,
base_init: None,
base_finalize: None,
class_init: Some(sub_class_init::<T>),
class_finalize: None,
class_data: imp_ptr as glib_ffi::gpointer,
instance_size: mem::size_of::<InstanceStruct<T>>() as u16,
n_preallocs: 0,
instance_init: Some(sub_init::<T>),
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_
}
}

View file

@ -25,10 +25,12 @@ use object::*;
pub trait PipelineImpl<T: PipelineBase>:
AnyImpl + ObjectImpl<T> + ElementImpl<T> + BinImpl<T> + Send + Sync + 'static
where
T::InstanceStructType: PanicPoison
{
}
any_impl!(PipelineBase, PipelineImpl);
any_impl!(PipelineBase, PipelineImpl, PanicPoison);
pub unsafe trait PipelineBase:
IsA<gst::Element> + IsA<gst::Bin> + IsA<gst::Pipeline> + ObjectType
@ -38,16 +40,18 @@ pub unsafe trait PipelineBase:
pub unsafe trait PipelineClassExt<T: PipelineBase>
where
T::ImplType: PipelineImpl<T>,
T::InstanceStructType: PanicPoison
{
fn override_vfuncs(&mut self, _: &ClassInitToken) {}
}
glib_wrapper! {
pub struct Pipeline(Object<InstanceStruct<Pipeline>>): [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<ElementInstanceStruct<Pipeline>>):
[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::<Pipeline>(),
@ -73,7 +77,10 @@ macro_rules! box_pipeline_impl(
($name:ident) => {
box_bin_impl!($name);
impl<T: PipelineBase> PipelineImpl<T> for Box<$name<T>> {
impl<T: PipelineBase> PipelineImpl<T> for Box<$name<T>>
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<PipelineImpl<Self>>;
type InstanceStructType = ElementInstanceStruct<Self>;
fn glib_type() -> glib::Type {
unsafe { from_glib(gst_ffi::gst_pipeline_get_type()) }

View file

@ -69,7 +69,7 @@ unsafe extern "C" fn uri_handler_get_uri<T: ObjectType>(
let interface_static = klass.get_interface_static(gst_ffi::gst_uri_handler_get_type())
as *const URIHandlerStatic<T>;
let instance = &*(uri_handler as *const InstanceStruct<T>);
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<T: ObjectType>(
let interface_static = klass.get_interface_static(gst_ffi::gst_uri_handler_get_type())
as *const URIHandlerStatic<T>;
let instance = &*(uri_handler as *const InstanceStruct<T>);
let instance = &*(uri_handler as *const T::InstanceStructType);
let imp = instance.get_impl();
let imp = (*(*interface_static).imp_static).get_impl(imp);