devalang_core/core/audio/loader/
trigger.rs

1use 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}