Skip to content

Commit

Permalink
Renamed HostError to PluginInstanceError, HostError is now the counte…
Browse files Browse the repository at this point in the history
…rpart to PluginError instead
  • Loading branch information
prokopyl committed May 12, 2024
1 parent 82e14b0 commit a2c38e4
Show file tree
Hide file tree
Showing 9 changed files with 176 additions and 62 deletions.
18 changes: 9 additions & 9 deletions host/src/extensions/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,11 @@ impl<H: HostHandlers> HostWrapper<H> {
#[inline]
pub unsafe fn audio_processor(
&self,
) -> Result<NonNull<<H as HostHandlers>::AudioProcessor<'_>>, HostError> {
) -> Result<NonNull<<H as HostHandlers>::AudioProcessor<'_>>, PluginInstanceError> {
let ptr = self
.audio_processor
.as_ptr()
.ok_or(HostError::DeactivatedPlugin)?;
.ok_or(PluginInstanceError::DeactivatedPlugin)?;

Ok(ptr.cast())
}
Expand Down Expand Up @@ -194,15 +194,15 @@ impl<H: HostHandlers> HostWrapper<H> {
pub(crate) unsafe fn setup_audio_processor<FA>(
&self,
audio_processor: FA,
) -> Result<(), HostError>
) -> Result<(), PluginInstanceError>
where
FA: for<'a> FnOnce(
&'a <H as HostHandlers>::Shared<'a>,
&mut <H as HostHandlers>::MainThread<'a>,
) -> <H as HostHandlers>::AudioProcessor<'a>,
{
if self.audio_processor.is_some() {
return Err(HostError::AlreadyActivatedPlugin);
return Err(PluginInstanceError::AlreadyActivatedPlugin);
}

self.audio_processor.put(audio_processor(
Expand All @@ -225,10 +225,10 @@ impl<H: HostHandlers> HostWrapper<H> {
<H as HostHandlers>::AudioProcessor<'s>,
&mut <H as HostHandlers>::MainThread<'s>,
) -> T,
) -> Result<T, HostError> {
) -> Result<T, PluginInstanceError> {
// SAFETY: The user enforces that this is called and non-concurrently to any other audio-thread method.
match self.audio_processor.take() {
None => Err(HostError::DeactivatedPlugin),
None => Err(PluginInstanceError::DeactivatedPlugin),
Some(audio_processor) => Ok(drop(
audio_processor,
// SAFETY: The user enforces that this is only called on the main thread, and
Expand Down Expand Up @@ -296,7 +296,7 @@ pub enum HostWrapperError {
NullHostInstance,
NullHostData,
Panic,
HostError(HostError),
HostError(PluginInstanceError),
}

impl HostWrapperError {
Expand All @@ -321,9 +321,9 @@ impl HostWrapperError {
}
}

impl From<HostError> for HostWrapperError {
impl From<PluginInstanceError> for HostWrapperError {
#[inline]
fn from(e: HostError) -> Self {
fn from(e: PluginInstanceError) -> Self {
Self::HostError(e)
}
}
Expand Down
8 changes: 4 additions & 4 deletions host/src/factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
//! See the [`PluginFactory`]'s type documentation for more detail and examples on how to
//! list plugins.

use crate::host::HostError;
use crate::host::PluginInstanceError;
use clap_sys::factory::plugin_factory::{clap_plugin_factory, CLAP_PLUGIN_FACTORY_ID};
use clap_sys::host::clap_host;
use clap_sys::plugin::clap_plugin;
Expand Down Expand Up @@ -147,15 +147,15 @@ impl<'a> PluginFactory<'a> {
&self,
plugin_id: &CStr,
host: *const clap_host,
) -> Result<NonNull<clap_plugin>, HostError> {
) -> Result<NonNull<clap_plugin>, PluginInstanceError> {
NonNull::new((*self.inner)
.create_plugin
.ok_or(HostError::NullFactoryCreatePluginFunction)?(
.ok_or(PluginInstanceError::NullFactoryCreatePluginFunction)?(
self.inner,
host,
plugin_id.as_ptr(),
) as *mut clap_plugin)
.ok_or(HostError::PluginNotFound)
.ok_or(PluginInstanceError::PluginNotFound)
}
}

Expand Down
2 changes: 1 addition & 1 deletion host/src/host.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ mod error;
mod extensions;
mod info;

pub use error::HostError;
pub use error::{HostError, PluginInstanceError};
pub use extensions::HostExtensions;
pub use info::HostInfo;

Expand Down
82 changes: 72 additions & 10 deletions host/src/host/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ use crate::host::HostHandlers;
use crate::process::ProcessingStartError;
use clap_sys::ext::log::{clap_log_severity, CLAP_LOG_ERROR, CLAP_LOG_PLUGIN_MISBEHAVING};
use core::fmt;
use core::fmt::{Debug, Display, Formatter};
use std::error::Error;

/// All errors that can arise using plugin instances.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum HostError {
pub enum PluginInstanceError {
/// The plugin's audio processing could not be started.
StartProcessingFailed,
/// Tried to activate a plugin that was already activated.
Expand Down Expand Up @@ -47,7 +49,7 @@ pub enum HostError {
NullActivateFunction,
}

impl HostError {
impl PluginInstanceError {
pub(crate) fn msg(&self) -> &'static str {
match self {
Self::StartProcessingFailed => "Could not start processing",
Expand All @@ -74,26 +76,86 @@ impl HostError {

pub(crate) fn severity(&self) -> clap_log_severity {
match self {
HostError::MissingPluginFactory => CLAP_LOG_PLUGIN_MISBEHAVING,
HostError::NullFactoryCreatePluginFunction => CLAP_LOG_PLUGIN_MISBEHAVING,
HostError::NullProcessFunction => CLAP_LOG_PLUGIN_MISBEHAVING,
HostError::NullActivateFunction => CLAP_LOG_PLUGIN_MISBEHAVING,
PluginInstanceError::MissingPluginFactory => CLAP_LOG_PLUGIN_MISBEHAVING,
PluginInstanceError::NullFactoryCreatePluginFunction => CLAP_LOG_PLUGIN_MISBEHAVING,
PluginInstanceError::NullProcessFunction => CLAP_LOG_PLUGIN_MISBEHAVING,
PluginInstanceError::NullActivateFunction => CLAP_LOG_PLUGIN_MISBEHAVING,
_ => CLAP_LOG_ERROR,
}
}
}

impl fmt::Display for HostError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
impl Display for PluginInstanceError {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
f.write_str(self.msg())
}
}

impl std::error::Error for HostError {}
impl Error for PluginInstanceError {}

impl<H: HostHandlers> From<ProcessingStartError<H>> for HostError {
impl<H: HostHandlers> From<ProcessingStartError<H>> for PluginInstanceError {
#[inline]
fn from(_: ProcessingStartError<H>) -> Self {
Self::StartProcessingFailed
}
}

/// A generic, type-erased error type for host-originating errors.
///
/// Errors are type-erased because the CLAP API does not support extracting error information from
/// a plugin or host, only that an error happened.
///
/// Errors originating from a user-provided host callback implementation are simply logged through
/// the host's provided logging facilities if available, or the standard error output ([`stderr`])
/// if not.
///
/// This error can be constructed either from any existing [`Error`] type, or from an arbitrary
/// error message.
///
/// # Example
///
/// ```
/// use std::io;
/// use clack_host::prelude::HostError;
///
/// fn foo () -> io::Result<()> {
/// /* ... */
/// # Ok(())
/// }
///
/// fn perform(valid: bool) -> Result<(), HostError> {
/// if !valid {
/// return Err(HostError::Message("Invalid value"))
/// }
/// /* ... */
/// foo()?;
/// /* ... */
/// Ok(())
/// }
/// # perform(true).unwrap()
/// ```
///
/// [`stderr`]: std::io::stderr
#[derive(Debug)]
pub enum HostError {
/// A generic, type-erased error.
Error(Box<dyn Error + 'static>),
/// A constant string message to be displayed.
Message(&'static str),
}

impl Display for HostError {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
HostError::Error(e) => Display::fmt(&e, f),
HostError::Message(msg) => f.write_str(msg),
}
}
}

impl<E: Error + 'static> From<E> for HostError {
#[inline]
fn from(e: E) -> Self {
HostError::Error(Box::new(e))
}
}
2 changes: 1 addition & 1 deletion host/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ pub mod prelude {
},
host::{
AudioProcessorHandler, HostError, HostExtensions, HostHandlers, HostInfo,
MainThreadHandler, SharedHandler,
MainThreadHandler, PluginInstanceError, SharedHandler,
},
plugin::PluginInstance,
plugin::{
Expand Down
14 changes: 8 additions & 6 deletions host/src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ impl<H: HostHandlers> PluginInstance<H> {
bundle: &PluginBundle,
plugin_id: &CStr,
host: &HostInfo,
) -> Result<Self, HostError>
) -> Result<Self, PluginInstanceError>
where
FS: for<'b> FnOnce(&'b ()) -> <H as HostHandlers>::Shared<'b>,
FH: for<'b> FnOnce(
Expand All @@ -51,14 +51,15 @@ impl<H: HostHandlers> PluginInstance<H> {
&mut self,
audio_processor: FA,
configuration: PluginAudioConfiguration,
) -> Result<StoppedPluginAudioProcessor<H>, HostError>
) -> Result<StoppedPluginAudioProcessor<H>, PluginInstanceError>
where
FA: for<'a> FnOnce(
&'a <H as HostHandlers>::Shared<'a>,
&mut <H as HostHandlers>::MainThread<'a>,
) -> <H as HostHandlers>::AudioProcessor<'a>,
{
let wrapper = Arc::get_mut(&mut self.inner).ok_or(HostError::AlreadyActivatedPlugin)?;
let wrapper =
Arc::get_mut(&mut self.inner).ok_or(PluginInstanceError::AlreadyActivatedPlugin)?;
wrapper.activate(audio_processor, configuration)?;

Ok(StoppedPluginAudioProcessor::new(Arc::clone(&self.inner)))
Expand All @@ -70,7 +71,7 @@ impl<H: HostHandlers> PluginInstance<H> {
}

#[inline]
pub fn try_deactivate(&mut self) -> Result<(), HostError> {
pub fn try_deactivate(&mut self) -> Result<(), PluginInstanceError> {
self.try_deactivate_with(|_, _| ())
}

Expand All @@ -95,14 +96,15 @@ impl<H: HostHandlers> PluginInstance<H> {
self.try_deactivate_with(drop_with).unwrap()
}

pub fn try_deactivate_with<T, D>(&mut self, drop_with: D) -> Result<T, HostError>
pub fn try_deactivate_with<T, D>(&mut self, drop_with: D) -> Result<T, PluginInstanceError>
where
D: for<'s> FnOnce(
<H as HostHandlers>::AudioProcessor<'_>,
&mut <H as HostHandlers>::MainThread<'s>,
) -> T,
{
let wrapper = Arc::get_mut(&mut self.inner).ok_or(HostError::StillActivatedPlugin)?;
let wrapper =
Arc::get_mut(&mut self.inner).ok_or(PluginInstanceError::StillActivatedPlugin)?;

wrapper.deactivate_with(drop_with)
}
Expand Down
20 changes: 10 additions & 10 deletions host/src/plugin/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl<H: HostHandlers> PluginInstanceInner<H> {
plugin_bundle: &PluginBundle,
plugin_id: &CStr,
host_info: HostInfo,
) -> Result<Arc<Self>, HostError>
) -> Result<Arc<Self>, PluginInstanceError>
where
FS: for<'s> FnOnce(&'s ()) -> <H as HostHandlers>::Shared<'s>,
FH: for<'s> FnOnce(
Expand All @@ -34,7 +34,7 @@ impl<H: HostHandlers> PluginInstanceInner<H> {
{
let plugin_factory = plugin_bundle
.get_plugin_factory()
.ok_or(HostError::MissingPluginFactory)?;
.ok_or(PluginInstanceError::MissingPluginFactory)?;

let host_wrapper = HostWrapper::new(shared, main_thread);
let host_descriptor = Box::pin(RawHostDescriptor::new::<H>(host_info));
Expand Down Expand Up @@ -73,7 +73,7 @@ impl<H: HostHandlers> PluginInstanceInner<H> {
destroy(plugin_instance_ptr.as_ptr());
}

return Err(HostError::InstantiationFailed);
return Err(PluginInstanceError::InstantiationFailed);
}
}
}
Expand Down Expand Up @@ -107,7 +107,7 @@ impl<H: HostHandlers> PluginInstanceInner<H> {
&mut self,
audio_processor: FA,
configuration: PluginAudioConfiguration,
) -> Result<(), HostError>
) -> Result<(), PluginInstanceError>
where
FA: for<'a> FnOnce(
&'a <H as HostHandlers>::Shared<'a>,
Expand All @@ -117,7 +117,7 @@ impl<H: HostHandlers> PluginInstanceInner<H> {
let activate = self
.raw_instance()
.activate
.ok_or(HostError::NullActivateFunction)?;
.ok_or(PluginInstanceError::NullActivateFunction)?;

// SAFETY: this method being &mut guarantees nothing can call any other main-thread method
unsafe {
Expand All @@ -137,7 +137,7 @@ impl<H: HostHandlers> PluginInstanceInner<H> {
if !success {
// SAFETY: this method being &mut guarantees nothing can call any other main-thread method
let _ = unsafe { self.host_wrapper.teardown_audio_processor(|_, _| ()) };
return Err(HostError::ActivationFailed);
return Err(PluginInstanceError::ActivationFailed);
}

Ok(())
Expand All @@ -155,9 +155,9 @@ impl<H: HostHandlers> PluginInstanceInner<H> {
<H as HostHandlers>::AudioProcessor<'s>,
&mut <H as HostHandlers>::MainThread<'s>,
) -> T,
) -> Result<T, HostError> {
) -> Result<T, PluginInstanceError> {
if !self.is_active() {
return Err(HostError::DeactivatedPlugin);
return Err(PluginInstanceError::DeactivatedPlugin);
}

if self.is_started.load(Ordering::Acquire) {
Expand All @@ -179,14 +179,14 @@ impl<H: HostHandlers> PluginInstanceInner<H> {
/// User must ensure the instance is not in a processing state, and that this is only called
/// on the audio thread.
#[inline]
pub unsafe fn start_processing(&self) -> Result<(), HostError> {
pub unsafe fn start_processing(&self) -> Result<(), PluginInstanceError> {
if let Some(start_processing) = self.raw_instance().start_processing {
if start_processing(self.raw_instance()) {
self.is_started.store(true, Ordering::Release);
return Ok(());
}

Err(HostError::StartProcessingFailed)
Err(PluginInstanceError::StartProcessingFailed)
} else {
Ok(())
}
Expand Down
Loading

0 comments on commit a2c38e4

Please sign in to comment.