pedalkernel/compiler/components/
switches.rs1use crate::compiler::component::{
4 Component, ControlParam, ControlParamKind, GraphRole, PinConfig, StampResult,
5};
6use crate::compiler::validate::Severity;
7use crate::tree::MnaSystem;
8
9use super::impl_component_dyn;
10
11#[derive(Debug, Clone, PartialEq)]
16pub struct Switch {
17 pub positions: usize,
18}
19
20impl Component for Switch {
21 impl_component_dyn!();
22
23 fn type_tag(&self) -> &'static str {
24 "switch"
25 }
26
27 fn is_passive(&self) -> bool {
28 false
29 }
30
31 fn is_control_only(&self) -> bool {
32 true
33 }
34
35 fn pin_config(&self) -> PinConfig {
36 PinConfig {
37 valid_pins: &[],
38 aliases: &[],
39 }
40 }
41
42 fn graph_role(&self) -> GraphRole {
43 GraphRole::Virtual
44 }
45
46 fn stamp_mna(
47 &self,
48 _comp_id: &str,
49 _n1: Option<usize>,
50 _n2: Option<usize>,
51 _mna: &mut MnaSystem,
52 _sample_rate: f64,
53 ) -> StampResult {
54 StampResult::Skip
55 }
56
57 fn validate_values(&self, comp_id: &str) -> Vec<(Severity, String)> {
58 let mut w = Vec::new();
59 if self.positions < 2 {
60 w.push((
61 Severity::Warning,
62 format!(
63 "Switch '{}' has {} position(s) \u{2014} a switch needs at least 2",
64 comp_id, self.positions
65 ),
66 ));
67 }
68 w
69 }
70
71 fn controls(&self) -> Vec<ControlParam> {
72 vec![ControlParam {
73 name: "position",
74 kind: ControlParamKind::SwitchPosition {
75 num_positions: self.positions,
76 },
77 }]
78 }
79
80 fn footprint_ref(&self) -> (&'static str, &'static str) {
81 match self.positions {
82 2 => ("Switch:SW_SPDT", "SW"),
83 3 => ("Switch:SW_Rotary4", "SW"),
84 _ => ("Switch:SW_Rotary4", "SW"),
85 }
86 }
87
88 fn symbol_name(&self) -> &'static str {
89 "switch"
90 }
91 fn layout_class(&self) -> &'static str {
92 "switch"
93 }
94}
95
96#[derive(Debug, Clone, PartialEq)]
101pub struct RotarySwitch {
102 pub linked_ids: Vec<String>,
103}
104
105impl Component for RotarySwitch {
106 impl_component_dyn!();
107
108 fn type_tag(&self) -> &'static str {
109 "rotary switch"
110 }
111
112 fn is_passive(&self) -> bool {
113 false
114 }
115
116 fn is_control_only(&self) -> bool {
117 true
118 }
119
120 fn pin_config(&self) -> PinConfig {
121 PinConfig {
122 valid_pins: &[],
123 aliases: &[],
124 }
125 }
126
127 fn graph_role(&self) -> GraphRole {
128 GraphRole::Virtual
129 }
130
131 fn stamp_mna(
132 &self,
133 _comp_id: &str,
134 _n1: Option<usize>,
135 _n2: Option<usize>,
136 _mna: &mut MnaSystem,
137 _sample_rate: f64,
138 ) -> StampResult {
139 StampResult::Skip
140 }
141
142 fn controls(&self) -> Vec<ControlParam> {
143 vec![ControlParam {
144 name: "position",
145 kind: ControlParamKind::SwitchPosition {
146 num_positions: self.linked_ids.len(),
147 },
148 }]
149 }
150
151 fn footprint_ref(&self) -> (&'static str, &'static str) {
152 let positions = self.linked_ids.len().max(2);
153 match positions {
154 2..=4 => ("Switch:SW_Rotary4", "SW"),
155 5..=6 => ("Switch:SW_Rotary6", "SW"),
156 7..=8 => ("Switch:SW_Rotary8", "SW"),
157 _ => ("Switch:SW_Rotary12", "SW"),
158 }
159 }
160
161 fn symbol_name(&self) -> &'static str {
162 "switch"
163 }
164 fn layout_class(&self) -> &'static str {
165 "rotary_switch"
166 }
167}
168
169#[derive(Debug, Clone, PartialEq)]
174pub struct TriggerInputComp;
175
176impl Component for TriggerInputComp {
177 impl_component_dyn!();
178
179 fn type_tag(&self) -> &'static str {
180 "trigger_input"
181 }
182
183 fn is_passive(&self) -> bool {
184 false
185 }
186
187 fn is_control_only(&self) -> bool {
188 true
189 }
190
191 fn pin_config(&self) -> PinConfig {
192 PinConfig {
193 valid_pins: &["out"],
194 aliases: &[],
195 }
196 }
197
198 fn graph_role(&self) -> GraphRole {
199 GraphRole::Virtual
200 }
201
202 fn stamp_mna(
203 &self,
204 _comp_id: &str,
205 _n1: Option<usize>,
206 _n2: Option<usize>,
207 _mna: &mut MnaSystem,
208 _sample_rate: f64,
209 ) -> StampResult {
210 StampResult::Skip
211 }
212
213 fn controls(&self) -> Vec<ControlParam> {
214 vec![ControlParam {
215 name: "trigger",
216 kind: ControlParamKind::Trigger,
217 }]
218 }
219
220 fn footprint_ref(&self) -> (&'static str, &'static str) {
221 ("Connector:TestPoint", "TP")
222 }
223
224 fn symbol_name(&self) -> &'static str {
225 "switch"
226 }
227 fn layout_class(&self) -> &'static str {
228 "trigger_input"
229 }
230
231 fn is_trigger(&self) -> bool {
232 true
233 }
234}