devalang_core/core/audio/loader/
trigger.rs1use crate::core::{parser::statement::StatementKind, store::variable::VariableTable};
2use devalang_types::{Duration, Value};
3
4pub fn load_trigger(
5 trigger: &Value,
6 duration: &Duration,
7 _effects: &Option<Value>,
8 base_duration: f32,
9 variable_table: VariableTable,
10) -> (String, f32) {
11 let mut trigger_path = String::new();
12 let mut duration_as_secs = 0.0;
13
14 match trigger {
15 Value::String(src) => {
16 trigger_path = src.to_string();
17 }
18 Value::Identifier(src) => {
19 trigger_path = src.to_string();
20 }
21
22 Value::Map(map) => {
23 if let Some(Value::String(src)) = map.get("entity") {
24 trigger_path = format!("devalang://bank/{}", src);
25 } else if let Some(Value::Identifier(src)) = map.get("entity") {
26 trigger_path = format!("devalang://bank/{}", src);
27 } else {
28 eprintln!(
29 "❌ Trigger map must contain an 'entity' key with a string or identifier value."
30 );
31 }
32 }
33 Value::Sample(src) => {
34 trigger_path = src.to_string();
35 }
36 Value::Statement(stmt) => {
37 if let StatementKind::Trigger {
38 entity,
39 duration: _,
40 effects: _,
41 } = &stmt.kind
42 {
43 trigger_path = entity.clone();
44 } else {
45 eprintln!(
46 "❌ Trigger statement must be of type 'Trigger', found: {:?}",
47 stmt.kind
48 );
49 }
50 }
51 _ => {
52 eprintln!(
53 "❌ Invalid trigger type. Expected a string or identifier variable, found: {:?}",
54 trigger
55 );
56 }
57 }
58
59 match duration {
60 Duration::Identifier(duration_identifier) => {
61 if duration_identifier == "auto" {
62 duration_as_secs = base_duration;
63 } else if let Some(Value::Number(num)) = variable_table.get(duration_identifier) {
64 duration_as_secs = *num;
65 } else if let Some(Value::String(num_str)) = variable_table.get(duration_identifier) {
66 duration_as_secs = num_str.parse::<f32>().unwrap_or(base_duration);
67 } else if let Some(Value::Identifier(num_str)) = variable_table.get(duration_identifier)
68 {
69 duration_as_secs = num_str.parse::<f32>().unwrap_or(base_duration);
70 } else {
71 eprintln!("❌ Invalid duration identifier: {}", duration_identifier);
72 }
73 }
74
75 Duration::Number(num) => {
76 duration_as_secs = *num;
77 }
78
79 Duration::Auto => {
80 duration_as_secs = base_duration;
81 }
82
83 Duration::Beat(beat_str) => {
84 let parts: Vec<&str> = beat_str.split('/').collect();
85
86 if parts.len() == 2 {
87 let numerator: f32 = parts[0].parse().unwrap_or(1.0);
88 let denominator: f32 = parts[1].parse().unwrap_or(1.0);
89 duration_as_secs = (numerator / denominator) * base_duration;
90 } else {
91 eprintln!("❌ Invalid beat duration format: {}", beat_str);
92 }
93 }
94 }
95
96 (trigger_path, duration_as_secs)
97}