|
@@ -106,6 +106,7 @@ impl PatchPen {
|
|
|
debug!("Patching pen #{}", self.pen);
|
|
|
let pen: &mut Pen = pens.get_mut(self.pen).expect("Invalid pen index");
|
|
|
self.patch.patch(pen);
|
|
|
+ pen.valid_settings();
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -290,6 +291,8 @@ impl PatternField {
|
|
|
|
|
|
// Always enable custom settings for pen
|
|
|
*dst.use_default = 0;
|
|
|
+
|
|
|
+ dst.valid_settings();
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -319,6 +322,30 @@ impl PatternPen {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+#[derive(Copy, Clone, Default, PartialEq)]
|
|
|
+struct RandomizedSetting {
|
|
|
+ speed: Option<f64>,
|
|
|
+ power: Option<f64>,
|
|
|
+ frequency: Option<u32>,
|
|
|
+ pulse_width: Option<PulseWidth>,
|
|
|
+}
|
|
|
+
|
|
|
+impl RandomizedSetting {
|
|
|
+ fn apply(&self, pen: &mut Pen) {
|
|
|
+ self.speed.map(|speed| *pen.speed = speed);
|
|
|
+ self.power.map(|power| *pen.power = power);
|
|
|
+ self.frequency.map(|freq| {
|
|
|
+ *pen.frequency = freq;
|
|
|
+ *pen.frequency_2 = freq.try_into().unwrap();
|
|
|
+ });
|
|
|
+ self.pulse_width.map(|pw| {
|
|
|
+ let pw: u32 = pw.into();
|
|
|
+ *pen.pulse_width = pw;
|
|
|
+ *pen.pulse_width_2 = pw.try_into().unwrap();
|
|
|
+ });
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
|
#[serde(rename_all = "PascalCase")]
|
|
|
pub struct RandomizePen {
|
|
@@ -338,53 +365,82 @@ impl RandomizePen {
|
|
|
self.index + self.count - 1
|
|
|
);
|
|
|
|
|
|
+ let mut generated: Vec<RandomizedSetting> = vec![];
|
|
|
+ const MAX_ATTEMPTS: usize = 1000;
|
|
|
+
|
|
|
for (index, pen) in pens
|
|
|
.iter_mut()
|
|
|
.skip(self.index)
|
|
|
.take(self.count)
|
|
|
.enumerate()
|
|
|
{
|
|
|
- if let Some((min, max, step)) = self.speed {
|
|
|
- let offset: usize = rand::thread_rng().gen_range(0..=((max - min) / step) as usize);
|
|
|
- let value: f64 = min + step * offset as f64;
|
|
|
- debug!("Randomizing speed for pen #{} to {}", index, value);
|
|
|
- *pen.speed = value;
|
|
|
- }
|
|
|
+ for attempt in 0..=MAX_ATTEMPTS {
|
|
|
+ let mut setting: RandomizedSetting = RandomizedSetting::default();
|
|
|
+
|
|
|
+ if let Some((min, max, step)) = self.speed {
|
|
|
+ let offset: usize =
|
|
|
+ rand::thread_rng().gen_range(0..=((max - min) / step) as usize);
|
|
|
+ let value: f64 = min + step * offset as f64;
|
|
|
+ debug!("Randomizing speed for pen #{} to {}", index, value);
|
|
|
+ setting.speed = Some(value);
|
|
|
+ }
|
|
|
|
|
|
- if let Some((min, max, step)) = self.power {
|
|
|
- let offset: usize = rand::thread_rng().gen_range(0..=((max - min) / step) as usize);
|
|
|
- let value: f64 = min + step * offset as f64;
|
|
|
- debug!("Randomizing power for pen #{} to {}", index, value);
|
|
|
- *pen.power = value;
|
|
|
- }
|
|
|
+ if let Some((min, max, step)) = self.power {
|
|
|
+ let offset: usize =
|
|
|
+ rand::thread_rng().gen_range(0..=((max - min) / step) as usize);
|
|
|
+ let value: f64 = min + step * offset as f64;
|
|
|
+ debug!("Randomizing power for pen #{} to {}", index, value);
|
|
|
+ setting.power = Some(value);
|
|
|
+ }
|
|
|
|
|
|
- if let Some((min, max, step)) = self.frequency {
|
|
|
- let offset: usize = rand::thread_rng().gen_range(0..=((max - min) / step) as usize);
|
|
|
- let value: u32 = min + step * offset as u32;
|
|
|
- debug!("Randomizing frequency for pen #{} to {}", index, value);
|
|
|
- *pen.frequency = value;
|
|
|
- *pen.frequency_2 = value.try_into().unwrap();
|
|
|
- }
|
|
|
+ if let Some((min, max, step)) = self.frequency {
|
|
|
+ let offset: usize =
|
|
|
+ rand::thread_rng().gen_range(0..=((max - min) / step) as usize);
|
|
|
+ let value: u32 = min + step * offset as u32;
|
|
|
+ debug!("Randomizing frequency for pen #{} to {}", index, value);
|
|
|
+ setting.frequency = Some(value);
|
|
|
+ }
|
|
|
|
|
|
- if let Some((min, max, step)) = self.pulse_width {
|
|
|
- let mut pw = PulseWidth::iter();
|
|
|
- let mut values: Vec<PulseWidth> = vec![pw.find(|x| *x == min).unwrap()];
|
|
|
- values.extend(
|
|
|
- pw.skip(step - 1)
|
|
|
- .step_by(step)
|
|
|
- .take_while_inclusive(|x| *x != max)
|
|
|
- .collect_vec(),
|
|
|
- );
|
|
|
+ if let Some((min, max, step)) = self.pulse_width {
|
|
|
+ let mut pw = PulseWidth::iter();
|
|
|
+ let mut values: Vec<PulseWidth> = vec![pw.find(|x| *x == min).unwrap()];
|
|
|
+ values.extend(
|
|
|
+ pw.skip(step - 1)
|
|
|
+ .step_by(step)
|
|
|
+ .take_while_inclusive(|x| *x != max)
|
|
|
+ .collect_vec(),
|
|
|
+ );
|
|
|
|
|
|
- let width: &PulseWidth = values
|
|
|
- .choose_multiple(&mut rand::thread_rng(), 1)
|
|
|
- .next()
|
|
|
- .unwrap();
|
|
|
- let value: u32 = (*width).into();
|
|
|
- debug!("Randomizing pulse width for pen #{} to {}", index, value);
|
|
|
- *pen.pulse_width = value;
|
|
|
- *pen.pulse_width_2 = value.try_into().unwrap();
|
|
|
+ let width: &PulseWidth = values
|
|
|
+ .choose_multiple(&mut rand::thread_rng(), 1)
|
|
|
+ .next()
|
|
|
+ .unwrap();
|
|
|
+ let value: u32 = (*width).into();
|
|
|
+ debug!("Randomizing pulse width for pen #{} to {}", index, value);
|
|
|
+ setting.pulse_width = Some(*width);
|
|
|
+ }
|
|
|
+
|
|
|
+ if !generated.contains(&setting) {
|
|
|
+ generated.push(setting);
|
|
|
+ setting.apply(pen);
|
|
|
+ if !pen.valid_settings() {
|
|
|
+ debug!("Retrying..");
|
|
|
+ } else {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ debug!("Duplicate random setting");
|
|
|
+ }
|
|
|
+
|
|
|
+ if attempt == MAX_ATTEMPTS {
|
|
|
+ panic!(
|
|
|
+ "Exceeded maximum number of {} randommization attempts",
|
|
|
+ MAX_ATTEMPTS
|
|
|
+ );
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+ pen.valid_settings();
|
|
|
}
|
|
|
}
|
|
|
}
|