From a3541163364c70c7d005ea13ff10d8e3eaecb7e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Tue, 26 Sep 2017 00:25:03 +0300 Subject: [PATCH] Make ObjectImpl and subtraits generic over T: ObjectType --- gst-plugin/src/base_sink.rs | 32 +++++++++++++-------------- gst-plugin/src/base_src.rs | 44 ++++++++++++++++++------------------- gst-plugin/src/demuxer.rs | 8 +++---- gst-plugin/src/element.rs | 17 +++++++------- gst-plugin/src/lib.rs | 30 +++++++++++++++++++++++++ gst-plugin/src/object.rs | 10 ++++----- gst-plugin/src/sink.rs | 12 +++++----- gst-plugin/src/source.rs | 12 +++++----- 8 files changed, 98 insertions(+), 67 deletions(-) diff --git a/gst-plugin/src/base_sink.rs b/gst-plugin/src/base_sink.rs index 0b17aaf1..9a3c680d 100644 --- a/gst-plugin/src/base_sink.rs +++ b/gst-plugin/src/base_sink.rs @@ -25,8 +25,8 @@ use gst_base::prelude::*; use object::*; use element::*; -pub trait BaseSinkImpl - : mopa::Any + ObjectImpl + ElementImpl + Send + Sync + 'static { +pub trait BaseSinkImpl + : mopa::Any + ObjectImpl + ElementImpl + Send + Sync + 'static { fn start(&self, _element: &gst_base::BaseSink) -> bool { true } @@ -42,7 +42,7 @@ pub trait BaseSinkImpl } } -mopafy!(BaseSinkImpl); +mopafy_object_impl!(BaseSinkImpl); pub unsafe trait BaseSink: IsA { fn parent_query(&self, query: &mut gst::QueryRef) -> bool { @@ -83,7 +83,7 @@ pub unsafe trait BaseSink: IsA { pub unsafe trait BaseSinkClass where T: IsA, - T::ImplType: BaseSinkImpl, + T::ImplType: BaseSinkImpl, { fn override_vfuncs(&mut self) { unsafe { @@ -119,28 +119,28 @@ macro_rules! box_base_sink_impl( ($name:ident) => { box_element_impl!($name); - impl BaseSinkImpl for Box<$name> { + impl BaseSinkImpl for Box<$name> { fn start(&self, element: &gst_base::BaseSink) -> bool { - let imp: &$name = self.as_ref(); + let imp: &$name = self.as_ref(); imp.start(element) } fn stop(&self, element: &gst_base::BaseSink) -> bool { - let imp: &$name = self.as_ref(); + let imp: &$name = self.as_ref(); imp.stop(element) } fn render(&self, element: &gst_base::BaseSink, buffer: &gst::BufferRef) -> gst::FlowReturn { - let imp: &$name = self.as_ref(); + let imp: &$name = self.as_ref(); imp.render(element, buffer) } fn query(&self, element: &gst_base::BaseSink, query: &mut gst::QueryRef) -> bool { - let imp: &$name = self.as_ref(); + let imp: &$name = self.as_ref(); imp.query(element, query) } fn event(&self, element: &gst_base::BaseSink, event: &gst::Event) -> bool { - let imp: &$name = self.as_ref(); + let imp: &$name = self.as_ref(); imp.event(element, event) } } @@ -153,7 +153,7 @@ impl ObjectType for RsBaseSink { const NAME: &'static str = "RsBaseSink"; type GlibType = gst_base_ffi::GstBaseSink; type GlibClassType = gst_base_ffi::GstBaseSinkClass; - type ImplType = Box; + type ImplType = Box>; fn glib_type() -> glib::Type { unsafe { from_glib(gst_base_ffi::gst_base_sink_get_type()) } @@ -170,7 +170,7 @@ unsafe extern "C" fn base_sink_start( ) -> glib_ffi::gboolean where T: IsA, - T::ImplType: BaseSinkImpl, + T::ImplType: BaseSinkImpl, { callback_guard!(); floating_reference_guard!(ptr); @@ -186,7 +186,7 @@ unsafe extern "C" fn base_sink_stop( ) -> glib_ffi::gboolean where T: IsA, - T::ImplType: BaseSinkImpl, + T::ImplType: BaseSinkImpl, { callback_guard!(); floating_reference_guard!(ptr); @@ -203,7 +203,7 @@ unsafe extern "C" fn base_sink_render( ) -> gst_ffi::GstFlowReturn where T: IsA, - T::ImplType: BaseSinkImpl, + T::ImplType: BaseSinkImpl, { callback_guard!(); floating_reference_guard!(ptr); @@ -223,7 +223,7 @@ unsafe extern "C" fn base_sink_query( ) -> glib_ffi::gboolean where T: IsA, - T::ImplType: BaseSinkImpl, + T::ImplType: BaseSinkImpl, { callback_guard!(); floating_reference_guard!(ptr); @@ -241,7 +241,7 @@ unsafe extern "C" fn base_sink_event( ) -> glib_ffi::gboolean where T: IsA, - T::ImplType: BaseSinkImpl, + T::ImplType: BaseSinkImpl, { callback_guard!(); floating_reference_guard!(ptr); diff --git a/gst-plugin/src/base_src.rs b/gst-plugin/src/base_src.rs index 5d00c912..3b731793 100644 --- a/gst-plugin/src/base_src.rs +++ b/gst-plugin/src/base_src.rs @@ -25,8 +25,8 @@ use gst_base::prelude::*; use object::*; use element::*; -pub trait BaseSrcImpl - : mopa::Any + ObjectImpl + ElementImpl + Send + Sync + 'static { +pub trait BaseSrcImpl + : mopa::Any + ObjectImpl + ElementImpl + Send + Sync + 'static { fn start(&self, _element: &gst_base::BaseSrc) -> bool { true } @@ -57,7 +57,7 @@ pub trait BaseSrcImpl } } -mopafy!(BaseSrcImpl); +mopafy_object_impl!(BaseSrcImpl); pub unsafe trait BaseSrc: IsA { fn parent_do_seek(&self, segment: &mut gst::Segment) -> bool { @@ -116,7 +116,7 @@ pub unsafe trait BaseSrc: IsA { pub unsafe trait BaseSrcClass where T: IsA, - T::ImplType: BaseSrcImpl, + T::ImplType: BaseSrcImpl, { fn override_vfuncs(&mut self) { unsafe { @@ -156,24 +156,24 @@ macro_rules! box_base_src_impl( ($name:ident) => { box_element_impl!($name); - impl BaseSrcImpl for Box<$name> { + impl BaseSrcImpl for Box<$name> { fn start(&self, element: &gst_base::BaseSrc) -> bool { - let imp: &$name = self.as_ref(); + let imp: &$name = self.as_ref(); imp.start(element) } fn stop(&self, element: &gst_base::BaseSrc) -> bool { - let imp: &$name = self.as_ref(); + let imp: &$name = self.as_ref(); imp.stop(element) } fn is_seekable(&self, element: &gst_base::BaseSrc) -> bool { - let imp: &$name = self.as_ref(); + let imp: &$name = self.as_ref(); imp.is_seekable(element) } fn get_size(&self, element: &gst_base::BaseSrc) -> Option { - let imp: &$name = self.as_ref(); + let imp: &$name = self.as_ref(); imp.get_size(element) } @@ -184,21 +184,21 @@ macro_rules! box_base_src_impl( length: u32, buffer: &mut gst::BufferRef, ) -> gst::FlowReturn { - let imp: &$name = self.as_ref(); + let imp: &$name = self.as_ref(); imp.fill(element, offset, length, buffer) } fn do_seek(&self, element: &gst_base::BaseSrc, segment: &mut gst::Segment) -> bool { - let imp: &$name = self.as_ref(); + let imp: &$name = self.as_ref(); imp.do_seek(element, segment) } fn query(&self, element: &gst_base::BaseSrc, query: &mut gst::QueryRef) -> bool { - let imp: &$name = self.as_ref(); + let imp: &$name = self.as_ref(); imp.query(element, query) } fn event(&self, element: &gst_base::BaseSrc, event: &gst::Event) -> bool { - let imp: &$name = self.as_ref(); + let imp: &$name = self.as_ref(); imp.event(element, event) } } @@ -210,7 +210,7 @@ impl ObjectType for RsBaseSrc { const NAME: &'static str = "RsBaseSrc"; type GlibType = gst_base_ffi::GstBaseSrc; type GlibClassType = gst_base_ffi::GstBaseSrcClass; - type ImplType = Box; + type ImplType = Box>; fn glib_type() -> glib::Type { unsafe { from_glib(gst_base_ffi::gst_base_src_get_type()) } @@ -227,7 +227,7 @@ unsafe extern "C" fn base_src_start( ) -> glib_ffi::gboolean where T: IsA, - T::ImplType: BaseSrcImpl, + T::ImplType: BaseSrcImpl, { callback_guard!(); floating_reference_guard!(ptr); @@ -243,7 +243,7 @@ unsafe extern "C" fn base_src_stop( ) -> glib_ffi::gboolean where T: IsA, - T::ImplType: BaseSrcImpl, + T::ImplType: BaseSrcImpl, { callback_guard!(); floating_reference_guard!(ptr); @@ -259,7 +259,7 @@ unsafe extern "C" fn base_src_is_seekable( ) -> glib_ffi::gboolean where T: IsA, - T::ImplType: BaseSrcImpl, + T::ImplType: BaseSrcImpl, { callback_guard!(); floating_reference_guard!(ptr); @@ -276,7 +276,7 @@ unsafe extern "C" fn base_src_get_size( ) -> glib_ffi::gboolean where T: IsA, - T::ImplType: BaseSrcImpl, + T::ImplType: BaseSrcImpl, { callback_guard!(); floating_reference_guard!(ptr); @@ -303,7 +303,7 @@ unsafe extern "C" fn base_src_fill( ) -> gst_ffi::GstFlowReturn where T: IsA, - T::ImplType: BaseSrcImpl, + T::ImplType: BaseSrcImpl, { callback_guard!(); floating_reference_guard!(ptr); @@ -323,7 +323,7 @@ unsafe extern "C" fn base_src_do_seek( ) -> glib_ffi::gboolean where T: IsA, - T::ImplType: BaseSrcImpl, + T::ImplType: BaseSrcImpl, { callback_guard!(); floating_reference_guard!(ptr); @@ -342,7 +342,7 @@ unsafe extern "C" fn base_src_query( ) -> glib_ffi::gboolean where T: IsA, - T::ImplType: BaseSrcImpl, + T::ImplType: BaseSrcImpl, { callback_guard!(); floating_reference_guard!(ptr); @@ -360,7 +360,7 @@ unsafe extern "C" fn base_src_event( ) -> glib_ffi::gboolean where T: IsA, - T::ImplType: BaseSrcImpl, + T::ImplType: BaseSrcImpl, { callback_guard!(); floating_reference_guard!(ptr); diff --git a/gst-plugin/src/demuxer.rs b/gst-plugin/src/demuxer.rs index 625c601c..3d9f8794 100644 --- a/gst-plugin/src/demuxer.rs +++ b/gst-plugin/src/demuxer.rs @@ -175,7 +175,7 @@ impl Demuxer { klass.add_pad_template(pad_template); } - fn init(element: &RsElement, demuxer_info: &DemuxerInfo) -> Box { + fn init(element: &RsElement, demuxer_info: &DemuxerInfo) -> Box> { let templ = element.get_pad_template("sink").unwrap(); let sinkpad = gst::Pad::new_from_template(&templ, "sink"); sinkpad.set_activate_function(Demuxer::sink_activate); @@ -638,9 +638,9 @@ impl Demuxer { } } -impl ObjectImpl for Demuxer {} +impl ObjectImpl for Demuxer {} -impl ElementImpl for Demuxer { +impl ElementImpl for Demuxer { fn change_state( &self, element: &gst::Element, @@ -689,7 +689,7 @@ impl ImplTypeStatic for DemuxerStatic { self.name.as_str() } - fn new(&self, element: &RsElement) -> Box { + fn new(&self, element: &RsElement) -> Box> { Demuxer::init(element, &self.demuxer_info) } diff --git a/gst-plugin/src/element.rs b/gst-plugin/src/element.rs index 768ebc49..db928b81 100644 --- a/gst-plugin/src/element.rs +++ b/gst-plugin/src/element.rs @@ -21,7 +21,8 @@ use gst::prelude::*; use object::*; -pub trait ElementImpl: ObjectImpl + mopa::Any + Send + Sync + 'static { +pub trait ElementImpl + : ObjectImpl + mopa::Any + Send + Sync + 'static { fn change_state( &self, element: &gst::Element, @@ -31,7 +32,7 @@ pub trait ElementImpl: ObjectImpl + mopa::Any + Send + Sync + 'static { } } -mopafy!(ElementImpl); +mopafy_object_impl!(ElementImpl); pub unsafe trait Element: IsA { fn parent_change_state(&self, transition: gst::StateChange) -> gst::StateChangeReturn { @@ -56,7 +57,7 @@ pub unsafe trait Element: IsA { pub unsafe trait ElementClass where T: IsA, - T::ImplType: ElementImpl, + T::ImplType: ElementImpl, { fn add_pad_template(&mut self, pad_template: gst::PadTemplate) { unsafe { @@ -103,7 +104,7 @@ glib_wrapper! { } impl RsElement { - pub fn get_impl(&self) -> &ElementImpl { + pub fn get_impl(&self) -> &ElementImpl { unsafe { let stash = self.to_glib_none(); let ptr: *mut InstanceStruct = stash.0; @@ -123,13 +124,13 @@ macro_rules! box_element_impl( ($name:ident) => { box_object_impl!($name); - impl ElementImpl for Box<$name> { + impl ElementImpl for Box<$name> { fn change_state( &self, element: &gst::Element, transition: gst::StateChange, ) -> gst::StateChangeReturn { - let imp: &$name = self.as_ref(); + let imp: &$name = self.as_ref(); imp.change_state(element, transition) } } @@ -142,7 +143,7 @@ impl ObjectType for RsElement { const NAME: &'static str = "RsElement"; type GlibType = gst_ffi::GstElement; type GlibClassType = gst_ffi::GstElementClass; - type ImplType = Box; + type ImplType = Box>; fn glib_type() -> glib::Type { unsafe { from_glib(gst_ffi::gst_element_get_type()) } @@ -159,7 +160,7 @@ unsafe extern "C" fn element_change_state( ) -> gst_ffi::GstStateChangeReturn where T: IsA, - T::ImplType: ElementImpl, + T::ImplType: ElementImpl, { callback_guard!(); floating_reference_guard!(ptr); diff --git a/gst-plugin/src/lib.rs b/gst-plugin/src/lib.rs index cfe03ba7..9c53faf1 100644 --- a/gst-plugin/src/lib.rs +++ b/gst-plugin/src/lib.rs @@ -60,6 +60,36 @@ impl Drop for FloatingReferenceGuard { } } +// mopafy! macro to work with generic traits over T: ObjectType +macro_rules! mopafy_object_impl { + ($trait:ident) => { + impl $trait { + #[inline] + pub fn downcast_ref>(&self) -> Option<&U> { + if self.is::() { + unsafe { + Some(self.downcast_ref_unchecked()) + } + } else { + None + } + } + + #[inline] + pub unsafe fn downcast_ref_unchecked>(&self) -> &U { + &*(self as *const Self as *const U) + } + + #[inline] + pub fn is>(&self) -> bool { + use std::any::TypeId; + use mopa; + TypeId::of::() == mopa::Any::get_type_id(self) + } + } + }; +} + #[macro_use] pub mod utils; #[macro_use] diff --git a/gst-plugin/src/object.rs b/gst-plugin/src/object.rs index 0e4690f1..826c6fe9 100644 --- a/gst-plugin/src/object.rs +++ b/gst-plugin/src/object.rs @@ -20,7 +20,7 @@ use gobject_ffi; use glib; use glib::translate::*; -pub trait ObjectImpl: Send + Sync + 'static { +pub trait ObjectImpl: Send + Sync + 'static { fn set_property(&self, _obj: &glib::Object, _id: u32, _value: &glib::Value) { unimplemented!() } @@ -39,14 +39,14 @@ pub trait ObjectImpl: Send + Sync + 'static { #[macro_export] macro_rules! box_object_impl( ($name:ident) => { - impl ObjectImpl for Box<$name> { + impl ObjectImpl for Box<$name> { fn set_property(&self, obj: &glib::Object, id: u32, value: &glib::Value) { - let imp: &$name = self.as_ref(); + 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(); + let imp: &$name = self.as_ref(); imp.get_property(obj, id) } } @@ -71,7 +71,7 @@ where const NAME: &'static str; type GlibType; type GlibClassType; - type ImplType: ObjectImpl; + type ImplType: ObjectImpl; fn glib_type() -> glib::Type; diff --git a/gst-plugin/src/sink.rs b/gst-plugin/src/sink.rs index d607ea0a..7c462ded 100644 --- a/gst-plugin/src/sink.rs +++ b/gst-plugin/src/sink.rs @@ -86,7 +86,7 @@ impl Sink { klass.install_properties(&PROPERTIES); } - fn init(element: &RsBaseSink, sink_info: &SinkInfo) -> Box { + fn init(element: &RsBaseSink, sink_info: &SinkInfo) -> Box> { element.set_blocksize(4096); let imp = Self::new(element, sink_info); @@ -133,7 +133,7 @@ impl Sink { } } -impl ObjectImpl for Sink { +impl ObjectImpl for Sink { fn set_property(&self, obj: &glib::Object, id: u32, value: &glib::Value) { let prop = &PROPERTIES[id as usize]; @@ -155,9 +155,9 @@ impl ObjectImpl for Sink { } } -impl ElementImpl for Sink {} +impl ElementImpl for Sink {} -impl BaseSinkImpl for Sink { +impl BaseSinkImpl for Sink { fn start(&self, element: &gst_base::BaseSink) -> bool { let sink = element.clone().downcast::().unwrap(); @@ -266,7 +266,7 @@ impl ImplTypeStatic for SinkStatic { self.name.as_str() } - fn new(&self, element: &RsBaseSink) -> Box { + fn new(&self, element: &RsBaseSink) -> Box> { Sink::init(element, &self.sink_info) } @@ -280,7 +280,7 @@ impl ImplTypeStatic for SinkStatic { } impl URIHandlerImplStatic for SinkStatic { - fn get_impl<'a>(&self, imp: &'a Box) -> &'a URIHandlerImpl { + fn get_impl<'a>(&self, imp: &'a Box>) -> &'a URIHandlerImpl { imp.downcast_ref::().unwrap() } diff --git a/gst-plugin/src/source.rs b/gst-plugin/src/source.rs index 7c7f0ad0..6a254e3e 100644 --- a/gst-plugin/src/source.rs +++ b/gst-plugin/src/source.rs @@ -100,7 +100,7 @@ impl Source { klass.install_properties(&PROPERTIES); } - fn init(element: &RsBaseSrc, source_info: &SourceInfo) -> Box { + fn init(element: &RsBaseSrc, source_info: &SourceInfo) -> Box> { element.set_blocksize(4096); let imp = Self::new(element, source_info); @@ -147,7 +147,7 @@ impl Source { } } -impl ObjectImpl for Source { +impl ObjectImpl for Source { fn set_property(&self, obj: &glib::Object, id: u32, value: &glib::Value) { let prop = &PROPERTIES[id as usize]; @@ -169,9 +169,9 @@ impl ObjectImpl for Source { } } -impl ElementImpl for Source {} +impl ElementImpl for Source {} -impl BaseSrcImpl for Source { +impl BaseSrcImpl for Source { fn start(&self, element: &gst_base::BaseSrc) -> bool { let src = element.clone().downcast::().unwrap(); @@ -343,7 +343,7 @@ impl ImplTypeStatic for SourceStatic { self.name.as_str() } - fn new(&self, element: &RsBaseSrc) -> Box { + fn new(&self, element: &RsBaseSrc) -> Box> { Source::init(element, &self.source_info) } @@ -357,7 +357,7 @@ impl ImplTypeStatic for SourceStatic { } impl URIHandlerImplStatic for SourceStatic { - fn get_impl<'a>(&self, imp: &'a Box) -> &'a URIHandlerImpl { + fn get_impl<'a>(&self, imp: &'a Box>) -> &'a URIHandlerImpl { imp.downcast_ref::().unwrap() }