Try to optimize
This commit is contained in:
@@ -93,17 +93,19 @@ pub struct ActivePatternState {
|
||||
pub iter: usize,
|
||||
}
|
||||
|
||||
pub type StepTracesMap = HashMap<(usize, usize, usize), ExecutionTrace>;
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub struct SharedSequencerState {
|
||||
pub active_patterns: Vec<ActivePatternState>,
|
||||
pub step_traces: HashMap<(usize, usize, usize), ExecutionTrace>,
|
||||
pub step_traces: Arc<StepTracesMap>,
|
||||
pub event_count: usize,
|
||||
pub dropped_events: usize,
|
||||
}
|
||||
|
||||
pub struct SequencerSnapshot {
|
||||
pub active_patterns: Vec<ActivePatternState>,
|
||||
pub step_traces: HashMap<(usize, usize, usize), ExecutionTrace>,
|
||||
step_traces: Arc<StepTracesMap>,
|
||||
pub event_count: usize,
|
||||
pub dropped_events: usize,
|
||||
}
|
||||
@@ -146,7 +148,7 @@ impl SequencerHandle {
|
||||
let state = self.shared_state.load();
|
||||
SequencerSnapshot {
|
||||
active_patterns: state.active_patterns.clone(),
|
||||
step_traces: state.step_traces.clone(),
|
||||
step_traces: Arc::clone(&state.step_traces),
|
||||
event_count: state.event_count,
|
||||
dropped_events: state.dropped_events,
|
||||
}
|
||||
@@ -366,7 +368,6 @@ pub(crate) struct TickOutput {
|
||||
}
|
||||
|
||||
struct StepResult {
|
||||
audio_commands: Vec<String>,
|
||||
completed_iterations: Vec<PatternId>,
|
||||
any_step_fired: bool,
|
||||
}
|
||||
@@ -384,15 +385,44 @@ fn parse_chain_target(s: &str) -> Option<PatternId> {
|
||||
})
|
||||
}
|
||||
|
||||
struct KeyCache {
|
||||
speed_keys: [[String; MAX_PATTERNS]; MAX_BANKS],
|
||||
chain_keys: [[String; MAX_PATTERNS]; MAX_BANKS],
|
||||
}
|
||||
|
||||
impl KeyCache {
|
||||
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}__"))
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn speed_key(&self, bank: usize, pattern: usize) -> &str {
|
||||
&self.speed_keys[bank][pattern]
|
||||
}
|
||||
|
||||
fn chain_key(&self, bank: usize, pattern: usize) -> &str {
|
||||
&self.chain_keys[bank][pattern]
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct SequencerState {
|
||||
audio_state: AudioState,
|
||||
pattern_cache: PatternCache,
|
||||
runs_counter: RunsCounter,
|
||||
step_traces: HashMap<(usize, usize, usize), ExecutionTrace>,
|
||||
step_traces: Arc<StepTracesMap>,
|
||||
event_count: usize,
|
||||
dropped_events: usize,
|
||||
script_engine: ScriptEngine,
|
||||
variables: Variables,
|
||||
speed_overrides: HashMap<(usize, usize), f64>,
|
||||
key_cache: KeyCache,
|
||||
buf_audio_commands: Vec<String>,
|
||||
}
|
||||
|
||||
impl SequencerState {
|
||||
@@ -406,11 +436,14 @@ impl SequencerState {
|
||||
audio_state: AudioState::new(),
|
||||
pattern_cache: PatternCache::new(),
|
||||
runs_counter: RunsCounter::new(),
|
||||
step_traces: HashMap::new(),
|
||||
step_traces: Arc::new(HashMap::new()),
|
||||
event_count: 0,
|
||||
dropped_events: 0,
|
||||
script_engine,
|
||||
variables,
|
||||
speed_overrides: HashMap::new(),
|
||||
key_cache: KeyCache::new(),
|
||||
buf_audio_commands: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -459,7 +492,7 @@ impl SequencerState {
|
||||
self.audio_state.active_patterns.clear();
|
||||
self.audio_state.pending_starts.clear();
|
||||
self.audio_state.pending_stops.clear();
|
||||
self.step_traces.clear();
|
||||
Arc::make_mut(&mut self.step_traces).clear();
|
||||
self.runs_counter.counts.clear();
|
||||
}
|
||||
SeqCommand::Shutdown => {}
|
||||
@@ -491,7 +524,7 @@ impl SequencerState {
|
||||
self.audio_state.prev_beat = beat;
|
||||
|
||||
TickOutput {
|
||||
audio_commands: steps.audio_commands,
|
||||
audio_commands: std::mem::take(&mut self.buf_audio_commands),
|
||||
new_tempo: vars.new_tempo,
|
||||
shared_state: self.build_shared_state(),
|
||||
}
|
||||
@@ -500,13 +533,14 @@ impl SequencerState {
|
||||
fn tick_paused(&mut self) -> TickOutput {
|
||||
for pending in self.audio_state.pending_stops.drain(..) {
|
||||
self.audio_state.active_patterns.remove(&pending.id);
|
||||
self.step_traces.retain(|&(bank, pattern, _), _| {
|
||||
Arc::make_mut(&mut self.step_traces).retain(|&(bank, pattern, _), _| {
|
||||
bank != pending.id.bank || pattern != pending.id.pattern
|
||||
});
|
||||
}
|
||||
self.audio_state.pending_starts.clear();
|
||||
self.buf_audio_commands.clear();
|
||||
TickOutput {
|
||||
audio_commands: Vec::new(),
|
||||
audio_commands: std::mem::take(&mut self.buf_audio_commands),
|
||||
new_tempo: None,
|
||||
shared_state: self.build_shared_state(),
|
||||
}
|
||||
@@ -547,7 +581,7 @@ impl SequencerState {
|
||||
for pending in &self.audio_state.pending_stops {
|
||||
if check_quantization_boundary(pending.quantization, beat, prev_beat, quantum) {
|
||||
self.audio_state.active_patterns.remove(&pending.id);
|
||||
self.step_traces.retain(|&(bank, pattern, _), _| {
|
||||
Arc::make_mut(&mut self.step_traces).retain(|&(bank, pattern, _), _| {
|
||||
bank != pending.id.bank || pattern != pending.id.pattern
|
||||
});
|
||||
stopped.push(pending.id);
|
||||
@@ -565,32 +599,29 @@ impl SequencerState {
|
||||
fill: bool,
|
||||
nudge_secs: f64,
|
||||
) -> StepResult {
|
||||
self.buf_audio_commands.clear();
|
||||
let mut result = StepResult {
|
||||
audio_commands: Vec::new(),
|
||||
completed_iterations: Vec::new(),
|
||||
any_step_fired: false,
|
||||
};
|
||||
|
||||
let speed_overrides: HashMap<(usize, usize), f64> = {
|
||||
self.speed_overrides.clear();
|
||||
{
|
||||
let vars = self.variables.lock().unwrap();
|
||||
self.audio_state
|
||||
.active_patterns
|
||||
.keys()
|
||||
.filter_map(|id| {
|
||||
let key = format!("__speed_{}_{}__", id.bank, id.pattern);
|
||||
vars.get(&key)
|
||||
.and_then(|v| v.as_float().ok())
|
||||
.map(|v| ((id.bank, id.pattern), v))
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
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()) {
|
||||
self.speed_overrides.insert((id.bank, id.pattern), v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (_id, active) in self.audio_state.active_patterns.iter_mut() {
|
||||
let Some(pattern) = self.pattern_cache.get(active.bank, active.pattern) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
let speed_mult = speed_overrides
|
||||
let speed_mult = self.speed_overrides
|
||||
.get(&(active.bank, active.pattern))
|
||||
.copied()
|
||||
.unwrap_or_else(|| pattern.speed.multiplier());
|
||||
@@ -634,13 +665,13 @@ impl SequencerState {
|
||||
.script_engine
|
||||
.evaluate_with_trace(script, &ctx, &mut trace)
|
||||
{
|
||||
self.step_traces.insert(
|
||||
Arc::make_mut(&mut self.step_traces).insert(
|
||||
(active.bank, active.pattern, source_idx),
|
||||
std::mem::take(&mut trace),
|
||||
);
|
||||
for cmd in cmds {
|
||||
self.event_count += 1;
|
||||
result.audio_commands.push(cmd);
|
||||
self.buf_audio_commands.push(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -681,18 +712,18 @@ impl SequencerState {
|
||||
|
||||
let mut chain_transitions = Vec::new();
|
||||
for id in completed {
|
||||
let chain_key = format!("__chain_{}_{}__", id.bank, id.pattern);
|
||||
if let Some(Value::Str(s, _)) = vars.get(&chain_key) {
|
||||
let chain_key = self.key_cache.chain_key(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));
|
||||
}
|
||||
}
|
||||
vars.remove(&chain_key);
|
||||
vars.remove(chain_key);
|
||||
}
|
||||
|
||||
for id in stopped {
|
||||
let chain_key = format!("__chain_{}_{}__", id.bank, id.pattern);
|
||||
vars.remove(&chain_key);
|
||||
let chain_key = self.key_cache.chain_key(id.bank, id.pattern);
|
||||
vars.remove(chain_key);
|
||||
}
|
||||
|
||||
VariableReads {
|
||||
@@ -738,7 +769,7 @@ impl SequencerState {
|
||||
iter: a.iter,
|
||||
})
|
||||
.collect(),
|
||||
step_traces: self.step_traces.clone(),
|
||||
step_traces: Arc::clone(&self.step_traces),
|
||||
event_count: self.event_count,
|
||||
dropped_events: self.dropped_events,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user