use vst3::Steinberg::Vst::ComponentFlags_;
use vst3::Steinberg::{
PClassInfo, PClassInfo_::ClassCardinality_, PClassInfo2, PClassInfoW, PFactoryInfo,
PFactoryInfo_::FactoryFlags_,
};
use super::subcategories::Vst3SubCategory;
use crate::wrapper::util::strlcpy;
use crate::wrapper::vst3::Vst3Plugin;
use crate::wrapper::vst3::util::u16strlcpy;
pub const VST3_SDK_VERSION: &str = "VST 3.6.14";
#[allow(clippy::unnecessary_cast)]
const K_CLASS_CARDINALITY_MANY_INSTANCES: i32 = ClassCardinality_::kManyInstances as i32;
#[allow(clippy::unnecessary_cast)]
const K_FACTORY_FLAG_UNICODE: i32 = FactoryFlags_::kUnicode as i32;
#[derive(Debug)]
pub struct PluginInfo {
pub cid: &'static [u8; 16],
pub name: &'static str,
pub subcategories: String,
pub vendor: &'static str,
pub version: &'static str,
pub url: &'static str,
pub email: &'static str,
}
impl PluginInfo {
pub fn for_plugin<P: Vst3Plugin>() -> PluginInfo {
PluginInfo {
cid: &P::PLATFORM_VST3_CLASS_ID,
name: P::NAME,
subcategories: make_subcategories_string::<P>(),
vendor: P::VENDOR,
version: P::VERSION,
url: P::URL,
email: P::EMAIL,
}
}
pub fn create_factory_info(&self) -> PFactoryInfo {
let mut info: PFactoryInfo = unsafe { std::mem::zeroed() };
strlcpy(&mut info.vendor, self.vendor);
strlcpy(&mut info.url, self.url);
strlcpy(&mut info.email, self.email);
info.flags = K_FACTORY_FLAG_UNICODE;
info
}
pub fn create_class_info(&self) -> PClassInfo {
let mut info: PClassInfo = unsafe { std::mem::zeroed() };
info.cid = self.cid.map(|b| b as std::ffi::c_char);
info.cardinality = K_CLASS_CARDINALITY_MANY_INSTANCES;
strlcpy(&mut info.category, "Audio Module Class");
strlcpy(&mut info.name, self.name);
info
}
pub fn create_class_info_2(&self) -> PClassInfo2 {
let mut info: PClassInfo2 = unsafe { std::mem::zeroed() };
info.cid = self.cid.map(|b| b as std::ffi::c_char);
info.cardinality = K_CLASS_CARDINALITY_MANY_INSTANCES;
strlcpy(&mut info.category, "Audio Module Class");
strlcpy(&mut info.name, self.name);
#[allow(clippy::unnecessary_cast)]
{
info.classFlags = ComponentFlags_::kSimpleModeSupported as u32;
}
strlcpy(&mut info.subCategories, &self.subcategories);
strlcpy(&mut info.vendor, self.vendor);
strlcpy(&mut info.version, self.version);
strlcpy(&mut info.sdkVersion, VST3_SDK_VERSION);
info
}
pub fn create_class_info_unicode(&self) -> PClassInfoW {
let mut info: PClassInfoW = unsafe { std::mem::zeroed() };
info.cid = self.cid.map(|b| b as std::ffi::c_char);
info.cardinality = K_CLASS_CARDINALITY_MANY_INSTANCES;
strlcpy(&mut info.category, "Audio Module Class");
u16strlcpy(&mut info.name, self.name);
#[allow(clippy::unnecessary_cast)]
{
info.classFlags = ComponentFlags_::kSimpleModeSupported as u32;
}
strlcpy(&mut info.subCategories, &self.subcategories);
u16strlcpy(&mut info.vendor, self.vendor);
u16strlcpy(&mut info.version, self.version);
u16strlcpy(&mut info.sdkVersion, VST3_SDK_VERSION);
info
}
}
fn make_subcategories_string<P: Vst3Plugin>() -> String {
crate::nice_debug_assert!(!P::VST3_SUBCATEGORIES.contains(&Vst3SubCategory::Custom("OnlyRT")));
let subcategory_string = P::VST3_SUBCATEGORIES
.iter()
.map(Vst3SubCategory::as_str)
.collect::<Vec<&str>>()
.join("|");
let subcategory_string = if P::HARD_REALTIME_ONLY {
format!("{subcategory_string}|OnlyRT")
} else {
subcategory_string
};
crate::nice_debug_assert!(subcategory_string.len() <= 127);
subcategory_string
}