and now to debug some SIGSEGVs

This commit is contained in:
🪞👃🪞 2024-07-24 15:12:48 +03:00
parent 24cfbfd959
commit cb181b0d86
4 changed files with 105 additions and 18 deletions

View file

@ -10,3 +10,4 @@ bindgen = "0.69.4"
[dev-dependencies]
winit = { version = "0.30.4", features = [ "x11" ] }
livi = "0.7.4"

View file

@ -7,16 +7,11 @@ pub struct Host(*mut self::bound::SuilHost);
pub struct Instance(*mut self::bound::SuilInstance);
pub struct Controller(*mut self::bound::SuilController);
impl Host {
pub fn new () -> Self {
//let write = std::ptr::null();
//let index = std::ptr::null();
//let subscribe = std::ptr::null();
//let unsubscribe = std::ptr::null();
Self(unsafe {
bound::suil_init(&mut 0, std::ptr::null_mut(), 0);
let argv = &mut [] as *mut *mut *mut i8;
bound::suil_init(&mut 0, argv, 0);
bound::suil_host_new(
Some(Self::write),
Some(Self::index),
@ -40,9 +35,9 @@ impl Host {
fn set_touch_func (&self) {
unimplemented!();
}
fn instance (
fn instance <T> (
&self,
controller: &Controller,
controller: &mut T,
container_type_uri: &str,
plugin_uri: &str,
ui_uri: &str,
@ -60,7 +55,7 @@ impl Host {
Ok(Instance(unsafe {
bound::suil_instance_new(
self.0,
*controller.0,
controller as *mut _ as *mut std::ffi::c_void,
container_type_uri.into_raw(),
plugin_uri.into_raw(),
ui_uri.into_raw(),
@ -88,3 +83,7 @@ impl Drop for Instance {
}
}
}
unsafe impl Send for Instance {}
unsafe impl Sync for Instance {}

View file

@ -1,13 +1,26 @@
use crate::*;
use std::sync::Arc;
#[test]
fn panics () {
let host = Host::new();
self::ui::UI::run().join();
let mut plugin = plugin::LV2Plugin::new("file:///home/user/.lv2/Odin2.lv2").unwrap();
let instance = Arc::new(host.instance(
&mut plugin,
"",
"https://thewavewarden.com/odin2",
"https://thewavewarden.com/odin2#ParentUI",
"",
"",
"/home/user/.lv2/Odin2.lv2/Odin2.so",
&[],
).unwrap());
self::ui::UI::run(&instance).join();
panic!();
}
mod ui {
use std::sync::Arc;
use std::thread::{spawn, JoinHandle};
use ::winit::{
application::ApplicationHandler,
@ -16,11 +29,20 @@ mod ui {
window::{Window, WindowId},
platform::x11::EventLoopBuilderExtX11
};
pub struct UI(Option<Window>);
use crate::{Host, Instance};
pub struct UI {
host: Arc<Instance>,
window: Option<Window>
}
impl UI {
pub fn new () -> Self { Self(None) }
pub fn run () -> JoinHandle<()> {
let mut ui = Self::new();
pub fn new (host: &Arc<Instance>) -> Self {
Self {
host: host.clone(),
window: None
}
}
pub fn run (host: &Arc<Instance>) -> JoinHandle<()> {
let mut ui = Self::new(host);
spawn(move||{
let event_loop = EventLoop::builder().with_x11().with_any_thread(true).build().unwrap();
event_loop.set_control_flow(ControlFlow::Wait);
@ -30,19 +52,83 @@ mod ui {
}
impl ApplicationHandler for UI {
fn resumed (&mut self, event_loop: &ActiveEventLoop) {
self.0 = Some(event_loop.create_window(Window::default_attributes()).unwrap());
self.window = Some(event_loop.create_window(Window::default_attributes()).unwrap());
}
fn window_event (&mut self, event_loop: &ActiveEventLoop, id: WindowId, event: WindowEvent) {
match event {
WindowEvent::CloseRequested => {
self.0.as_ref().unwrap().set_visible(false);
self.window.as_ref().unwrap().set_visible(false);
event_loop.exit();
},
WindowEvent::RedrawRequested => {
self.0.as_ref().unwrap().request_redraw();
self.window.as_ref().unwrap().request_redraw();
}
_ => (),
}
}
}
}
mod plugin {
use std::thread::JoinHandle;
use std::sync::Arc;
use ::livi::{
World,
Instance,
Plugin as LiviPlugin,
Features,
FeaturesBuilder,
Port,
event::LV2AtomSequence,
};
/// A LV2 plugin.
pub struct LV2Plugin {
pub world: World,
pub instance: Instance,
pub plugin: LiviPlugin,
pub features: Arc<Features>,
pub port_list: Vec<Port>,
pub input_buffer: Vec<LV2AtomSequence>,
pub ui_thread: Option<JoinHandle<()>>,
}
impl LV2Plugin {
pub fn new (uri: &str) -> Result<Self, Box<dyn std::error::Error>> {
// Get 1st plugin at URI
let world = World::with_load_bundle(&uri);
let features = FeaturesBuilder { min_block_length: 1, max_block_length: 65536 };
let features = world.build_features(features);
let mut plugin = None;
for p in world.iter_plugins() {
plugin = Some(p);
break
}
if plugin.is_none() {
return Err(format!("plugin not found: {uri}").into())
}
let plugin = plugin.unwrap();
let err = &format!("init {uri}");
// Instantiate
Ok(Self {
world,
instance: unsafe {
plugin
.instantiate(features.clone(), 48000.0)
.expect(&err)
},
port_list: {
let mut port_list = vec![];
for port in plugin.ports() {
port_list.push(port);
}
port_list
},
plugin,
features,
input_buffer: Vec::with_capacity(1024),
ui_thread: None
})
}
}
}