1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
//! 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`](wrapper::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 {
//! # save: Some(save),
//! // For the sake of this example, we are only implementing the load() method.
//! load: Some(load::<P>),
//! });
//! }
//! # unsafe extern "C" fn save(_: *const clap_plugin, _: *const clap_sys::stream::clap_ostream) -> bool {
//! # unimplemented!()
//! # }
//!
//! // 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()
//! }
//! ```
//!
//!
use cratePlugin;
use c_void;
use CStr;
use PhantomData;
use NonNull;
pub use *;
/// A collection of all extensions supported for a given plugin type `P`.
///
/// Plugins can declare the different extensions they support by using the
/// [`register`](PluginExtensions::register) method on this struct, during a call to
/// [`declare_extensions`](Plugin::declare_extensions).
/// A prelude which re-exports all the types and traits used for custom extension implementation.
///
/// See the [module docs](self) for more information on how to implement custom extensions in a plugin.