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