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