nice_plug/wrapper/vst3/
factory.rs1use vst3::Steinberg::Vst::ComponentFlags_;
9use vst3::Steinberg::{
10 PClassInfo, PClassInfo_::ClassCardinality_, PClassInfo2, PClassInfoW, PFactoryInfo,
11 PFactoryInfo_::FactoryFlags_,
12};
13
14use super::subcategories::Vst3SubCategory;
15use crate::wrapper::util::strlcpy;
16use crate::wrapper::vst3::Vst3Plugin;
17use crate::wrapper::vst3::util::u16strlcpy;
18
19pub const VST3_SDK_VERSION: &str = "VST 3.6.14";
22
23#[allow(clippy::unnecessary_cast)]
24const K_CLASS_CARDINALITY_MANY_INSTANCES: i32 = ClassCardinality_::kManyInstances as i32;
25#[allow(clippy::unnecessary_cast)]
26const K_FACTORY_FLAG_UNICODE: i32 = FactoryFlags_::kUnicode as i32;
27
28#[derive(Debug)]
31pub struct PluginInfo {
32 pub cid: &'static [u8; 16],
33 pub name: &'static str,
34 pub subcategories: String,
35 pub vendor: &'static str,
36 pub version: &'static str,
37
38 pub url: &'static str,
40 pub email: &'static str,
41}
42
43impl PluginInfo {
44 pub fn for_plugin<P: Vst3Plugin>() -> PluginInfo {
45 PluginInfo {
46 cid: &P::PLATFORM_VST3_CLASS_ID,
47 name: P::NAME,
48 subcategories: make_subcategories_string::<P>(),
49 vendor: P::VENDOR,
50 version: P::VERSION,
51 url: P::URL,
52 email: P::EMAIL,
53 }
54 }
55
56 pub fn create_factory_info(&self) -> PFactoryInfo {
59 let mut info: PFactoryInfo = unsafe { std::mem::zeroed() };
60 strlcpy(&mut info.vendor, self.vendor);
61 strlcpy(&mut info.url, self.url);
62 strlcpy(&mut info.email, self.email);
63 info.flags = K_FACTORY_FLAG_UNICODE;
64
65 info
66 }
67
68 pub fn create_class_info(&self) -> PClassInfo {
71 let mut info: PClassInfo = unsafe { std::mem::zeroed() };
72 info.cid = self.cid.map(|b| b as std::ffi::c_char);
73 info.cardinality = K_CLASS_CARDINALITY_MANY_INSTANCES;
74 strlcpy(&mut info.category, "Audio Module Class");
75 strlcpy(&mut info.name, self.name);
76
77 info
78 }
79
80 pub fn create_class_info_2(&self) -> PClassInfo2 {
83 let mut info: PClassInfo2 = unsafe { std::mem::zeroed() };
84 info.cid = self.cid.map(|b| b as std::ffi::c_char);
85 info.cardinality = K_CLASS_CARDINALITY_MANY_INSTANCES;
86 strlcpy(&mut info.category, "Audio Module Class");
87 strlcpy(&mut info.name, self.name);
88 #[allow(clippy::unnecessary_cast)]
89 {
90 info.classFlags = ComponentFlags_::kSimpleModeSupported as u32;
91 }
92 strlcpy(&mut info.subCategories, &self.subcategories);
93 strlcpy(&mut info.vendor, self.vendor);
94 strlcpy(&mut info.version, self.version);
95 strlcpy(&mut info.sdkVersion, VST3_SDK_VERSION);
96
97 info
98 }
99
100 pub fn create_class_info_unicode(&self) -> PClassInfoW {
103 let mut info: PClassInfoW = unsafe { std::mem::zeroed() };
104 info.cid = self.cid.map(|b| b as std::ffi::c_char);
105 info.cardinality = K_CLASS_CARDINALITY_MANY_INSTANCES;
106 strlcpy(&mut info.category, "Audio Module Class");
107 u16strlcpy(&mut info.name, self.name);
108 #[allow(clippy::unnecessary_cast)]
109 {
110 info.classFlags = ComponentFlags_::kSimpleModeSupported as u32;
111 }
112 strlcpy(&mut info.subCategories, &self.subcategories);
113 u16strlcpy(&mut info.vendor, self.vendor);
114 u16strlcpy(&mut info.version, self.version);
115 u16strlcpy(&mut info.sdkVersion, VST3_SDK_VERSION);
116
117 info
118 }
119}
120
121fn make_subcategories_string<P: Vst3Plugin>() -> String {
123 crate::nice_debug_assert!(!P::VST3_SUBCATEGORIES.contains(&Vst3SubCategory::Custom("OnlyRT")));
126 let subcategory_string = P::VST3_SUBCATEGORIES
127 .iter()
128 .map(Vst3SubCategory::as_str)
129 .collect::<Vec<&str>>()
130 .join("|");
131
132 let subcategory_string = if P::HARD_REALTIME_ONLY {
133 format!("{subcategory_string}|OnlyRT")
134 } else {
135 subcategory_string
136 };
137 crate::nice_debug_assert!(subcategory_string.len() <= 127);
138
139 subcategory_string
140}