From a44fe9cd193a6d33dda1e17e72b0331a64a17b32 Mon Sep 17 00:00:00 2001 From: Yruama_Lairba Date: Wed, 26 Jan 2022 01:53:37 +0100 Subject: [PATCH 1/5] implement correct pointer behaviour for ports --- core/src/port.rs | 29 +++++++++++++++++++---------- core/src/port/audio.rs | 40 +++++++++++++++++++++++++++------------- core/src/port/control.rs | 25 ++++++++++++++----------- core/src/port/cv.rs | 40 ++++++++++++++++++++++------------------ 4 files changed, 82 insertions(+), 52 deletions(-) diff --git a/core/src/port.rs b/core/src/port.rs index 0c7c16e6..f3a7b04d 100644 --- a/core/src/port.rs +++ b/core/src/port.rs @@ -21,9 +21,9 @@ pub use lv2_core_derive::*; /// 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. /// @@ -32,7 +32,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, sample_count: u32) -> Self::InputPortType; + unsafe fn input_from_raw( + pointer: NonNull, + sample_count: u32, + ) -> *const Self::InputPortType; /// Create a reference to the data where output should be written to. /// @@ -41,7 +44,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, sample_count: u32) -> Self::OutputPortType; + unsafe fn output_from_raw( + pointer: NonNull, + sample_count: u32, + ) -> *mut Self::OutputPortType; } /// Abstraction of safe port handles. @@ -60,7 +66,7 @@ pub trait PortHandle: Sized { /// /// Fields of this type can be dereferenced to the input type of the port type. pub struct InputPort { - port: T::InputPortType, + port: *const T::InputPortType, } impl Deref for InputPort { @@ -68,11 +74,14 @@ impl Deref for InputPort { #[inline] fn deref(&self) -> &Self::Target { - &self.port + unsafe { &*self.port } } } -impl PortHandle for InputPort { +impl PortHandle for InputPort +where + T: PortType, +{ #[inline] unsafe fn from_raw(pointer: *mut c_void, sample_count: u32) -> Option { Some(Self { @@ -85,7 +94,7 @@ impl PortHandle for InputPort { /// /// Fields of this type can be dereferenced to the output type of the port type. pub struct OutputPort { - port: T::OutputPortType, + port: *mut T::OutputPortType, } impl Deref for OutputPort { @@ -93,14 +102,14 @@ impl Deref for OutputPort { #[inline] fn deref(&self) -> &Self::Target { - &self.port + unsafe { &*self.port } } } impl DerefMut for OutputPort { #[inline] fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.port + unsafe { &mut *self.port } } } diff --git a/core/src/port/audio.rs b/core/src/port/audio.rs index ac755e90..2f3c51c1 100644 --- a/core/src/port/audio.rs +++ b/core/src/port/audio.rs @@ -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, sample_count: u32) -> Self::InputPortType { + unsafe fn input_from_raw( + pointer: NonNull, + 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, sample_count: u32) -> Self::OutputPortType { + unsafe fn output_from_raw( + pointer: NonNull, + sample_count: u32, + ) -> *mut Self::OutputPortType { std::slice::from_raw_parts_mut(pointer.as_ptr() as *mut f32, sample_count as usize) } } @@ -132,11 +138,15 @@ unsafe impl UriBound for InPlaceAudio { } impl PortType for InPlaceAudio { - type InputPortType = &'static [Cell]; - type OutputPortType = &'static [Cell]; + type InputPortType = [Cell]; + type OutputPortType = [Cell]; #[inline] - unsafe fn input_from_raw(pointer: NonNull, sample_count: u32) -> Self::InputPortType { + unsafe fn input_from_raw( + pointer: NonNull, + sample_count: u32, + ) -> *const Self::InputPortType { + //std::slice::from_raw_parts(pointer.as_ptr() as *const Cell, sample_count as usize) Cell::from_mut(std::slice::from_raw_parts_mut( pointer.as_ptr() as *mut f32, sample_count as usize, @@ -145,11 +155,15 @@ impl PortType for InPlaceAudio { } #[inline] - unsafe fn output_from_raw(pointer: NonNull, 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, + sample_count: u32, + ) -> *mut Self::OutputPortType { + std::slice::from_raw_parts_mut(pointer.as_ptr() as *mut Cell, 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() } } diff --git a/core/src/port/control.rs b/core/src/port/control.rs index 4f9c953f..3cc378dc 100644 --- a/core/src/port/control.rs +++ b/core/src/port/control.rs @@ -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, _sample_count: u32) -> f32 { - *(pointer.cast().as_ref()) + unsafe fn input_from_raw(pointer: NonNull, _sample_count: u32) -> *const f32 { + pointer.as_ptr() as *const f32 } #[inline] - unsafe fn output_from_raw(pointer: NonNull, _sample_count: u32) -> &'static mut f32 { - (pointer.as_ptr() as *mut f32).as_mut().unwrap() + unsafe fn output_from_raw(pointer: NonNull, _sample_count: u32) -> *mut f32 { + pointer.as_ptr() as *mut f32 } } @@ -130,19 +130,22 @@ unsafe impl UriBound for InPlaceControl { } impl PortType for InPlaceControl { - type InputPortType = &'static Cell; - type OutputPortType = &'static Cell; + type InputPortType = Cell; + type OutputPortType = Cell; #[inline] - unsafe fn input_from_raw(pointer: NonNull, _sample_count: u32) -> Self::InputPortType { - Cell::from_mut(&mut *(pointer.as_ptr() as *mut f32)) + unsafe fn input_from_raw( + pointer: NonNull, + _sample_count: u32, + ) -> *const Self::InputPortType { + pointer.as_ptr() as _ } #[inline] unsafe fn output_from_raw( pointer: NonNull, _sample_count: u32, - ) -> Self::OutputPortType { - Cell::from_mut(&mut *(pointer.as_ptr() as *mut f32)) + ) -> *mut Self::OutputPortType { + pointer.as_ptr() as _ } } diff --git a/core/src/port/cv.rs b/core/src/port/cv.rs index 9455aa0c..592f3f26 100644 --- a/core/src/port/cv.rs +++ b/core/src/port/cv.rs @@ -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, sample_count: u32) -> Self::InputPortType { + unsafe fn input_from_raw( + pointer: NonNull, + 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, sample_count: u32) -> Self::OutputPortType { + unsafe fn output_from_raw( + pointer: NonNull, + sample_count: u32, + ) -> *mut Self::OutputPortType { std::slice::from_raw_parts_mut(pointer.as_ptr() as *mut f32, sample_count as usize) } } @@ -158,24 +164,22 @@ unsafe impl UriBound for InPlaceCV { } impl PortType for InPlaceCV { - type InputPortType = &'static [Cell]; - type OutputPortType = &'static [Cell]; + type InputPortType = [Cell]; + type OutputPortType = [Cell]; #[inline] - unsafe fn input_from_raw(pointer: NonNull, 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, + sample_count: u32, + ) -> *const Self::InputPortType { + std::slice::from_raw_parts(pointer.as_ptr() as *const Cell, sample_count as usize) } #[inline] - unsafe fn output_from_raw(pointer: NonNull, 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, + sample_count: u32, + ) -> *mut Self::OutputPortType { + std::slice::from_raw_parts_mut(pointer.as_ptr() as *mut Cell, sample_count as usize) } } From a8682a2098d77d6af1e6744a5852f68122cdd904 Mon Sep 17 00:00:00 2001 From: Yruama_Lairba Date: Wed, 26 Jan 2022 01:55:15 +0100 Subject: [PATCH 2/5] mark todo!() for Atom port to avoid compile error --- atom/src/port.rs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/atom/src/port.rs b/atom/src/port.rs index 155c4df4..ab70cd10 100644 --- a/atom/src/port.rs +++ b/atom/src/port.rs @@ -110,15 +110,23 @@ impl PortType for AtomPort { type OutputPortType = PortWriter<'static>; #[inline] - unsafe fn input_from_raw(pointer: NonNull, _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, + _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, _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, + _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()) } } From 8767840e715b46b6e59035449564f8f89b589ddc Mon Sep 17 00:00:00 2001 From: Yruama_Lairba Date: Sat, 5 Feb 2022 20:27:47 +0100 Subject: [PATCH 3/5] fix doc, proc macro need to be availlable only in doc --- core/src/port.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/core/src/port.rs b/core/src/port.rs index f3a7b04d..c844b968 100644 --- a/core/src/port.rs +++ b/core/src/port.rs @@ -13,9 +13,6 @@ 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. @@ -135,7 +132,8 @@ impl PortHandle for Option { /// # 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)] @@ -146,6 +144,7 @@ impl PortHandle for Option { /// control_output: OutputPort, /// optional_control_input: Option>, /// } +/// ``` /// /// 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 { From 40456395805e1b4d66ffd8d5a05a01dcbbddb69f Mon Sep 17 00:00:00 2001 From: Yruama_Lairba Date: Sat, 2 Apr 2022 15:36:34 +0200 Subject: [PATCH 4/5] Fix, re export of FeatureCollection alongside trait --- core/src/feature/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/src/feature/mod.rs b/core/src/feature/mod.rs index 3871d1eb..86fea5f2 100644 --- a/core/src/feature/mod.rs +++ b/core/src/feature/mod.rs @@ -9,6 +9,8 @@ pub use cache::FeatureCache; pub use core_features::*; pub use descriptor::FeatureDescriptor; +pub use lv2_core_derive::FeatureCollection; + use std::ffi::c_void; /// All threading contexts of LV2 interface methods. From 2e3ab00bf5a01d57a4b7814869835c474ca38d24 Mon Sep 17 00:00:00 2001 From: Yruama_Lairba Date: Sat, 2 Apr 2022 15:51:04 +0200 Subject: [PATCH 5/5] refix, conditional re export --- core/src/feature/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/feature/mod.rs b/core/src/feature/mod.rs index 86fea5f2..d001e55d 100644 --- a/core/src/feature/mod.rs +++ b/core/src/feature/mod.rs @@ -9,6 +9,7 @@ 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;