feat: Restructure the gst parent<->child relations
This commit is contained in:
97
gst/src/wrapper.rs
Normal file
97
gst/src/wrapper.rs
Normal file
@@ -0,0 +1,97 @@
|
||||
pub trait GstWrapper {
|
||||
type GstType: glib::prelude::ObjectType;
|
||||
fn from_gst(gst: Self::GstType) -> Self;
|
||||
fn into_gst(self) -> Self::GstType;
|
||||
fn as_gst_ref(&self) -> &Self::GstType;
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! wrap_gst {
|
||||
($name:ident) => {
|
||||
wrap_gst!($name, gstreamer::$name);
|
||||
};
|
||||
($name:ident, $inner:ty) => {
|
||||
#[derive(Debug, Clone)]
|
||||
#[repr(transparent)]
|
||||
pub struct $name {
|
||||
pub(crate) inner: $inner,
|
||||
}
|
||||
|
||||
impl From<$inner> for $name {
|
||||
fn from(inner: $inner) -> Self {
|
||||
Self { inner }
|
||||
}
|
||||
}
|
||||
impl From<$name> for $inner {
|
||||
fn from(wrapper: $name) -> Self {
|
||||
wrapper.into_inner()
|
||||
}
|
||||
}
|
||||
|
||||
impl $name {
|
||||
pub fn into_inner(self) -> $inner {
|
||||
self.inner.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl $crate::wrapper::GstWrapper for $name {
|
||||
type GstType = $inner;
|
||||
|
||||
fn from_gst(gst: Self::GstType) -> Self {
|
||||
Self { inner: gst }
|
||||
}
|
||||
|
||||
fn into_gst(self) -> Self::GstType {
|
||||
self.inner.clone()
|
||||
}
|
||||
|
||||
fn as_gst_ref(&self) -> &Self::GstType {
|
||||
&self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl ChildOf<$name> for $name {
|
||||
fn upcast_ref(&self) -> &$name {
|
||||
self
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// A trait for types that can be upcasted to type T.
|
||||
pub trait ChildOf<T> {
|
||||
fn upcast_ref(&self) -> &T;
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! parent_child {
|
||||
($parent:ty, $child:ty) => {
|
||||
impl ChildOf<$parent> for $child
|
||||
where
|
||||
$child: GstWrapper,
|
||||
$parent: GstWrapper,
|
||||
{
|
||||
fn upcast_ref(&self) -> &$parent {
|
||||
let upcasted = self.inner.upcast_ref::<<$parent as GstWrapper>::GstType>();
|
||||
unsafe { &*(upcasted as *const <$parent as GstWrapper>::GstType as *const $parent) }
|
||||
}
|
||||
}
|
||||
};
|
||||
($parent:ty, $child:ty, downcast) => {
|
||||
impl ChildOf<$parent> for $child
|
||||
where
|
||||
$child: GstWrapper,
|
||||
$parent: GstWrapper,
|
||||
{
|
||||
fn upcast_ref(&self) -> &$parent {
|
||||
let downcasted = self
|
||||
.inner
|
||||
.downcast_ref::<<$parent as GstWrapper>::GstType>()
|
||||
.expect("BUG: Failed to downcast GStreamer type from child to parent");
|
||||
unsafe {
|
||||
&*(downcasted as *const <$parent as GstWrapper>::GstType as *const $parent)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user