use std::ffi::c_void;
use std::ops::{Deref, DerefMut};
use std::ptr::NonNull;
use urid::UriBound;
pub use lv2_core_derive::*;
pub trait PortType {
type InputPortType: Sized;
type OutputPortType: Sized;
unsafe fn input_from_raw(pointer: NonNull<c_void>, sample_count: u32) -> Self::InputPortType;
unsafe fn output_from_raw(pointer: NonNull<c_void>, sample_count: u32) -> Self::OutputPortType;
}
pub struct Audio;
unsafe impl UriBound for Audio {
const URI: &'static [u8] = ::lv2_sys::LV2_CORE__AudioPort;
}
impl PortType for Audio {
type InputPortType = &'static [f32];
type OutputPortType = &'static mut [f32];
#[inline]
unsafe fn input_from_raw(pointer: NonNull<c_void>, sample_count: u32) -> Self::InputPortType {
std::slice::from_raw_parts(pointer.as_ptr() as *const f32, sample_count as usize)
}
#[inline]
unsafe fn output_from_raw(pointer: NonNull<c_void>, sample_count: u32) -> Self::OutputPortType {
std::slice::from_raw_parts_mut(pointer.as_ptr() as *mut f32, sample_count as usize)
}
}
pub struct Control;
unsafe impl UriBound for Control {
const URI: &'static [u8] = ::lv2_sys::LV2_CORE__ControlPort;
}
impl PortType for Control {
type InputPortType = f32;
type OutputPortType = &'static mut f32;
#[inline]
unsafe fn input_from_raw(pointer: NonNull<c_void>, _sample_count: u32) -> f32 {
*(pointer.cast().as_ref())
}
unsafe fn output_from_raw(pointer: NonNull<c_void>, _sample_count: u32) -> &'static mut f32 {
(pointer.as_ptr() as *mut f32).as_mut().unwrap()
}
}
pub struct CV;
unsafe impl UriBound for CV {
const URI: &'static [u8] = ::lv2_sys::LV2_CORE__CVPort;
}
impl PortType for CV {
type InputPortType = &'static [f32];
type OutputPortType = &'static mut [f32];
#[inline]
unsafe fn input_from_raw(pointer: NonNull<c_void>, sample_count: u32) -> Self::InputPortType {
std::slice::from_raw_parts(pointer.as_ptr() as *const f32, sample_count as usize)
}
#[inline]
unsafe fn output_from_raw(pointer: NonNull<c_void>, sample_count: u32) -> Self::OutputPortType {
std::slice::from_raw_parts_mut(pointer.as_ptr() as *mut f32, sample_count as usize)
}
}
pub trait PortHandle: Sized {
unsafe fn from_raw(pointer: *mut c_void, sample_count: u32) -> Option<Self>;
}
pub struct InputPort<T: PortType> {
port: T::InputPortType,
}
impl<T: PortType> Deref for InputPort<T> {
type Target = T::InputPortType;
#[inline]
fn deref(&self) -> &Self::Target {
&self.port
}
}
impl<T: PortType> PortHandle for InputPort<T> {
#[inline]
unsafe fn from_raw(pointer: *mut c_void, sample_count: u32) -> Option<Self> {
if let Some(pointer) = NonNull::new(pointer) {
Some(Self {
port: T::input_from_raw(pointer, sample_count),
})
} else {
None
}
}
}
pub struct OutputPort<T: PortType> {
port: T::OutputPortType,
}
impl<T: PortType> Deref for OutputPort<T> {
type Target = T::OutputPortType;
#[inline]
fn deref(&self) -> &Self::Target {
&self.port
}
}
impl<T: PortType> DerefMut for OutputPort<T> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.port
}
}
impl<T: PortType> PortHandle for OutputPort<T> {
#[inline]
unsafe fn from_raw(pointer: *mut c_void, sample_count: u32) -> Option<Self> {
if let Some(pointer) = NonNull::new(pointer) {
Some(Self {
port: T::output_from_raw(pointer, sample_count),
})
} else {
None
}
}
}
impl<T: PortHandle> PortHandle for Option<T> {
unsafe fn from_raw(pointer: *mut c_void, sample_count: u32) -> Option<Self> {
Some(T::from_raw(pointer, sample_count))
}
}
pub trait PortCollection: Sized {
type Cache: PortPointerCache;
unsafe fn from_connections(cache: &Self::Cache, sample_count: u32) -> Option<Self>;
}
impl PortCollection for () {
type Cache = ();
unsafe fn from_connections(_cache: &(), _sample_count: u32) -> Option<Self> {
Some(())
}
}
pub trait PortPointerCache: Sized + Default {
fn connect(&mut self, index: u32, pointer: *mut c_void);
}
impl PortPointerCache for () {
fn connect(&mut self, _index: u32, _pointer: *mut c_void) {}
}