feat: Restructure the gst parent<->child relations

This commit is contained in:
uttarayan21
2025-12-23 01:09:01 +05:30
parent 043d1e99f0
commit 8d46bd2b85
11 changed files with 274 additions and 343 deletions

97
gst/src/wrapper.rs Normal file
View 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)
}
}
}
};
}