103 lines
2.8 KiB
Rust
103 lines
2.8 KiB
Rust
use arc_swap::ArcSwap;
|
|
use parking_lot::Mutex;
|
|
use std::collections::hash_map::DefaultHasher;
|
|
use std::collections::HashMap;
|
|
use std::hash::{Hash, Hasher};
|
|
use std::sync::Arc;
|
|
|
|
use rand::rngs::StdRng;
|
|
use rand::SeedableRng;
|
|
|
|
use crate::model::{ScriptEngine, StepContext, Value};
|
|
use crate::state::{EditorContext, StackCache};
|
|
|
|
pub fn update_cache(editor_ctx: &EditorContext) {
|
|
let lines = editor_ctx.editor.lines();
|
|
let cursor_line = editor_ctx.editor.cursor().0;
|
|
|
|
let mut hasher = DefaultHasher::new();
|
|
for (i, line) in lines.iter().enumerate() {
|
|
if i > cursor_line {
|
|
break;
|
|
}
|
|
line.hash(&mut hasher);
|
|
}
|
|
let lines_hash = hasher.finish();
|
|
|
|
if let Some(ref c) = *editor_ctx.stack_cache.borrow() {
|
|
if c.cursor_line == cursor_line && c.lines_hash == lines_hash {
|
|
return;
|
|
}
|
|
}
|
|
|
|
let partial: Vec<&str> = lines
|
|
.iter()
|
|
.take(cursor_line + 1)
|
|
.map(|s| s.as_str())
|
|
.collect();
|
|
let script = partial.join("\n");
|
|
|
|
let result = if script.trim().is_empty() {
|
|
"Stack: []".to_string()
|
|
} else {
|
|
let vars = Arc::new(ArcSwap::from_pointee(HashMap::new()));
|
|
let dict = Arc::new(Mutex::new(HashMap::new()));
|
|
let rng = Arc::new(Mutex::new(StdRng::seed_from_u64(42)));
|
|
let mut engine = ScriptEngine::new(vars, dict, rng);
|
|
|
|
let ctx = StepContext {
|
|
step: 0,
|
|
beat: 0.0,
|
|
bank: 0,
|
|
pattern: 0,
|
|
tempo: 120.0,
|
|
phase: 0.0,
|
|
slot: 0,
|
|
runs: 0,
|
|
iter: 0,
|
|
speed: 1.0,
|
|
fill: false,
|
|
nudge_secs: 0.0,
|
|
cc_access: None,
|
|
speed_key: "",
|
|
mouse_x: 0.5,
|
|
mouse_y: 0.5,
|
|
mouse_down: 0.0,
|
|
};
|
|
|
|
match engine.evaluate(&script, &ctx) {
|
|
Ok(_) => {
|
|
let stack = engine.stack();
|
|
let formatted: Vec<String> = stack.iter().map(format_value).collect();
|
|
format!("Stack: [{}]", formatted.join(" "))
|
|
}
|
|
Err(e) => format!("Error: {e}"),
|
|
}
|
|
};
|
|
|
|
*editor_ctx.stack_cache.borrow_mut() = Some(StackCache {
|
|
cursor_line,
|
|
lines_hash,
|
|
result,
|
|
});
|
|
}
|
|
|
|
fn format_value(v: &Value) -> String {
|
|
match v {
|
|
Value::Int(n, _) => n.to_string(),
|
|
Value::Float(f, _) => {
|
|
if f.fract() == 0.0 && f.abs() < 1_000_000.0 {
|
|
format!("{f:.1}")
|
|
} else {
|
|
format!("{f:.4}")
|
|
}
|
|
}
|
|
Value::Str(s, _) => format!("\"{s}\""),
|
|
Value::Quotation(..) => "[...]".to_string(),
|
|
Value::CycleList(items) | Value::ArpList(items) => {
|
|
let inner: Vec<String> = items.iter().map(format_value).collect();
|
|
format!("({})", inner.join(" "))
|
|
}
|
|
}
|
|
}
|