Again
This commit is contained in:
@@ -810,10 +810,10 @@ impl SequencerState {
|
||||
|
||||
self.speed_overrides.clear();
|
||||
{
|
||||
let vars = self.variables.lock();
|
||||
let vars = self.variables.load();
|
||||
for id in self.audio_state.active_patterns.keys() {
|
||||
let key = self.key_cache.speed_key(id.bank, id.pattern);
|
||||
if let Some(v) = vars.get(key).and_then(|v| v.as_float().ok()) {
|
||||
if let Some(v) = vars.get(key).and_then(|v: &Value| v.as_float().ok()) {
|
||||
self.speed_overrides.insert((id.bank, id.pattern), v);
|
||||
}
|
||||
}
|
||||
@@ -931,8 +931,8 @@ impl SequencerState {
|
||||
};
|
||||
}
|
||||
|
||||
let mut vars = self.variables.lock();
|
||||
let new_tempo = vars.remove("__tempo__").and_then(|v| v.as_float().ok());
|
||||
let vars = self.variables.load();
|
||||
let new_tempo = vars.get("__tempo__").and_then(|v: &Value| v.as_float().ok());
|
||||
|
||||
let mut chain_transitions = Vec::new();
|
||||
for id in completed {
|
||||
@@ -942,12 +942,29 @@ impl SequencerState {
|
||||
chain_transitions.push((*id, target));
|
||||
}
|
||||
}
|
||||
vars.remove(chain_key);
|
||||
}
|
||||
|
||||
for id in stopped {
|
||||
let chain_key = self.key_cache.chain_key(id.bank, id.pattern);
|
||||
vars.remove(chain_key);
|
||||
// Remove consumed variables (tempo and chain keys)
|
||||
let needs_removal = new_tempo.is_some()
|
||||
|| completed.iter().any(|id| {
|
||||
let chain_key = self.key_cache.chain_key(id.bank, id.pattern);
|
||||
vars.contains_key(chain_key)
|
||||
})
|
||||
|| stopped.iter().any(|id| {
|
||||
let chain_key = self.key_cache.chain_key(id.bank, id.pattern);
|
||||
vars.contains_key(chain_key)
|
||||
});
|
||||
|
||||
if needs_removal {
|
||||
let mut new_vars = (**vars).clone();
|
||||
new_vars.remove("__tempo__");
|
||||
for id in completed {
|
||||
new_vars.remove(self.key_cache.chain_key(id.bank, id.pattern));
|
||||
}
|
||||
for id in stopped {
|
||||
new_vars.remove(self.key_cache.chain_key(id.bank, id.pattern));
|
||||
}
|
||||
self.variables.store(Arc::new(new_vars));
|
||||
}
|
||||
|
||||
VariableReads {
|
||||
@@ -1316,10 +1333,11 @@ fn parse_midi_command(cmd: &str) -> Option<(MidiCommand, Option<f64>)> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use arc_swap::ArcSwap;
|
||||
use parking_lot::Mutex;
|
||||
|
||||
fn make_state() -> SequencerState {
|
||||
let variables: Variables = Arc::new(Mutex::new(HashMap::new()));
|
||||
let variables: Variables = Arc::new(ArcSwap::from_pointee(HashMap::new()));
|
||||
let dict: Dictionary = Arc::new(Mutex::new(HashMap::new()));
|
||||
let rng: Rng = Arc::new(Mutex::new(
|
||||
<rand::rngs::StdRng as rand::SeedableRng>::seed_from_u64(0),
|
||||
@@ -1496,11 +1514,12 @@ mod tests {
|
||||
|
||||
// Set chain variable
|
||||
{
|
||||
let mut vars = state.variables.lock();
|
||||
let mut vars = (**state.variables.load()).clone();
|
||||
vars.insert(
|
||||
"__chain_0_0__".to_string(),
|
||||
Value::Str(std::sync::Arc::from("0:1"), None),
|
||||
);
|
||||
state.variables.store(Arc::new(vars));
|
||||
}
|
||||
|
||||
// Pattern 0 completes iteration AND gets stopped immediately in the same tick.
|
||||
@@ -1745,11 +1764,12 @@ mod tests {
|
||||
|
||||
// Set chain: 0:0 -> 0:1
|
||||
{
|
||||
let mut vars = state.variables.lock();
|
||||
let mut vars = (**state.variables.load()).clone();
|
||||
vars.insert(
|
||||
"__chain_0_0__".to_string(),
|
||||
Value::Str(std::sync::Arc::from("0:1"), None),
|
||||
);
|
||||
state.variables.store(Arc::new(vars));
|
||||
}
|
||||
|
||||
// Pattern 0 (length 1) completes iteration at beat=1.0 AND
|
||||
@@ -1996,8 +2016,9 @@ mod tests {
|
||||
|
||||
// Script fires at beat 1.0 (step 0). Set __tempo__ as if the script did.
|
||||
{
|
||||
let mut vars = state.variables.lock();
|
||||
let mut vars = (**state.variables.load()).clone();
|
||||
vars.insert("__tempo__".to_string(), Value::Float(140.0, None));
|
||||
state.variables.store(Arc::new(vars));
|
||||
}
|
||||
|
||||
let output = state.tick(tick_at(1.0, true));
|
||||
|
||||
Reference in New Issue
Block a user