forked from mirrors/gstreamer-rs
Fix compilation with GLib subclassing changes
This commit is contained in:
parent
fec4e12410
commit
1d53b66858
5 changed files with 231 additions and 183 deletions
|
@ -98,6 +98,7 @@ mod media_factory {
|
||||||
// up the class data
|
// up the class data
|
||||||
impl ObjectSubclass for Factory {
|
impl ObjectSubclass for Factory {
|
||||||
const NAME: &'static str = "RsRTSPMediaFactory";
|
const NAME: &'static str = "RsRTSPMediaFactory";
|
||||||
|
type Type = super::Factory;
|
||||||
type ParentType = gst_rtsp_server::RTSPMediaFactory;
|
type ParentType = gst_rtsp_server::RTSPMediaFactory;
|
||||||
type Instance = gst::subclass::ElementInstanceStruct<Self>;
|
type Instance = gst::subclass::ElementInstanceStruct<Self>;
|
||||||
type Class = subclass::simple::ClassStruct<Self>;
|
type Class = subclass::simple::ClassStruct<Self>;
|
||||||
|
@ -114,12 +115,8 @@ mod media_factory {
|
||||||
|
|
||||||
// Implementation of glib::Object virtual methods
|
// Implementation of glib::Object virtual methods
|
||||||
impl ObjectImpl for Factory {
|
impl ObjectImpl for Factory {
|
||||||
fn constructed(&self, obj: &glib::Object) {
|
fn constructed(&self, factory: &Self::Type) {
|
||||||
self.parent_constructed(obj);
|
self.parent_constructed(factory);
|
||||||
|
|
||||||
let factory = obj
|
|
||||||
.downcast_ref::<gst_rtsp_server::RTSPMediaFactory>()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
// All media created by this factory are our custom media type. This would
|
// All media created by this factory are our custom media type. This would
|
||||||
// not require a media factory subclass and can also be called on the normal
|
// not require a media factory subclass and can also be called on the normal
|
||||||
|
@ -199,6 +196,7 @@ mod media {
|
||||||
// up the class data
|
// up the class data
|
||||||
impl ObjectSubclass for Media {
|
impl ObjectSubclass for Media {
|
||||||
const NAME: &'static str = "RsRTSPMedia";
|
const NAME: &'static str = "RsRTSPMedia";
|
||||||
|
type Type = super::Media;
|
||||||
type ParentType = gst_rtsp_server::RTSPMedia;
|
type ParentType = gst_rtsp_server::RTSPMedia;
|
||||||
type Instance = gst::subclass::ElementInstanceStruct<Self>;
|
type Instance = gst::subclass::ElementInstanceStruct<Self>;
|
||||||
type Class = subclass::simple::ClassStruct<Self>;
|
type Class = subclass::simple::ClassStruct<Self>;
|
||||||
|
@ -266,6 +264,7 @@ mod server {
|
||||||
// up the class data
|
// up the class data
|
||||||
impl ObjectSubclass for Server {
|
impl ObjectSubclass for Server {
|
||||||
const NAME: &'static str = "RsRTSPServer";
|
const NAME: &'static str = "RsRTSPServer";
|
||||||
|
type Type = super::Server;
|
||||||
type ParentType = gst_rtsp_server::RTSPServer;
|
type ParentType = gst_rtsp_server::RTSPServer;
|
||||||
type Instance = gst::subclass::ElementInstanceStruct<Self>;
|
type Instance = gst::subclass::ElementInstanceStruct<Self>;
|
||||||
type Class = subclass::simple::ClassStruct<Self>;
|
type Class = subclass::simple::ClassStruct<Self>;
|
||||||
|
@ -353,6 +352,7 @@ mod client {
|
||||||
// up the class data
|
// up the class data
|
||||||
impl ObjectSubclass for Client {
|
impl ObjectSubclass for Client {
|
||||||
const NAME: &'static str = "RsRTSPClient";
|
const NAME: &'static str = "RsRTSPClient";
|
||||||
|
type Type = super::Client;
|
||||||
type ParentType = gst_rtsp_server::RTSPClient;
|
type ParentType = gst_rtsp_server::RTSPClient;
|
||||||
type Instance = gst::subclass::ElementInstanceStruct<Self>;
|
type Instance = gst::subclass::ElementInstanceStruct<Self>;
|
||||||
type Class = subclass::simple::ClassStruct<Self>;
|
type Class = subclass::simple::ClassStruct<Self>;
|
||||||
|
|
|
@ -62,6 +62,7 @@ mod fir_filter {
|
||||||
// up the class data
|
// up the class data
|
||||||
impl ObjectSubclass for FirFilter {
|
impl ObjectSubclass for FirFilter {
|
||||||
const NAME: &'static str = "RsFirFilter";
|
const NAME: &'static str = "RsFirFilter";
|
||||||
|
type Type = super::FirFilter;
|
||||||
type ParentType = gst_base::BaseTransform;
|
type ParentType = gst_base::BaseTransform;
|
||||||
type Instance = gst::subclass::ElementInstanceStruct<Self>;
|
type Instance = gst::subclass::ElementInstanceStruct<Self>;
|
||||||
type Class = subclass::simple::ClassStruct<Self>;
|
type Class = subclass::simple::ClassStruct<Self>;
|
||||||
|
@ -88,7 +89,7 @@ mod fir_filter {
|
||||||
// will automatically instantiate pads for them.
|
// will automatically instantiate pads for them.
|
||||||
//
|
//
|
||||||
// Our element here can only handle F32 mono audio.
|
// Our element here can only handle F32 mono audio.
|
||||||
fn class_init(klass: &mut subclass::simple::ClassStruct<Self>) {
|
fn class_init(klass: &mut Self::Class) {
|
||||||
// Set the element specific metadata. This information is what
|
// Set the element specific metadata. This information is what
|
||||||
// is visible from gst-inspect-1.0 and can also be programatically
|
// is visible from gst-inspect-1.0 and can also be programatically
|
||||||
// retrieved from the gst::Registry after initial registration
|
// retrieved from the gst::Registry after initial registration
|
||||||
|
|
|
@ -81,7 +81,7 @@ pub trait ClockImplExt {
|
||||||
fn wake_id(&self, id: &ClockId)
|
fn wake_id(&self, id: &ClockId)
|
||||||
where
|
where
|
||||||
Self: ObjectSubclass,
|
Self: ObjectSubclass,
|
||||||
<Self as ObjectSubclass>::ParentType: IsA<Clock>;
|
<Self as ObjectSubclass>::Type: IsA<Clock>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ClockImpl> ClockImplExt for T {
|
impl<T: ClockImpl> ClockImplExt for T {
|
||||||
|
@ -199,7 +199,7 @@ impl<T: ClockImpl> ClockImplExt for T {
|
||||||
fn wake_id(&self, id: &ClockId)
|
fn wake_id(&self, id: &ClockId)
|
||||||
where
|
where
|
||||||
Self: ObjectSubclass,
|
Self: ObjectSubclass,
|
||||||
<Self as ObjectSubclass>::ParentType: IsA<Clock>,
|
<Self as ObjectSubclass>::Type: IsA<Clock>,
|
||||||
{
|
{
|
||||||
let clock = self.get_instance();
|
let clock = self.get_instance();
|
||||||
|
|
||||||
|
|
|
@ -549,145 +549,175 @@ mod tests {
|
||||||
use glib::subclass;
|
use glib::subclass;
|
||||||
use std::sync::atomic;
|
use std::sync::atomic;
|
||||||
|
|
||||||
struct TestElement {
|
pub mod imp {
|
||||||
srcpad: ::Pad,
|
use super::*;
|
||||||
sinkpad: ::Pad,
|
|
||||||
n_buffers: atomic::AtomicU32,
|
pub struct TestElement {
|
||||||
reached_playing: atomic::AtomicBool,
|
pub(super) srcpad: ::Pad,
|
||||||
|
pub(super) sinkpad: ::Pad,
|
||||||
|
pub(super) n_buffers: atomic::AtomicU32,
|
||||||
|
pub(super) reached_playing: atomic::AtomicBool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestElement {
|
||||||
|
fn sink_chain(
|
||||||
|
&self,
|
||||||
|
_pad: &::Pad,
|
||||||
|
_element: &::Element,
|
||||||
|
buffer: ::Buffer,
|
||||||
|
) -> Result<::FlowSuccess, ::FlowError> {
|
||||||
|
self.n_buffers.fetch_add(1, atomic::Ordering::SeqCst);
|
||||||
|
self.srcpad.push(buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sink_event(&self, _pad: &::Pad, _element: &::Element, event: ::Event) -> bool {
|
||||||
|
self.srcpad.push_event(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sink_query(
|
||||||
|
&self,
|
||||||
|
_pad: &::Pad,
|
||||||
|
_element: &::Element,
|
||||||
|
query: &mut ::QueryRef,
|
||||||
|
) -> bool {
|
||||||
|
self.srcpad.peer_query(query)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn src_event(&self, _pad: &::Pad, _element: &::Element, event: ::Event) -> bool {
|
||||||
|
self.sinkpad.push_event(event)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn src_query(
|
||||||
|
&self,
|
||||||
|
_pad: &::Pad,
|
||||||
|
_element: &::Element,
|
||||||
|
query: &mut ::QueryRef,
|
||||||
|
) -> bool {
|
||||||
|
self.sinkpad.peer_query(query)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ObjectSubclass for TestElement {
|
||||||
|
const NAME: &'static str = "TestElement";
|
||||||
|
type Type = super::TestElement;
|
||||||
|
type ParentType = ::Element;
|
||||||
|
type Instance = ::subclass::ElementInstanceStruct<Self>;
|
||||||
|
type Class = subclass::simple::ClassStruct<Self>;
|
||||||
|
|
||||||
|
glib_object_subclass!();
|
||||||
|
|
||||||
|
fn with_class(klass: &subclass::simple::ClassStruct<Self>) -> Self {
|
||||||
|
let templ = klass.get_pad_template("sink").unwrap();
|
||||||
|
let sinkpad = ::Pad::builder_with_template(&templ, Some("sink"))
|
||||||
|
.chain_function(|pad, parent, buffer| {
|
||||||
|
TestElement::catch_panic_pad_function(
|
||||||
|
parent,
|
||||||
|
|| Err(::FlowError::Error),
|
||||||
|
|identity, element| identity.sink_chain(pad, element, buffer),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.event_function(|pad, parent, event| {
|
||||||
|
TestElement::catch_panic_pad_function(
|
||||||
|
parent,
|
||||||
|
|| false,
|
||||||
|
|identity, element| identity.sink_event(pad, element, event),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.query_function(|pad, parent, query| {
|
||||||
|
TestElement::catch_panic_pad_function(
|
||||||
|
parent,
|
||||||
|
|| false,
|
||||||
|
|identity, element| identity.sink_query(pad, element, query),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let templ = klass.get_pad_template("src").unwrap();
|
||||||
|
let srcpad = ::Pad::builder_with_template(&templ, Some("src"))
|
||||||
|
.event_function(|pad, parent, event| {
|
||||||
|
TestElement::catch_panic_pad_function(
|
||||||
|
parent,
|
||||||
|
|| false,
|
||||||
|
|identity, element| identity.src_event(pad, element, event),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.query_function(|pad, parent, query| {
|
||||||
|
TestElement::catch_panic_pad_function(
|
||||||
|
parent,
|
||||||
|
|| false,
|
||||||
|
|identity, element| identity.src_query(pad, element, query),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Self {
|
||||||
|
n_buffers: atomic::AtomicU32::new(0),
|
||||||
|
reached_playing: atomic::AtomicBool::new(false),
|
||||||
|
srcpad,
|
||||||
|
sinkpad,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn class_init(klass: &mut subclass::simple::ClassStruct<Self>) {
|
||||||
|
klass.set_metadata(
|
||||||
|
"Test Element",
|
||||||
|
"Generic",
|
||||||
|
"Does nothing",
|
||||||
|
"Sebastian Dröge <sebastian@centricular.com>",
|
||||||
|
);
|
||||||
|
|
||||||
|
let caps = ::Caps::new_any();
|
||||||
|
let src_pad_template =
|
||||||
|
::PadTemplate::new("src", ::PadDirection::Src, ::PadPresence::Always, &caps)
|
||||||
|
.unwrap();
|
||||||
|
klass.add_pad_template(src_pad_template);
|
||||||
|
|
||||||
|
let sink_pad_template =
|
||||||
|
::PadTemplate::new("sink", ::PadDirection::Sink, ::PadPresence::Always, &caps)
|
||||||
|
.unwrap();
|
||||||
|
klass.add_pad_template(sink_pad_template);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ObjectImpl for TestElement {
|
||||||
|
fn constructed(&self, element: &Self::Type) {
|
||||||
|
self.parent_constructed(element);
|
||||||
|
|
||||||
|
element.add_pad(&self.sinkpad).unwrap();
|
||||||
|
element.add_pad(&self.srcpad).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ElementImpl for TestElement {
|
||||||
|
fn change_state(
|
||||||
|
&self,
|
||||||
|
element: &::Element,
|
||||||
|
transition: ::StateChange,
|
||||||
|
) -> Result<::StateChangeSuccess, ::StateChangeError> {
|
||||||
|
let res = self.parent_change_state(element, transition)?;
|
||||||
|
|
||||||
|
if transition == ::StateChange::PausedToPlaying {
|
||||||
|
self.reached_playing.store(true, atomic::Ordering::SeqCst);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glib_wrapper! {
|
||||||
|
pub struct TestElement(ObjectSubclass<imp::TestElement>) @extends ::Element, ::Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for TestElement {}
|
||||||
|
unsafe impl Sync for TestElement {}
|
||||||
|
|
||||||
impl TestElement {
|
impl TestElement {
|
||||||
fn sink_chain(
|
pub fn new(name: Option<&str>) -> Self {
|
||||||
&self,
|
glib::Object::new(TestElement::static_type(), &[("name", &name)])
|
||||||
_pad: &::Pad,
|
.unwrap()
|
||||||
_element: &::Element,
|
.downcast::<Self>()
|
||||||
buffer: ::Buffer,
|
.unwrap()
|
||||||
) -> Result<::FlowSuccess, ::FlowError> {
|
|
||||||
self.n_buffers.fetch_add(1, atomic::Ordering::SeqCst);
|
|
||||||
self.srcpad.push(buffer)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sink_event(&self, _pad: &::Pad, _element: &::Element, event: ::Event) -> bool {
|
|
||||||
self.srcpad.push_event(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sink_query(&self, _pad: &::Pad, _element: &::Element, query: &mut ::QueryRef) -> bool {
|
|
||||||
self.srcpad.peer_query(query)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn src_event(&self, _pad: &::Pad, _element: &::Element, event: ::Event) -> bool {
|
|
||||||
self.sinkpad.push_event(event)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn src_query(&self, _pad: &::Pad, _element: &::Element, query: &mut ::QueryRef) -> bool {
|
|
||||||
self.sinkpad.peer_query(query)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ObjectSubclass for TestElement {
|
|
||||||
const NAME: &'static str = "TestElement";
|
|
||||||
type ParentType = ::Element;
|
|
||||||
type Instance = ::subclass::ElementInstanceStruct<Self>;
|
|
||||||
type Class = subclass::simple::ClassStruct<Self>;
|
|
||||||
|
|
||||||
glib_object_subclass!();
|
|
||||||
|
|
||||||
fn with_class(klass: &subclass::simple::ClassStruct<Self>) -> Self {
|
|
||||||
let templ = klass.get_pad_template("sink").unwrap();
|
|
||||||
let sinkpad = ::Pad::builder_with_template(&templ, Some("sink"))
|
|
||||||
.chain_function(|pad, parent, buffer| {
|
|
||||||
TestElement::catch_panic_pad_function(
|
|
||||||
parent,
|
|
||||||
|| Err(::FlowError::Error),
|
|
||||||
|identity, element| identity.sink_chain(pad, element, buffer),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.event_function(|pad, parent, event| {
|
|
||||||
TestElement::catch_panic_pad_function(
|
|
||||||
parent,
|
|
||||||
|| false,
|
|
||||||
|identity, element| identity.sink_event(pad, element, event),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.query_function(|pad, parent, query| {
|
|
||||||
TestElement::catch_panic_pad_function(
|
|
||||||
parent,
|
|
||||||
|| false,
|
|
||||||
|identity, element| identity.sink_query(pad, element, query),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.build();
|
|
||||||
|
|
||||||
let templ = klass.get_pad_template("src").unwrap();
|
|
||||||
let srcpad = ::Pad::builder_with_template(&templ, Some("src"))
|
|
||||||
.event_function(|pad, parent, event| {
|
|
||||||
TestElement::catch_panic_pad_function(
|
|
||||||
parent,
|
|
||||||
|| false,
|
|
||||||
|identity, element| identity.src_event(pad, element, event),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.query_function(|pad, parent, query| {
|
|
||||||
TestElement::catch_panic_pad_function(
|
|
||||||
parent,
|
|
||||||
|| false,
|
|
||||||
|identity, element| identity.src_query(pad, element, query),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.build();
|
|
||||||
|
|
||||||
Self {
|
|
||||||
n_buffers: atomic::AtomicU32::new(0),
|
|
||||||
reached_playing: atomic::AtomicBool::new(false),
|
|
||||||
srcpad,
|
|
||||||
sinkpad,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn class_init(klass: &mut subclass::simple::ClassStruct<Self>) {
|
|
||||||
klass.set_metadata(
|
|
||||||
"Test Element",
|
|
||||||
"Generic",
|
|
||||||
"Does nothing",
|
|
||||||
"Sebastian Dröge <sebastian@centricular.com>",
|
|
||||||
);
|
|
||||||
|
|
||||||
let caps = ::Caps::new_any();
|
|
||||||
let src_pad_template =
|
|
||||||
::PadTemplate::new("src", ::PadDirection::Src, ::PadPresence::Always, &caps)
|
|
||||||
.unwrap();
|
|
||||||
klass.add_pad_template(src_pad_template);
|
|
||||||
|
|
||||||
let sink_pad_template =
|
|
||||||
::PadTemplate::new("sink", ::PadDirection::Sink, ::PadPresence::Always, &caps)
|
|
||||||
.unwrap();
|
|
||||||
klass.add_pad_template(sink_pad_template);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ObjectImpl for TestElement {
|
|
||||||
fn constructed(&self, obj: &glib::Object) {
|
|
||||||
self.parent_constructed(obj);
|
|
||||||
|
|
||||||
let element = obj.downcast_ref::<::Element>().unwrap();
|
|
||||||
element.add_pad(&self.sinkpad).unwrap();
|
|
||||||
element.add_pad(&self.srcpad).unwrap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ElementImpl for TestElement {
|
|
||||||
fn change_state(
|
|
||||||
&self,
|
|
||||||
element: &::Element,
|
|
||||||
transition: ::StateChange,
|
|
||||||
) -> Result<::StateChangeSuccess, ::StateChangeError> {
|
|
||||||
let res = self.parent_change_state(element, transition)?;
|
|
||||||
|
|
||||||
if transition == ::StateChange::PausedToPlaying {
|
|
||||||
self.reached_playing.store(true, atomic::Ordering::SeqCst);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(res)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -695,10 +725,7 @@ mod tests {
|
||||||
fn test_element_subclass() {
|
fn test_element_subclass() {
|
||||||
::init().unwrap();
|
::init().unwrap();
|
||||||
|
|
||||||
let element = glib::Object::new(TestElement::get_type(), &[("name", &"test")])
|
let element = TestElement::new(Some("test"));
|
||||||
.unwrap()
|
|
||||||
.downcast::<::Element>()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(element.get_name(), "test");
|
assert_eq!(element.get_name(), "test");
|
||||||
|
|
||||||
|
@ -713,8 +740,10 @@ mod tests {
|
||||||
|
|
||||||
src.set_property("num-buffers", &100i32).unwrap();
|
src.set_property("num-buffers", &100i32).unwrap();
|
||||||
|
|
||||||
pipeline.add_many(&[&src, &element, &sink]).unwrap();
|
pipeline
|
||||||
::Element::link_many(&[&src, &element, &sink]).unwrap();
|
.add_many(&[&src, &element.upcast_ref(), &sink])
|
||||||
|
.unwrap();
|
||||||
|
::Element::link_many(&[&src, &element.upcast_ref(), &sink]).unwrap();
|
||||||
|
|
||||||
pipeline.set_state(::State::Playing).unwrap();
|
pipeline.set_state(::State::Playing).unwrap();
|
||||||
let bus = pipeline.get_bus().unwrap();
|
let bus = pipeline.get_bus().unwrap();
|
||||||
|
@ -724,7 +753,7 @@ mod tests {
|
||||||
|
|
||||||
pipeline.set_state(::State::Null).unwrap();
|
pipeline.set_state(::State::Null).unwrap();
|
||||||
|
|
||||||
let imp = TestElement::from_instance(&element);
|
let imp = imp::TestElement::from_instance(&element);
|
||||||
assert_eq!(imp.n_buffers.load(atomic::Ordering::SeqCst), 100);
|
assert_eq!(imp.n_buffers.load(atomic::Ordering::SeqCst), 100);
|
||||||
assert_eq!(imp.reached_playing.load(atomic::Ordering::SeqCst), true);
|
assert_eq!(imp.reached_playing.load(atomic::Ordering::SeqCst), true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,38 +93,62 @@ mod tests {
|
||||||
use glib::subclass;
|
use glib::subclass;
|
||||||
use std::sync::atomic;
|
use std::sync::atomic;
|
||||||
|
|
||||||
struct TestPad {
|
pub mod imp {
|
||||||
linked: atomic::AtomicBool,
|
use super::*;
|
||||||
unlinked: atomic::AtomicBool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ObjectSubclass for TestPad {
|
pub struct TestPad {
|
||||||
const NAME: &'static str = "TestPad";
|
pub(super) linked: atomic::AtomicBool,
|
||||||
type ParentType = ::Pad;
|
pub(super) unlinked: atomic::AtomicBool,
|
||||||
type Instance = subclass::simple::InstanceStruct<Self>;
|
}
|
||||||
type Class = subclass::simple::ClassStruct<Self>;
|
|
||||||
|
|
||||||
glib_object_subclass!();
|
impl ObjectSubclass for TestPad {
|
||||||
|
const NAME: &'static str = "TestPad";
|
||||||
|
type Type = super::TestPad;
|
||||||
|
type ParentType = ::Pad;
|
||||||
|
type Instance = subclass::simple::InstanceStruct<Self>;
|
||||||
|
type Class = subclass::simple::ClassStruct<Self>;
|
||||||
|
|
||||||
fn new() -> Self {
|
glib_object_subclass!();
|
||||||
Self {
|
|
||||||
linked: atomic::AtomicBool::new(false),
|
fn new() -> Self {
|
||||||
unlinked: atomic::AtomicBool::new(false),
|
Self {
|
||||||
|
linked: atomic::AtomicBool::new(false),
|
||||||
|
unlinked: atomic::AtomicBool::new(false),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ObjectImpl for TestPad {}
|
||||||
|
|
||||||
|
impl PadImpl for TestPad {
|
||||||
|
fn linked(&self, pad: &Pad, peer: &Pad) {
|
||||||
|
self.linked.store(true, atomic::Ordering::SeqCst);
|
||||||
|
self.parent_linked(pad, peer)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unlinked(&self, pad: &Pad, peer: &Pad) {
|
||||||
|
self.unlinked.store(true, atomic::Ordering::SeqCst);
|
||||||
|
self.parent_unlinked(pad, peer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectImpl for TestPad {}
|
glib_wrapper! {
|
||||||
|
pub struct TestPad(ObjectSubclass<imp::TestPad>) @extends ::Pad, ::Object;
|
||||||
|
}
|
||||||
|
|
||||||
impl PadImpl for TestPad {
|
unsafe impl Send for TestPad {}
|
||||||
fn linked(&self, pad: &Pad, peer: &Pad) {
|
unsafe impl Sync for TestPad {}
|
||||||
self.linked.store(true, atomic::Ordering::SeqCst);
|
|
||||||
self.parent_linked(pad, peer)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unlinked(&self, pad: &Pad, peer: &Pad) {
|
impl TestPad {
|
||||||
self.unlinked.store(true, atomic::Ordering::SeqCst);
|
pub fn new(name: &str, direction: ::PadDirection) -> Self {
|
||||||
self.parent_unlinked(pad, peer)
|
glib::Object::new(
|
||||||
|
TestPad::static_type(),
|
||||||
|
&[("name", &name), ("direction", &direction)],
|
||||||
|
)
|
||||||
|
.unwrap()
|
||||||
|
.downcast::<Self>()
|
||||||
|
.unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,13 +156,7 @@ mod tests {
|
||||||
fn test_pad_subclass() {
|
fn test_pad_subclass() {
|
||||||
::init().unwrap();
|
::init().unwrap();
|
||||||
|
|
||||||
let pad = glib::Object::new(
|
let pad = TestPad::new("test", ::PadDirection::Src);
|
||||||
TestPad::get_type(),
|
|
||||||
&[("name", &"test"), ("direction", &::PadDirection::Src)],
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
.downcast::<::Pad>()
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_eq!(pad.get_name(), "test");
|
assert_eq!(pad.get_name(), "test");
|
||||||
|
|
||||||
|
@ -146,7 +164,7 @@ mod tests {
|
||||||
pad.link(&otherpad).unwrap();
|
pad.link(&otherpad).unwrap();
|
||||||
pad.unlink(&otherpad).unwrap();
|
pad.unlink(&otherpad).unwrap();
|
||||||
|
|
||||||
let imp = TestPad::from_instance(&pad);
|
let imp = imp::TestPad::from_instance(&pad);
|
||||||
assert!(imp.linked.load(atomic::Ordering::SeqCst));
|
assert!(imp.linked.load(atomic::Ordering::SeqCst));
|
||||||
assert!(imp.unlinked.load(atomic::Ordering::SeqCst));
|
assert!(imp.unlinked.load(atomic::Ordering::SeqCst));
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue