mleml/extra/builtin/
mixer_template.rs1use std::mem::discriminant;
2
3use dasp::frame::Stereo;
4
5use crate::{
6 resource::{
7 JsonArray, LeftoverSound, Mixer, PremixedSound, ResConfig, ResState, Resource, StringError,
8 },
9 types::Sound,
10};
11
12pub struct SimpleMixer<'a> {
14 name: String,
15 id: String,
16 desc: String,
17 schema: ResConfig,
18 values: ResConfig,
19 mix: fn(
20 &[(bool, &'a [Stereo<f32>])],
21 u32,
22 &ResConfig,
23 &ResState,
24 ) -> Result<(Box<Sound>, Box<ResState>, LeftoverSound<'a>), StringError>,
25 check_state: fn(&ResState) -> bool,
26}
27
28impl<'a> SimpleMixer<'a> {
29 pub fn new(
31 name: String,
32 id: String,
33 desc: String,
34 schema: ResConfig,
35 values: ResConfig,
36 mix: fn(
37 PremixedSound,
38 u32,
39 &ResConfig,
40 &ResState,
41 ) -> Result<(Box<Sound>, Box<ResState>, LeftoverSound<'a>), StringError>,
42 check_state: fn(&ResState) -> bool,
43 ) -> Self {
44 SimpleMixer {
45 name,
46 id,
47 desc,
48 schema,
49 values,
50 mix,
51 check_state,
52 }
53 }
54}
55
56impl<'a> Resource for SimpleMixer<'a> {
57 fn orig_name(&self) -> &str {
58 self.name.as_str()
59 }
60
61 fn id(&self) -> &str {
62 self.id.as_str()
63 }
64
65 fn check_config(&self, conf: &ResConfig) -> Result<(), StringError> {
66 match json_array_find_deviation(&self.schema, conf) {
67 Some(i) => Err(StringError(format!("type mismatch at index {}", i))),
68 None => Ok(()),
69 }
70 }
71
72 fn check_state(&self, state: &ResState) -> Option<()> {
73 (self.check_state)(state).then_some(())
74 }
75
76 fn description(&self) -> &str {
77 self.desc.as_str()
78 }
79}
80
81impl<'a> Mixer<'a> for SimpleMixer<'a> {
82 fn get_values(&self) -> ResConfig {
83 self.values.clone()
84 }
85
86 fn mix(
87 &self,
88 channels: PremixedSound<'a>,
89 play_time: u32,
90 conf: &ResConfig,
91 state: &ResState,
92 ) -> Result<(Box<Sound>, Box<ResState>, LeftoverSound<'a>), StringError> {
93 (self.mix)(channels, play_time, conf, state)
94 }
95}
96
97fn json_array_find_deviation(reference: &JsonArray, given: &JsonArray) -> Option<usize> {
98 (0..given.len())
99 .find(|&i| discriminant(&reference.as_slice()[i]) != discriminant(&given.as_slice()[i]))
100}