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 { entity, duration: _, effects: _ } = &stmt.kind {
41                trigger_path = entity.clone();
42            } else {
43                eprintln!("❌ Trigger statement must be of type 'Trigger', found: {:?}", stmt.kind);
44            }
45        }
46        _ => {
47            eprintln!(
48                "❌ Invalid trigger type. Expected a string or identifier variable, found: {:?}",
49                trigger
50            );
51        }
52    }
53
54    match duration {
55        Duration::Identifier(duration_identifier) => {
56            if duration_identifier == "auto" {
57                duration_as_secs = base_duration;
58            } else if let Some(Value::Number(num)) = variable_table.get(duration_identifier) {
59                duration_as_secs = *num;
60            } else if let Some(Value::String(num_str)) = variable_table.get(duration_identifier) {
61                duration_as_secs = num_str.parse::<f32>().unwrap_or(base_duration);
62            } else if
63                let Some(Value::Identifier(num_str)) = variable_table.get(duration_identifier)
64            {
65                duration_as_secs = num_str.parse::<f32>().unwrap_or(base_duration);
66            } else {
67                eprintln!("❌ Invalid duration identifier: {}", duration_identifier);
68            }
69        }
70
71        Duration::Number(num) => {
72            duration_as_secs = *num;
73        }
74
75        Duration::Auto => {
76            duration_as_secs = base_duration;
77        }
78
79        Duration::Beat(beat_str) => {
80            let parts: Vec<&str> = beat_str.split('/').collect();
81
82            if parts.len() == 2 {
83                let numerator: f32 = parts[0].parse().unwrap_or(1.0);
84                let denominator: f32 = parts[1].parse().unwrap_or(1.0);
85                duration_as_secs = (numerator / denominator) * base_duration;
86            } else {
87                eprintln!("❌ Invalid beat duration format: {}", beat_str);
88            }
89        }
90
91    }
92
93    (trigger_path, duration_as_secs)
94}