Expand description
Traits and associated utilities to handle and implement CLAP extensions.
These traits are designed to be used for implementing custom or unsupported extensions.
If you want to use an existing extension in your plugin, see the clack_extensions
crate instead.
§Example
This example shows a basic implementation for the plugin side of the CLAP State extension.
The implementation wrapper leverages the PluginWrapper
utility to handle things like error management and unwind safety. See its documentation for more
information.
use std::ffi::CStr;
use clap_sys::ext::state::{CLAP_EXT_STATE, clap_plugin_state};
use clack_plugin::extensions::prelude::*;
// The struct end-users will actually interact with.
#[derive(Copy, Clone)]
pub struct PluginState(RawExtension<PluginExtensionSide, clap_plugin_state>);
unsafe impl Extension for PluginState {
const IDENTIFIERS: &[&CStr] = &[CLAP_EXT_STATE];
type ExtensionSide = PluginExtensionSide;
#[inline]
unsafe fn from_raw(raw: RawExtension<Self::ExtensionSide>) -> Self {
Self(raw.cast())
}
}
// For implementors of the extensions (here, on the plugin side):
// first define a trait the extension has to implement
use clack_common::stream::{InputStream, OutputStream};
use clack_plugin::plugin::{Plugin, PluginError};
pub trait PluginStateImplementation {
fn load(&self, input: &mut InputStream) -> Result<(), PluginError>;
}
// Then, implement the ExtensionImplementation trait for the given implementors
// to provide the C FFI-compatible struct.
// SAFETY: The given struct is the CLAP extension struct for the matching side of this extension.
unsafe impl<P: Plugin> ExtensionImplementation<P> for PluginState
where
// In this case, all the CLAP State methods belong to the main thread.
// Other extensions may have other requirements, possibly split between multiple threads.
for<'a> P::MainThread<'a>: PluginStateImplementation,
{
const IMPLEMENTATION: RawExtensionImplementation =
RawExtensionImplementation::new(&clap_plugin_state {
// For the sake of this example, we are only implementing the load() method.
load: Some(load::<P>),
});
}
// Finally, implement the C FFI functions that will be exposed to the host.
use clap_sys::stream::clap_istream;
unsafe extern "C" fn load<P: Plugin>(
plugin: *const clap_plugin,
stream: *const clap_istream,
) -> bool
where
for<'a> P::MainThread<'a>: PluginStateImplementation,
{
PluginWrapper::<P>::handle(plugin, |p| {
let input = InputStream::from_raw_mut(&mut *(stream as *mut _));
// Retrieve the plugin's main thread struct, and call load() on it
p.main_thread().load(input)?;
Ok(())
})
.is_some()
}Modules§
- prelude
- A prelude which re-exports all the types and traits used for custom extension implementation.
- wrapper
- Utilities to manipulate Plugin instances from an FFI context.
Structs§
- Host
Extension Side - A marker struct that represents extensions to be implemented by the host side.
- Plugin
Extension Side - A marker struct that represents extensions to be implemented by the plugin side.
- Plugin
Extensions - A collection of all extensions supported for a given plugin type
P. - RawExtension
- A raw extension pointer.
- RawExtension
Implementation - A pointer to an extension’s implementation struct.
Traits§
- Extension
- A type representing a CLAP extension pointer.
- Extension
Implementation - Provides an implementation of this extension for a given type
I(typically either a host or plugin structure). - Extension
Side - An extension side marker: either
PluginExtensionSideorHostExtensionSide.