Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix deref #106

Draft
wants to merge 5 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions atom/src/port.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,23 @@ impl PortType for AtomPort {
type OutputPortType = PortWriter<'static>;

#[inline]
unsafe fn input_from_raw(pointer: NonNull<c_void>, _sample_count: u32) -> PortReader<'static> {
let header = AtomHeader::from_raw(pointer.cast().as_ref());
PortReader::new(UnidentifiedAtom::from_header(header))
unsafe fn input_from_raw(
pointer: NonNull<c_void>,
_sample_count: u32,
) -> *const PortReader<'static> {
todo!();
//let header = AtomHeader::from_raw(pointer.cast().as_ref());
//PortReader::new(UnidentifiedAtom::from_header(header))
}

#[inline]
unsafe fn output_from_raw(pointer: NonNull<c_void>, _sample_count: u32) -> PortWriter<'static> {
let header = AtomHeader::from_raw_mut(pointer.cast().as_mut());
PortWriter::new(UnidentifiedAtom::from_header_mut(header).body_mut())
unsafe fn output_from_raw(
pointer: NonNull<c_void>,
_sample_count: u32,
) -> *mut PortWriter<'static> {
todo!();
//let header = AtomHeader::from_raw_mut(pointer.cast().as_mut());
//PortWriter::new(UnidentifiedAtom::from_header_mut(header).body_mut())
}
}

Expand Down
3 changes: 3 additions & 0 deletions core/src/feature/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ pub use cache::FeatureCache;
pub use core_features::*;
pub use descriptor::FeatureDescriptor;

#[cfg(feature = "lv2-core-derive")]
pub use lv2_core_derive::FeatureCollection;

use std::ffi::c_void;

/// All threading contexts of LV2 interface methods.
Expand Down
36 changes: 22 additions & 14 deletions core/src/port.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,14 @@ use std::ffi::c_void;
use std::ops::{Deref, DerefMut};
use std::ptr::NonNull;

#[cfg(feature = "lv2-core-derive")]
pub use lv2_core_derive::*;

/// Generalization of port types.
///
/// A port can read input or create a pointer to the output, but the exact type of input/output (pointer) depends on the type of port. This trait generalizes these types and behaviour.
pub trait PortType {
/// The type of input read by the port.
type InputPortType: Sized;
type InputPortType: ?Sized;
/// The type of output reference created by the port.
type OutputPortType: Sized;
type OutputPortType: ?Sized;

/// Read data from the pointer or create a reference to the input.
///
Expand All @@ -32,7 +29,10 @@ pub trait PortType {
/// # Safety
///
/// This method is unsafe because one needs to de-reference a raw pointer to implement this method.
unsafe fn input_from_raw(pointer: NonNull<c_void>, sample_count: u32) -> Self::InputPortType;
unsafe fn input_from_raw(
pointer: NonNull<c_void>,
sample_count: u32,
) -> *const Self::InputPortType;

/// Create a reference to the data where output should be written to.
///
Expand All @@ -41,7 +41,10 @@ pub trait PortType {
/// # Safety
///
/// This method is unsafe because one needs to de-reference a raw pointer to implement this method.
unsafe fn output_from_raw(pointer: NonNull<c_void>, sample_count: u32) -> Self::OutputPortType;
unsafe fn output_from_raw(
pointer: NonNull<c_void>,
sample_count: u32,
) -> *mut Self::OutputPortType;
}

/// Abstraction of safe port handles.
Expand All @@ -60,19 +63,22 @@ pub trait PortHandle: Sized {
///
/// Fields of this type can be dereferenced to the input type of the port type.
pub struct InputPort<T: PortType> {
port: T::InputPortType,
port: *const T::InputPortType,
}

impl<T: PortType> Deref for InputPort<T> {
type Target = T::InputPortType;

#[inline]
fn deref(&self) -> &Self::Target {
&self.port
unsafe { &*self.port }
}
}

impl<T: PortType> PortHandle for InputPort<T> {
impl<T> PortHandle for InputPort<T>
where
T: PortType,
{
#[inline]
unsafe fn from_raw(pointer: *mut c_void, sample_count: u32) -> Option<Self> {
Some(Self {
Expand All @@ -85,22 +91,22 @@ impl<T: PortType> PortHandle for InputPort<T> {
///
/// Fields of this type can be dereferenced to the output type of the port type.
pub struct OutputPort<T: PortType> {
port: T::OutputPortType,
port: *mut T::OutputPortType,
}

impl<T: PortType> Deref for OutputPort<T> {
type Target = T::OutputPortType;

#[inline]
fn deref(&self) -> &Self::Target {
&self.port
unsafe { &*self.port }
}
}

impl<T: PortType> DerefMut for OutputPort<T> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.port
unsafe { &mut *self.port }
}
}

Expand All @@ -126,7 +132,8 @@ impl<T: PortHandle> PortHandle for Option<T> {
/// # Implementing
///
/// The most convenient way to create a port collections is to define a struct with port types from the [`port`](index.html) module and then simply derive `PortCollection` for it. An example:
///
/// ```
/// # pub use lv2_core_derive::*;
/// use lv2_core::port::*;
///
/// #[derive(PortCollection)]
Expand All @@ -137,6 +144,7 @@ impl<T: PortHandle> PortHandle for Option<T> {
/// control_output: OutputPort<Control>,
/// optional_control_input: Option<InputPort<Control>>,
/// }
/// ```
///
/// Please note that port indices are mapped in the order of occurrence; In our example, the implementation will treat `audio_input` as port `0`, `audio_output` as port `1` and so on. Therefore, your plugin definition and your port collection have to match. Otherwise, undefined behaviour will occur.
pub trait PortCollection: Sized {
Expand Down
40 changes: 27 additions & 13 deletions core/src/port/audio.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,22 @@ unsafe impl UriBound for Audio {
}

impl PortType for Audio {
type InputPortType = &'static [f32];
type OutputPortType = &'static mut [f32];
type InputPortType = [f32];
type OutputPortType = [f32];

#[inline]
unsafe fn input_from_raw(pointer: NonNull<c_void>, sample_count: u32) -> Self::InputPortType {
unsafe fn input_from_raw(
pointer: NonNull<c_void>,
sample_count: u32,
) -> *const 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 {
unsafe fn output_from_raw(
pointer: NonNull<c_void>,
sample_count: u32,
) -> *mut Self::OutputPortType {
std::slice::from_raw_parts_mut(pointer.as_ptr() as *mut f32, sample_count as usize)
}
}
Expand Down Expand Up @@ -132,11 +138,15 @@ unsafe impl UriBound for InPlaceAudio {
}

impl PortType for InPlaceAudio {
type InputPortType = &'static [Cell<f32>];
type OutputPortType = &'static [Cell<f32>];
type InputPortType = [Cell<f32>];
type OutputPortType = [Cell<f32>];

#[inline]
unsafe fn input_from_raw(pointer: NonNull<c_void>, sample_count: u32) -> Self::InputPortType {
unsafe fn input_from_raw(
pointer: NonNull<c_void>,
sample_count: u32,
) -> *const Self::InputPortType {
//std::slice::from_raw_parts(pointer.as_ptr() as *const Cell<f32>, sample_count as usize)
Cell::from_mut(std::slice::from_raw_parts_mut(
pointer.as_ptr() as *mut f32,
sample_count as usize,
Expand All @@ -145,11 +155,15 @@ impl PortType for InPlaceAudio {
}

#[inline]
unsafe fn output_from_raw(pointer: NonNull<c_void>, sample_count: u32) -> Self::OutputPortType {
Cell::from_mut(std::slice::from_raw_parts_mut(
pointer.as_ptr() as *mut f32,
sample_count as usize,
))
.as_slice_of_cells()
unsafe fn output_from_raw(
pointer: NonNull<c_void>,
sample_count: u32,
) -> *mut Self::OutputPortType {
std::slice::from_raw_parts_mut(pointer.as_ptr() as *mut Cell<f32>, sample_count as usize)
//Cell::from_mut(std::slice::from_raw_parts_mut(
// pointer.as_ptr() as *mut f32,
// sample_count as usize,
//))
//.as_slice_of_cells()
}
}
25 changes: 14 additions & 11 deletions core/src/port/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,16 @@ unsafe impl UriBound for Control {

impl PortType for Control {
type InputPortType = f32;
type OutputPortType = &'static mut f32;
type OutputPortType = f32;

#[inline]
unsafe fn input_from_raw(pointer: NonNull<c_void>, _sample_count: u32) -> f32 {
*(pointer.cast().as_ref())
unsafe fn input_from_raw(pointer: NonNull<c_void>, _sample_count: u32) -> *const f32 {
pointer.as_ptr() as *const f32
}

#[inline]
unsafe fn output_from_raw(pointer: NonNull<c_void>, _sample_count: u32) -> &'static mut f32 {
(pointer.as_ptr() as *mut f32).as_mut().unwrap()
unsafe fn output_from_raw(pointer: NonNull<c_void>, _sample_count: u32) -> *mut f32 {
pointer.as_ptr() as *mut f32
}
}

Expand Down Expand Up @@ -130,19 +130,22 @@ unsafe impl UriBound for InPlaceControl {
}

impl PortType for InPlaceControl {
type InputPortType = &'static Cell<f32>;
type OutputPortType = &'static Cell<f32>;
type InputPortType = Cell<f32>;
type OutputPortType = Cell<f32>;

#[inline]
unsafe fn input_from_raw(pointer: NonNull<c_void>, _sample_count: u32) -> Self::InputPortType {
Cell::from_mut(&mut *(pointer.as_ptr() as *mut f32))
unsafe fn input_from_raw(
pointer: NonNull<c_void>,
_sample_count: u32,
) -> *const Self::InputPortType {
pointer.as_ptr() as _
}

#[inline]
unsafe fn output_from_raw(
pointer: NonNull<c_void>,
_sample_count: u32,
) -> Self::OutputPortType {
Cell::from_mut(&mut *(pointer.as_ptr() as *mut f32))
) -> *mut Self::OutputPortType {
pointer.as_ptr() as _
}
}
40 changes: 22 additions & 18 deletions core/src/port/cv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,22 @@ unsafe impl UriBound for CV {
}

impl PortType for CV {
type InputPortType = &'static [f32];
type OutputPortType = &'static mut [f32];
type InputPortType = [f32];
type OutputPortType = [f32];

#[inline]
unsafe fn input_from_raw(pointer: NonNull<c_void>, sample_count: u32) -> Self::InputPortType {
unsafe fn input_from_raw(
pointer: NonNull<c_void>,
sample_count: u32,
) -> *const 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 {
unsafe fn output_from_raw(
pointer: NonNull<c_void>,
sample_count: u32,
) -> *mut Self::OutputPortType {
std::slice::from_raw_parts_mut(pointer.as_ptr() as *mut f32, sample_count as usize)
}
}
Expand Down Expand Up @@ -158,24 +164,22 @@ unsafe impl UriBound for InPlaceCV {
}

impl PortType for InPlaceCV {
type InputPortType = &'static [Cell<f32>];
type OutputPortType = &'static [Cell<f32>];
type InputPortType = [Cell<f32>];
type OutputPortType = [Cell<f32>];

#[inline]
unsafe fn input_from_raw(pointer: NonNull<c_void>, sample_count: u32) -> Self::InputPortType {
Cell::from_mut(std::slice::from_raw_parts_mut(
pointer.as_ptr() as *mut f32,
sample_count as usize,
))
.as_slice_of_cells()
unsafe fn input_from_raw(
pointer: NonNull<c_void>,
sample_count: u32,
) -> *const Self::InputPortType {
std::slice::from_raw_parts(pointer.as_ptr() as *const Cell<f32>, sample_count as usize)
}

#[inline]
unsafe fn output_from_raw(pointer: NonNull<c_void>, sample_count: u32) -> Self::OutputPortType {
Cell::from_mut(std::slice::from_raw_parts_mut(
pointer.as_ptr() as *mut f32,
sample_count as usize,
))
.as_slice_of_cells()
unsafe fn output_from_raw(
pointer: NonNull<c_void>,
sample_count: u32,
) -> *mut Self::OutputPortType {
std::slice::from_raw_parts_mut(pointer.as_ptr() as *mut Cell<f32>, sample_count as usize)
}
}