[−][src]Crate lv2_worker
Work scheduling library that allows real-time capable LV2 plugins to execute non-real-time actions.
This crate allows plugins to schedule work that must be performed in another thread. Plugins can use this interface to safely perform work that is not real-time safe, and receive the result in the run context. A typical use case is a sampler reading and caching data from disk. You can look at the LV2 Worker Specification for more details.
Example
use std::any::Any; use lv2_core::feature::*; use lv2_core::prelude::*; use urid::*; use lv2_worker::*; #[derive(PortCollection)] struct Ports {} /// Requested features #[derive(FeatureCollection)] struct AudioFeatures<'a> { ///host feature allowing to schedule some work schedule: Schedule<'a, EgWorker>, } //custom datatype struct WorkMessage { cycle: usize, task: usize, } /// A plugin that do some work in another thread struct EgWorker { // The schedule handler needs to know the plugin type in order to access the `WorkData` type. cycle: usize, end_cycle: usize, } /// URI identifier unsafe impl UriBound for EgWorker { const URI: &'static [u8] = b"urn:rust-lv2-more-examples:eg-worker-rs\0"; } impl Plugin for EgWorker { type Ports = Ports; type InitFeatures = (); type AudioFeatures = AudioFeatures<'static>; fn new(_plugin_info: &PluginInfo, _features: &mut Self::InitFeatures) -> Option<Self> { Some(Self { cycle: 0, end_cycle: 1, }) } fn run(&mut self, _ports: &mut Ports, features: &mut Self::AudioFeatures) { self.cycle += 1; let cycle = self.cycle; println!("cycle {} started", cycle); for task in 0..10 { let work = WorkMessage { cycle, task }; // schedule some work, passing some data and check for error if let Err(e) = features.schedule.schedule_work(work) { eprintln!("Can't schedule work: {}", e); } } } fn extension_data(uri: &Uri) -> Option<&'static dyn Any> { match_extensions![uri, WorkerDescriptor<Self>] } } /// Implementing the extension. impl Worker for EgWorker { // data type sent by the schedule handler and received by the `work` method. type WorkData = WorkMessage; // data type sent by the response handler and received by the `work_response` method. type ResponseData = String; fn work( //response handler need to know the plugin type. response_handler: &ResponseHandler<Self>, data: Self::WorkData, ) -> Result<(), WorkerError> { println!("work received: cycle {}, task {}", data.cycle, data.task); if data.task >= 5 { if let Err(e) = response_handler.respond(format!( "response to cycle {}, task {}", data.cycle, data.task )) { eprintln!("Can't respond: {}", e); } }; Ok(()) } fn work_response( &mut self, data: Self::ResponseData, _features: &mut Self::AudioFeatures, ) -> Result<(), WorkerError> { println!("work_response received: {}", data); Ok(()) } fn end_run(&mut self, _features: &mut Self::AudioFeatures) -> Result<(), WorkerError> { println!("cycle {} ended", self.end_cycle); self.end_cycle += 1; Ok(()) } }
Structs
ResponseHandler | Handler available inside the worker function to send a response to the |
Schedule | Host feature providing data to build a ScheduleHandler. |
WorkerDescriptor | Raw wrapper of the |
Enums
RespondError | Errors potentially generated by the
|
ScheduleError | Errors potentially generated by the
|
WorkerError | Errors potentially generated by |
Traits
Worker | The non-realtime working extension for plugins. |