|
@@ -1,10 +1,5 @@
|
|
|
-use std::{
|
|
|
- fs::File,
|
|
|
- io::{Cursor, Read, Write},
|
|
|
- path::PathBuf,
|
|
|
-};
|
|
|
+use std::path::PathBuf;
|
|
|
|
|
|
-use binrw::{BinRead, BinWriterExt};
|
|
|
use ezcad::{pen::Pen, types::Rgba};
|
|
|
use log::debug;
|
|
|
use serde::{Deserialize, Serialize};
|
|
@@ -28,61 +23,59 @@ pub struct Patch {
|
|
|
}
|
|
|
|
|
|
impl Patch {
|
|
|
- fn patch(&self, id: usize, pens: &mut Vec<Pen>) {
|
|
|
- let to_patch: &mut Pen = pens.get_mut(id).expect("Invalid pen index");
|
|
|
-
|
|
|
+ fn patch(&self, pen: &mut Pen) {
|
|
|
self.color.map(|color| {
|
|
|
- debug!("Patching color for pen #{} to {:?}", id, color);
|
|
|
- *to_patch.color = color.into()
|
|
|
+ debug!("Patching pen color to {:?}", color);
|
|
|
+ *pen.color = color.into()
|
|
|
});
|
|
|
|
|
|
self.enabled.map(|enabled| {
|
|
|
- debug!("Patching enablement for pen #{} to {}", id, enabled);
|
|
|
- *to_patch.disabled = !enabled as u32;
|
|
|
+ debug!("Patching pen enablement to {}", enabled);
|
|
|
+ *pen.disabled = !enabled as u32;
|
|
|
});
|
|
|
|
|
|
self.loop_count.map(|loop_count| {
|
|
|
- debug!("Patching loop count for pen #{} to {}", id, loop_count);
|
|
|
+ debug!("Patching pen loop count to {}", loop_count);
|
|
|
assert!(loop_count > 0, "Pen loop count must be greater than zero");
|
|
|
- *to_patch.loop_count = loop_count;
|
|
|
+ *pen.loop_count = loop_count;
|
|
|
});
|
|
|
|
|
|
self.speed.map(|speed| {
|
|
|
- debug!("Patching speed for pen #{} to {}", id, speed);
|
|
|
+ debug!("Patching pen speed {}", speed);
|
|
|
assert!(
|
|
|
speed > SPEED_MIN && speed <= SPEED_MAX,
|
|
|
"Pen speed must be between {} and {}",
|
|
|
SPEED_MIN,
|
|
|
SPEED_MAX
|
|
|
);
|
|
|
- *to_patch.speed = speed;
|
|
|
+ *pen.speed = speed;
|
|
|
});
|
|
|
|
|
|
self.power.map(|power| {
|
|
|
- debug!("Patching power for pen #{} to {}", id, power);
|
|
|
+ debug!("Patching pen power {}", power);
|
|
|
assert!(
|
|
|
power > POWER_MIN && power <= POWER_MAX,
|
|
|
"Pen power must be between {} and {}",
|
|
|
POWER_MIN,
|
|
|
POWER_MAX
|
|
|
);
|
|
|
- *to_patch.power = power;
|
|
|
+ *pen.power = power;
|
|
|
});
|
|
|
|
|
|
self.frequency.map(|frequency| {
|
|
|
- debug!("Patching frequency for pen #{} to {}", id, frequency);
|
|
|
+ debug!("Patching pen frequency {}", frequency);
|
|
|
assert!(
|
|
|
frequency >= FREQUENCY_MIN && frequency <= FREQUENCY_MAX,
|
|
|
"Pen frequency must be between {} and {}",
|
|
|
FREQUENCY_MIN,
|
|
|
FREQUENCY_MAX
|
|
|
);
|
|
|
- *to_patch.frequency = frequency;
|
|
|
- *to_patch.frequency_2 = frequency.try_into().unwrap();
|
|
|
+ *pen.frequency = frequency;
|
|
|
+ *pen.frequency_2 = frequency.try_into().unwrap();
|
|
|
});
|
|
|
|
|
|
// Always enable custom settings for pen
|
|
|
- *to_patch.use_default = 0;
|
|
|
+ *pen.use_default = 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -96,7 +89,9 @@ pub struct PatchPen {
|
|
|
|
|
|
impl PatchPen {
|
|
|
pub fn patch(&self, pens: &mut Vec<Pen>) {
|
|
|
- self.patch.patch(self.pen, pens);
|
|
|
+ debug!("Patching pen #{}", self.pen);
|
|
|
+ let pen: &mut Pen = pens.get_mut(self.pen).expect("Invalid pen index");
|
|
|
+ self.patch.patch(pen);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -140,7 +135,8 @@ impl ClonePen {
|
|
|
|
|
|
// Patch pen if needed
|
|
|
self.patch.as_ref().map(|patch| {
|
|
|
- patch.patch(idx, pens);
|
|
|
+ debug!("Patching pen #{}", idx);
|
|
|
+ patch.patch(dst);
|
|
|
});
|
|
|
}
|
|
|
}
|
|
@@ -150,7 +146,8 @@ impl ClonePen {
|
|
|
|
|
|
// Patch pen if needed
|
|
|
self.patch.as_ref().map(|patch| {
|
|
|
- patch.patch(self.to, pens);
|
|
|
+ debug!("Patching pen #{}", self.to);
|
|
|
+ patch.patch(dst);
|
|
|
});
|
|
|
}
|
|
|
}
|
|
@@ -165,55 +162,39 @@ pub enum PatternField {
|
|
|
Frequency(i32),
|
|
|
}
|
|
|
|
|
|
-#[derive(Debug, Serialize, Deserialize)]
|
|
|
-#[serde(rename_all = "PascalCase")]
|
|
|
-pub struct PatternPen {
|
|
|
- from: usize,
|
|
|
- to: usize,
|
|
|
- field: PatternField,
|
|
|
-}
|
|
|
+impl PatternField {
|
|
|
+ pub fn pattern(&self, pens: &mut dyn Iterator<Item = (usize, &mut Pen)>) {
|
|
|
+ // Obtain settings from source (first) pen
|
|
|
+ let (src_idx, src) = pens.next().expect("Pattern must involve at least one pen");
|
|
|
|
|
|
-impl PatternPen {
|
|
|
- pub fn pattern(&self, pens: &mut Vec<Pen>) {
|
|
|
- debug!("Patterning from pen #{} to #{}", self.from, self.to);
|
|
|
- assert!(
|
|
|
- self.to > self.from,
|
|
|
- "Target pen(s) must be greater than source pen"
|
|
|
- );
|
|
|
-
|
|
|
- // Obtain settings from first pen
|
|
|
- let src: Pen = pens.get(self.from).expect("Invalid pen index").clone();
|
|
|
-
|
|
|
- let mut setting: PatternField = match self.field {
|
|
|
+ let mut setting: PatternField = match self {
|
|
|
PatternField::Loops(_) => {
|
|
|
debug!(
|
|
|
"Initial loop count from pen #{} is {}",
|
|
|
- self.from, *src.loop_count
|
|
|
+ src_idx, *src.loop_count
|
|
|
);
|
|
|
PatternField::Loops((*src.loop_count).try_into().unwrap())
|
|
|
}
|
|
|
PatternField::Speed(_) => {
|
|
|
- debug!("Initial speed from pen #{} is {}", self.from, *src.speed);
|
|
|
+ debug!("Initial speed from pen #{} is {}", src_idx, *src.speed);
|
|
|
PatternField::Speed(*src.speed)
|
|
|
}
|
|
|
PatternField::Power(_) => {
|
|
|
- debug!("Initial power from pen #{} is {}", self.from, *src.power);
|
|
|
+ debug!("Initial power from pen #{} is {}", src_idx, *src.power);
|
|
|
PatternField::Power(*src.power)
|
|
|
}
|
|
|
PatternField::Frequency(_) => {
|
|
|
debug!(
|
|
|
"Initial frequency from pen #{} is {}",
|
|
|
- self.from, *src.frequency
|
|
|
+ src_idx, *src.frequency
|
|
|
);
|
|
|
PatternField::Frequency((*src.frequency).try_into().unwrap())
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- for idx in (self.from..=self.to).skip(1) {
|
|
|
- let dst: &mut Pen = pens.get_mut(idx).expect("Invalid pen index");
|
|
|
-
|
|
|
+ for (idx, dst) in pens {
|
|
|
// Calculate new setting
|
|
|
- setting = match (setting, &self.field) {
|
|
|
+ setting = match (setting, self) {
|
|
|
(PatternField::Loops(prev), PatternField::Loops(incr)) => {
|
|
|
let value: i32 = prev + incr;
|
|
|
debug!("Patching loop count for pen #{} to {}", idx, value);
|
|
@@ -274,6 +255,31 @@ impl PatternPen {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+#[derive(Debug, Serialize, Deserialize)]
|
|
|
+#[serde(rename_all = "PascalCase")]
|
|
|
+pub struct PatternPen {
|
|
|
+ index: usize,
|
|
|
+ count: usize,
|
|
|
+ field: PatternField,
|
|
|
+}
|
|
|
+
|
|
|
+impl PatternPen {
|
|
|
+ pub fn pattern(&self, pens: &mut Vec<Pen>) {
|
|
|
+ debug!(
|
|
|
+ "Patterning from pen #{} to #{}",
|
|
|
+ self.index,
|
|
|
+ self.index + self.count - 1
|
|
|
+ );
|
|
|
+ self.field.pattern(
|
|
|
+ &mut pens
|
|
|
+ .iter_mut()
|
|
|
+ .enumerate()
|
|
|
+ .skip(self.index)
|
|
|
+ .take(self.count),
|
|
|
+ )
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
#[derive(Debug, Serialize, Deserialize)]
|
|
|
#[serde(rename_all = "PascalCase")]
|
|
|
pub struct ImportExportPen {
|
|
@@ -291,13 +297,7 @@ impl ImportExportPen {
|
|
|
|
|
|
let pen = pens.get(self.index).expect("Invalid pen index");
|
|
|
|
|
|
- let mut buffer: Cursor<Vec<u8>> = Cursor::new(vec![]);
|
|
|
- buffer.write_le(pen).expect("Failed to serialize pen");
|
|
|
-
|
|
|
- let mut output: File = File::create(&self.path).expect("Failed to open output file");
|
|
|
- output
|
|
|
- .write_all(buffer.into_inner().as_slice())
|
|
|
- .expect("Failed to write to output file");
|
|
|
+ pen.write_to_file(&self.path);
|
|
|
}
|
|
|
|
|
|
pub fn import(&self, pens: &mut Vec<Pen>) {
|
|
@@ -307,14 +307,7 @@ impl ImportExportPen {
|
|
|
self.path.to_string_lossy()
|
|
|
);
|
|
|
|
|
|
- let mut input: File = File::open(&self.path).expect("Failed to open input file");
|
|
|
-
|
|
|
- let mut buffer: Cursor<Vec<u8>> = Cursor::new(vec![]);
|
|
|
- input
|
|
|
- .read_to_end(buffer.get_mut())
|
|
|
- .expect("Failed to read input file");
|
|
|
-
|
|
|
- let pen: Pen = Pen::read_le(&mut buffer).expect("Failed to deserialize input as pen");
|
|
|
+ let pen: Pen = Pen::read_from_file(&self.path);
|
|
|
|
|
|
let dst: &mut Pen = pens.get_mut(self.index).expect("Invalid pen index");
|
|
|
*dst = pen;
|