146 lines
4.3 KiB
Rust
146 lines
4.3 KiB
Rust
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;
|
|
fn from_gst_ref(gst: &Self::GstType) -> &Self;
|
|
}
|
|
|
|
#[macro_export]
|
|
macro_rules! wrap_gst {
|
|
($name:ident) => {
|
|
$crate::wrap_gst!($name, gstreamer::$name);
|
|
};
|
|
($name:ident, $inner:ty) => {
|
|
$crate::wrap_gst!(core $name, $inner);
|
|
$crate::wrap_gst!($name, $inner, into_inner);
|
|
};
|
|
($name:ident, $inner:ty, skip_inner) => {
|
|
$crate::wrap_gst!(core $name, $inner);
|
|
};
|
|
|
|
(core $name:ident, $inner:ty) => {
|
|
#[derive(Debug, Clone)]
|
|
#[repr(transparent)]
|
|
pub struct $name {
|
|
pub(crate) inner: $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
|
|
}
|
|
|
|
fn from_gst_ref(gst: &Self::GstType) -> &Self {
|
|
unsafe { &*(gst as *const Self::GstType as *const Self) }
|
|
}
|
|
}
|
|
|
|
impl ChildOf<$name> for $name {
|
|
fn upcast_ref(&self) -> &$name {
|
|
self
|
|
}
|
|
}
|
|
};
|
|
($name:ident, $inner:ty, into_inner) => {
|
|
impl From<$inner> for $name {
|
|
fn from(inner: $inner) -> Self {
|
|
Self { inner }
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
/// 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(
|
|
format!(
|
|
"BUG: Failed to downcast GStreamer type from child {} to parent {}",
|
|
stringify!($child),
|
|
stringify!($parent)
|
|
)
|
|
.as_str(),
|
|
);
|
|
unsafe {
|
|
&*(downcasted as *const <$parent as GstWrapper>::GstType as *const $parent)
|
|
}
|
|
}
|
|
}
|
|
}; // ($parent:ty, $child:ty, deref) => {
|
|
// $crate::parent_child!($parent, $child);
|
|
// $crate::parent_child!($parent, $child, __deref);
|
|
// };
|
|
//
|
|
// ($parent:ty, $child:ty, downcast, deref) => {
|
|
// $crate::parent_child!($parent, $child, downcast);
|
|
// $crate::parent_child!($parent, $child, __deref);
|
|
// };
|
|
// ($parent:ty, $child:ty, deref, downcast) => {
|
|
// $crate::parent_child!($parent, $child, downcast);
|
|
// $crate::parent_child!($parent, $child, __deref);
|
|
// };
|
|
//
|
|
// ($parent:ty, $child:ty, __deref) => {
|
|
// impl core::ops::Deref for $child
|
|
// where
|
|
// $child: GstWrapper,
|
|
// $parent: GstWrapper,
|
|
// {
|
|
// type Target = $parent;
|
|
//
|
|
// fn deref(&self) -> &Self::Target {
|
|
// self.upcast_ref()
|
|
// }
|
|
// }
|
|
// };
|
|
}
|