pen.rs 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. use std::{
  2. fs::File,
  3. io::{Cursor, Read, Write},
  4. path::PathBuf,
  5. };
  6. use binrw::{BinRead, BinWriterExt};
  7. use ezcad::pen::Pen;
  8. use log::debug;
  9. use serde::{Deserialize, Serialize};
  10. const SPEED_MIN: f64 = 0.0;
  11. const SPEED_MAX: f64 = 100000.0;
  12. const POWER_MIN: f64 = 0.0;
  13. const POWER_MAX: f64 = 100.0;
  14. const FREQUENCY_MIN: u32 = 1000;
  15. const FREQUENCY_MAX: u32 = 999000;
  16. #[derive(Debug, Serialize, Deserialize)]
  17. #[serde(rename_all = "PascalCase")]
  18. pub struct Patch {
  19. color: Option<(u8, u8, u8)>,
  20. enabled: Option<bool>,
  21. loop_count: Option<u32>,
  22. speed: Option<f64>,
  23. power: Option<f64>,
  24. frequency: Option<u32>,
  25. }
  26. impl Patch {
  27. fn patch(&self, id: usize, pens: &mut Vec<Pen>) {
  28. let to_patch: &mut Pen = pens.get_mut(id).expect("Invalid pen index");
  29. if let Some(color) = self.color {
  30. debug!("Patching color for pen #{}: {:?}", id, color);
  31. *to_patch.color = color.into()
  32. }
  33. if let Some(enabled) = self.enabled {
  34. debug!("Patching enablement for pen #{}: {}", id, enabled);
  35. *to_patch.disabled = !enabled as u32;
  36. }
  37. if let Some(loop_count) = self.loop_count {
  38. debug!("Patching loop count for pen #{}: {}", id, loop_count);
  39. assert!(loop_count > 0, "Pen loop count must be greater than zero");
  40. *to_patch.loop_count = loop_count;
  41. }
  42. if let Some(speed) = self.speed {
  43. debug!("Patching speed for pen #{}: {}", id, speed);
  44. assert!(
  45. speed > SPEED_MIN && speed <= SPEED_MAX,
  46. "Pen speed must be between {} and {}",
  47. SPEED_MIN,
  48. SPEED_MAX
  49. );
  50. *to_patch.speed = speed;
  51. }
  52. if let Some(power) = self.power {
  53. debug!("Patching power for pen #{}: {}", id, power);
  54. assert!(
  55. power > POWER_MIN && power <= POWER_MAX,
  56. "Pen power must be between {} and {}",
  57. POWER_MIN,
  58. POWER_MAX
  59. );
  60. *to_patch.power = power;
  61. }
  62. if let Some(frequency) = self.frequency {
  63. debug!("Patching frequency for pen #{}: {}", id, frequency);
  64. assert!(
  65. frequency >= FREQUENCY_MIN && frequency <= FREQUENCY_MAX,
  66. "Pen frequency must be between {} and {}",
  67. FREQUENCY_MIN,
  68. FREQUENCY_MAX
  69. );
  70. *to_patch.frequency = frequency;
  71. *to_patch.frequency_2 = frequency.try_into().unwrap();
  72. }
  73. // Always enable custom settings for pen
  74. *to_patch.use_default = 0;
  75. }
  76. }
  77. #[derive(Debug, Serialize, Deserialize)]
  78. #[serde(rename_all = "PascalCase")]
  79. pub struct PatchPen {
  80. pen: usize,
  81. #[serde(flatten)]
  82. patch: Patch,
  83. }
  84. impl PatchPen {
  85. pub fn patch(&self, pens: &mut Vec<Pen>) {
  86. self.patch.patch(self.pen, pens);
  87. }
  88. }
  89. #[derive(Debug, Serialize, Deserialize)]
  90. #[serde(rename_all = "PascalCase")]
  91. pub struct ClonePen {
  92. from: usize,
  93. to: usize,
  94. #[serde(flatten)]
  95. patch: Option<Patch>,
  96. }
  97. impl ClonePen {
  98. pub fn clone(&self, pens: &mut Vec<Pen>) {
  99. debug!("Cloning pen #{} to #{}", self.from, self.to);
  100. assert!(
  101. self.to > self.from,
  102. "Target pen must be greater than source pen"
  103. );
  104. // Clone pen
  105. let src: Pen = pens.get(self.from).expect("Invalid pen index").clone();
  106. let dst: &mut Pen = pens.get_mut(self.to).expect("Invalid pen index");
  107. *dst = src;
  108. // Patch pen if needed
  109. if let Some(patch) = &self.patch {
  110. patch.patch(self.to, pens);
  111. }
  112. }
  113. }
  114. #[derive(Debug, Serialize, Deserialize)]
  115. pub enum PatternField {
  116. Loops(i32),
  117. Speed(f64),
  118. Power(f64),
  119. Frequency(i32),
  120. }
  121. #[derive(Debug, Serialize, Deserialize)]
  122. #[serde(rename_all = "PascalCase")]
  123. pub struct PatternPen {
  124. from: usize,
  125. to: usize,
  126. field: PatternField,
  127. }
  128. impl PatternPen {
  129. pub fn pattern(&self, pens: &mut Vec<Pen>) {
  130. debug!("Patterning from pen #{} to #{}", self.from, self.to);
  131. assert!(
  132. self.to > self.from,
  133. "Target pen(s) must be greater than source pen"
  134. );
  135. // Obtain settings from first pen
  136. let src: Pen = pens.get(self.from).expect("Invalid pen index").clone();
  137. let mut setting: PatternField = match self.field {
  138. PatternField::Loops(_) => {
  139. debug!(
  140. "Initial loop count from pen #{}: {}",
  141. self.from, *src.loop_count
  142. );
  143. PatternField::Loops((*src.loop_count).try_into().unwrap())
  144. }
  145. PatternField::Speed(_) => {
  146. debug!("Initial speed from pen #{}: {}", self.from, *src.speed);
  147. PatternField::Speed(*src.speed)
  148. }
  149. PatternField::Power(_) => {
  150. debug!("Initial power from pen #{}: {}", self.from, *src.power);
  151. PatternField::Power(*src.power)
  152. }
  153. PatternField::Frequency(_) => {
  154. debug!(
  155. "Initial frequency from pen #{}: {}",
  156. self.from, *src.frequency
  157. );
  158. PatternField::Frequency((*src.frequency).try_into().unwrap())
  159. }
  160. };
  161. for dst in (self.from..=self.to).skip(1) {
  162. // Clone to target pen
  163. let pen: &mut Pen = pens.get_mut(dst).expect("Invalid pen index");
  164. *pen = src.clone();
  165. // Calculate new setting
  166. setting = match (setting, &self.field) {
  167. (PatternField::Loops(prev), PatternField::Loops(incr)) => {
  168. let value: i32 = prev + incr;
  169. debug!("Patching loop count for pen #{}: {}", dst, value);
  170. assert!(value > 0, "Pen loop count must be greater than zero");
  171. PatternField::Loops(value)
  172. }
  173. (PatternField::Speed(prev), PatternField::Speed(incr)) => {
  174. let value: f64 = prev + incr;
  175. debug!("Patching speed for pen #{}: {}", dst, value);
  176. assert!(
  177. value > SPEED_MIN && value <= SPEED_MAX,
  178. "Pen speed must be between {} and {}",
  179. SPEED_MIN,
  180. SPEED_MAX
  181. );
  182. PatternField::Speed(value)
  183. }
  184. (PatternField::Power(prev), PatternField::Power(incr)) => {
  185. let value: f64 = prev + incr;
  186. debug!("Patching power for pen #{}: {}", dst, value);
  187. assert!(
  188. value > POWER_MIN && value <= POWER_MAX,
  189. "Pen power must be between {} and {}",
  190. POWER_MIN,
  191. POWER_MAX
  192. );
  193. PatternField::Power(value)
  194. }
  195. (PatternField::Frequency(prev), PatternField::Frequency(incr)) => {
  196. let value: i32 = prev + incr;
  197. debug!("Patching frequency for pen #{}: {}", dst, value);
  198. assert!(
  199. value >= FREQUENCY_MIN.try_into().unwrap()
  200. && value <= FREQUENCY_MAX.try_into().unwrap(),
  201. "Pen frequency must be between {} and {}",
  202. FREQUENCY_MIN,
  203. FREQUENCY_MAX
  204. );
  205. PatternField::Frequency(value)
  206. }
  207. _ => unreachable!(),
  208. };
  209. // Patch updated value
  210. match setting {
  211. PatternField::Loops(x) => *pen.loop_count = x.try_into().unwrap(),
  212. PatternField::Speed(x) => *pen.speed = x,
  213. PatternField::Power(x) => *pen.power = x,
  214. PatternField::Frequency(x) => {
  215. *pen.frequency = x.try_into().unwrap();
  216. *pen.frequency_2 = x.try_into().unwrap();
  217. }
  218. }
  219. // Always enable custom settings for pen
  220. *pen.use_default = 0;
  221. }
  222. }
  223. }
  224. #[derive(Debug, Serialize, Deserialize)]
  225. #[serde(rename_all = "PascalCase")]
  226. pub struct ImportExportPen {
  227. index: usize,
  228. path: PathBuf,
  229. }
  230. impl ImportExportPen {
  231. pub fn export(&self, pens: &mut Vec<Pen>) {
  232. debug!(
  233. "Exporting pen #{} to '{}'",
  234. self.index,
  235. self.path.to_string_lossy()
  236. );
  237. let pen = pens.get(self.index).expect("Invalid pen index");
  238. let mut buffer: Cursor<Vec<u8>> = Cursor::new(vec![]);
  239. buffer.write_le(pen).expect("Failed to serialize pen");
  240. let mut output: File = File::create(&self.path).expect("Failed to open output file");
  241. output
  242. .write_all(buffer.into_inner().as_slice())
  243. .expect("Failed to write to output file");
  244. }
  245. pub fn import(&self, pens: &mut Vec<Pen>) {
  246. debug!(
  247. "Importing pen #{} from '{}'",
  248. self.index,
  249. self.path.to_string_lossy()
  250. );
  251. let mut input: File = File::open(&self.path).expect("Failed to open input file");
  252. let mut buffer: Cursor<Vec<u8>> = Cursor::new(vec![]);
  253. input
  254. .read_to_end(buffer.get_mut())
  255. .expect("Failed to read input file");
  256. let pen: Pen = Pen::read_le(&mut buffer).expect("Failed to deserialize input as pen");
  257. let dst: &mut Pen = pens.get_mut(self.index).expect("Invalid pen index");
  258. *dst = pen;
  259. }
  260. }