use super::{Engine, LastFrame, Slot};
use crate::{EngineError, PresetReport};
use lactea_preset::{
ParseError, Preset, export_shape_file, export_wave_file, import_shape_file, import_wave_file,
};
impl Engine {
pub fn import_custom_wave(
&mut self,
slot: usize,
bytes: &[u8],
) -> Result<PresetReport, EngineError> {
self.import_custom(|p| import_wave_file(p, slot, bytes))
}
pub fn import_custom_shape(
&mut self,
slot: usize,
bytes: &[u8],
) -> Result<PresetReport, EngineError> {
self.import_custom(|p| import_shape_file(p, slot, bytes))
}
pub fn export_custom_wave(&self, slot: usize) -> Option<String> {
export_wave_file(&self.shown_slot()?.loaded.preset, slot)
}
pub fn export_custom_shape(&self, slot: usize) -> Option<String> {
export_shape_file(&self.shown_slot()?.loaded.preset, slot)
}
fn shown_slot(&self) -> Option<&Slot> {
self.incoming.as_ref().or(self.active.as_ref())
}
fn import_custom(
&mut self,
apply: impl FnOnce(&mut Preset) -> Result<(), ParseError>,
) -> Result<PresetReport, EngineError> {
let into_incoming = self.incoming.is_some();
let target = if into_incoming {
&mut self.incoming
} else {
&mut self.active
};
let mut slot = target.take().ok_or(EngineError::NoPreset)?;
let result = self.rebuild(&mut slot, apply);
let target = if into_incoming {
&mut self.incoming
} else {
&mut self.active
};
*target = Some(slot);
result
}
fn rebuild(
&mut self,
slot: &mut Slot,
apply: impl FnOnce(&mut Preset) -> Result<(), ParseError>,
) -> Result<PresetReport, EngineError> {
let mut preset = slot.loaded.preset.clone();
apply(&mut preset)?;
let text = preset.to_milk();
let name = slot.loaded.name.clone();
let (loaded, report) =
self.build_loaded(text.as_bytes(), &name, &mut slot.renderer, true)?;
slot.loaded = loaded;
slot.last = LastFrame::default();
Ok(report)
}
}