Feat: extend CI to cover desktop

This commit is contained in:
2026-01-30 21:19:48 +01:00
parent 6c9ec9a05f
commit bdba58312c
5 changed files with 61 additions and 17 deletions

View File

@@ -41,6 +41,7 @@ pub type Variables = Arc<Mutex<HashMap<String, Value>>>;
pub type Dictionary = Arc<Mutex<HashMap<String, Vec<Op>>>>;
pub type Rng = Arc<Mutex<StdRng>>;
pub type Stack = Arc<Mutex<Vec<Value>>>;
pub(super) type CmdSnapshot<'a> = (Option<&'a Value>, &'a [(String, Value)]);
#[derive(Clone, Debug)]
pub enum Value {
@@ -140,8 +141,12 @@ impl CmdRegister {
&self.deltas
}
pub(super) fn snapshot(&self) -> Option<(&Value, &[(String, Value)])> {
self.sound.as_ref().map(|s| (s, self.params.as_slice()))
pub(super) fn snapshot(&self) -> Option<CmdSnapshot<'_>> {
if self.sound.is_some() || !self.params.is_empty() {
Some((self.sound.as_ref(), self.params.as_slice()))
} else {
None
}
}
pub(super) fn clear(&mut self) {

View File

@@ -147,9 +147,12 @@ impl Forth {
};
let emit_with_cycling = |cmd: &CmdRegister, emit_idx: usize, delta_secs: f64, outputs: &mut Vec<String>| -> Result<Option<Value>, String> {
let (sound_val, params) = cmd.snapshot().ok_or("no sound set")?;
let resolved_sound_val = resolve_cycling(sound_val, emit_idx);
let sound = resolved_sound_val.as_str()?.to_string();
let (sound_opt, params) = cmd.snapshot().ok_or("nothing to emit")?;
let resolved_sound_val = sound_opt.map(|sv| resolve_cycling(sv, emit_idx));
let sound_str = match &resolved_sound_val {
Some(v) => Some(v.as_str()?.to_string()),
None => None,
};
let resolved_params: Vec<(String, String)> =
params.iter().map(|(k, v)| {
let resolved = resolve_cycling(v, emit_idx);
@@ -162,8 +165,8 @@ impl Forth {
}
(k.clone(), resolved.to_param_string())
}).collect();
emit_output(&sound, &resolved_params, ctx.step_duration(), delta_secs, outputs);
Ok(Some(resolved_sound_val.into_owned()))
emit_output(sound_str.as_deref(), &resolved_params, ctx.step_duration(), delta_secs, outputs);
Ok(resolved_sound_val.map(|v| v.into_owned()))
};
while pc < ops.len() {
@@ -796,25 +799,33 @@ fn is_tempo_scaled_param(name: &str) -> bool {
}
fn emit_output(
sound: &str,
sound: Option<&str>,
params: &[(String, String)],
step_duration: f64,
nudge_secs: f64,
outputs: &mut Vec<String>,
) {
let mut pairs = vec![("sound".into(), sound.to_string())];
let mut pairs: Vec<(String, String)> = if let Some(s) = sound {
vec![("sound".into(), s.to_string())]
} else {
vec![]
};
pairs.extend(params.iter().cloned());
if nudge_secs > 0.0 {
pairs.push(("delta".into(), nudge_secs.to_string()));
}
if !pairs.iter().any(|(k, _)| k == "dur") {
// Only add default dur if there's a sound (new voice)
if sound.is_some() && !pairs.iter().any(|(k, _)| k == "dur") {
pairs.push(("dur".into(), step_duration.to_string()));
}
if let Some(idx) = pairs.iter().position(|(k, _)| k == "delaytime") {
let ratio: f64 = pairs[idx].1.parse().unwrap_or(1.0);
pairs[idx].1 = (ratio * step_duration).to_string();
} else {
pairs.push(("delaytime".into(), step_duration.to_string()));
// Only add default delaytime if there's a sound (new voice)
if sound.is_some() {
if let Some(idx) = pairs.iter().position(|(k, _)| k == "delaytime") {
let ratio: f64 = pairs[idx].1.parse().unwrap_or(1.0);
pairs[idx].1 = (ratio * step_duration).to_string();
} else {
pairs.push(("delaytime".into(), step_duration.to_string()));
}
}
for pair in &mut pairs {
if is_tempo_scaled_param(&pair.0) {