Feat: optimizations
This commit is contained in:
@@ -140,7 +140,7 @@ pub struct PatternSnapshot {
|
||||
pub struct StepSnapshot {
|
||||
pub active: bool,
|
||||
pub script: String,
|
||||
pub source: Option<usize>,
|
||||
pub source: Option<u8>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Default, Debug)]
|
||||
@@ -392,7 +392,7 @@ impl PatternSnapshot {
|
||||
for _ in 0..self.steps.len() {
|
||||
if let Some(step) = self.steps.get(current) {
|
||||
if let Some(source) = step.source {
|
||||
current = source;
|
||||
current = source as usize;
|
||||
} else {
|
||||
return current;
|
||||
}
|
||||
@@ -500,30 +500,32 @@ fn parse_chain_target(s: &str) -> Option<PatternId> {
|
||||
})
|
||||
}
|
||||
|
||||
struct KeyCache {
|
||||
speed_keys: [[String; MAX_PATTERNS]; MAX_BANKS],
|
||||
chain_keys: [[String; MAX_PATTERNS]; MAX_BANKS],
|
||||
struct KeyBuf {
|
||||
speed: String,
|
||||
chain: String,
|
||||
}
|
||||
|
||||
impl KeyCache {
|
||||
impl KeyBuf {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
speed_keys: std::array::from_fn(|bank| {
|
||||
std::array::from_fn(|pattern| format!("__speed_{bank}_{pattern}__"))
|
||||
}),
|
||||
chain_keys: std::array::from_fn(|bank| {
|
||||
std::array::from_fn(|pattern| format!("__chain_{bank}_{pattern}__"))
|
||||
}),
|
||||
speed: String::with_capacity(24),
|
||||
chain: String::with_capacity(24),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn speed_key(&self, bank: usize, pattern: usize) -> &str {
|
||||
&self.speed_keys[bank][pattern]
|
||||
}
|
||||
fn format_speed_key(buf: &mut String, bank: usize, pattern: usize) -> &str {
|
||||
use std::fmt::Write;
|
||||
buf.clear();
|
||||
write!(buf, "__speed_{bank}_{pattern}__").unwrap();
|
||||
buf
|
||||
}
|
||||
|
||||
fn chain_key(&self, bank: usize, pattern: usize) -> &str {
|
||||
&self.chain_keys[bank][pattern]
|
||||
}
|
||||
fn format_chain_key(buf: &mut String, bank: usize, pattern: usize) -> &str {
|
||||
use std::fmt::Write;
|
||||
buf.clear();
|
||||
write!(buf, "__chain_{bank}_{pattern}__").unwrap();
|
||||
buf
|
||||
}
|
||||
|
||||
pub(crate) struct SequencerState {
|
||||
@@ -537,7 +539,7 @@ pub(crate) struct SequencerState {
|
||||
variables: Variables,
|
||||
dict: Dictionary,
|
||||
speed_overrides: HashMap<(usize, usize), f64>,
|
||||
key_cache: KeyCache,
|
||||
key_buf: KeyBuf,
|
||||
buf_audio_commands: Vec<TimestampedCommand>,
|
||||
buf_activated: Vec<PatternId>,
|
||||
buf_stopped: Vec<PatternId>,
|
||||
@@ -566,7 +568,7 @@ impl SequencerState {
|
||||
variables,
|
||||
dict,
|
||||
speed_overrides: HashMap::with_capacity(MAX_PATTERNS),
|
||||
key_cache: KeyCache::new(),
|
||||
key_buf: KeyBuf::new(),
|
||||
buf_audio_commands: Vec::with_capacity(32),
|
||||
buf_activated: Vec::with_capacity(16),
|
||||
buf_stopped: Vec::with_capacity(16),
|
||||
@@ -834,7 +836,7 @@ impl SequencerState {
|
||||
{
|
||||
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);
|
||||
let key = format_speed_key(&mut self.key_buf.speed, id.bank, id.pattern);
|
||||
if let Some(v) = vars.get(key).and_then(|v: &Value| v.as_float().ok()) {
|
||||
self.speed_overrides.insert((id.bank, id.pattern), v);
|
||||
}
|
||||
@@ -884,6 +886,8 @@ impl SequencerState {
|
||||
active.pattern,
|
||||
source_idx,
|
||||
);
|
||||
let speed_key = format_speed_key(&mut self.key_buf.speed, active.bank, active.pattern);
|
||||
let chain_key = format_chain_key(&mut self.key_buf.chain, active.bank, active.pattern);
|
||||
let ctx = StepContext {
|
||||
step: step_idx,
|
||||
beat: step_beat,
|
||||
@@ -897,9 +901,9 @@ impl SequencerState {
|
||||
speed: speed_mult,
|
||||
fill,
|
||||
nudge_secs,
|
||||
cc_access: self.cc_access.clone(),
|
||||
speed_key: self.key_cache.speed_key(active.bank, active.pattern),
|
||||
chain_key: self.key_cache.chain_key(active.bank, active.pattern),
|
||||
cc_access: self.cc_access.as_deref(),
|
||||
speed_key,
|
||||
chain_key,
|
||||
#[cfg(feature = "desktop")]
|
||||
mouse_x,
|
||||
#[cfg(feature = "desktop")]
|
||||
@@ -970,8 +974,9 @@ impl SequencerState {
|
||||
.and_then(|v: &Value| v.as_float().ok());
|
||||
|
||||
let mut chain_transitions = Vec::new();
|
||||
let mut buf = String::with_capacity(24);
|
||||
for id in completed {
|
||||
let chain_key = self.key_cache.chain_key(id.bank, id.pattern);
|
||||
let chain_key = format_chain_key(&mut buf, id.bank, id.pattern);
|
||||
if let Some(Value::Str(s, _)) = vars.get(chain_key) {
|
||||
if let Some(target) = parse_chain_target(s) {
|
||||
chain_transitions.push((*id, target));
|
||||
@@ -980,24 +985,24 @@ impl SequencerState {
|
||||
}
|
||||
|
||||
// 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)
|
||||
});
|
||||
let mut needs_removal = new_tempo.is_some();
|
||||
if !needs_removal {
|
||||
for id in completed.iter().chain(stopped.iter()) {
|
||||
if vars.contains_key(format_chain_key(&mut buf, id.bank, id.pattern)) {
|
||||
needs_removal = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
new_vars.remove(format_chain_key(&mut buf, id.bank, id.pattern));
|
||||
}
|
||||
for id in stopped {
|
||||
new_vars.remove(self.key_cache.chain_key(id.bank, id.pattern));
|
||||
new_vars.remove(format_chain_key(&mut buf, id.bank, id.pattern));
|
||||
}
|
||||
self.variables.store(Arc::new(new_vars));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user