Interface/
interfaces.rs

1use std::net::UdpSocket;
2use std::io;
3use std::thread::sleep;
4use std::time::{Duration, Instant};
5use Common::fixture::{MAX_CHANNEL, calculate_dmx_values};
6use crate::artnet::ArtnetInterface;
7
8const TARGET: &str = "255.255.255.255:6454";
9const FREQUENCY: u64 = 23;
10
11/// Trait that should be implemented by all interfaces. For now, there is no possibility to modularly create a
12/// DmxInterface. TODO
13pub trait DmxInterface {
14    /// Sends universes to fixtures.
15    ///
16    /// # Arguments
17    ///
18    /// * 'local_universe_index' - If an interface can output more than one universe, this parameter is set to the
19    ///                            universe we want to output on (0-indexed)
20    /// * 'data' - An Array with all the DMX-values of the universe we want to output
21    fn send_universe(&self, local_universe_index: u16, data: &[u8;MAX_CHANNEL as usize]) -> Result<(), io::Error>;
22}
23
24/// Initiates the interfaces, then calculates the DMX-values and outputs them to the interfaces. For now, this function
25/// outputs the DMX-values all to artnet, but this should later be changed to allow all interfaces, that implement the
26/// trait ['DmxInterface']. TODO
27pub fn dmx_output_loop() -> io::Result<()> {
28    let socket = UdpSocket::bind("0.0.0.0:0")?;
29    socket.set_broadcast(true)?;
30    
31    let artnet_interface: Box<dyn DmxInterface> = Box::new(ArtnetInterface::new(socket, TARGET.to_string()));
32
33    println!("Starting artnet");
34
35
36    loop {
37        let start = Instant::now();
38
39        let universes = calculate_dmx_values();
40
41        for (universe_index, data) in universes.iter().enumerate() {
42            artnet_interface.send_universe(universe_index as u16, data)?;
43        }
44
45        let elapsed = start.elapsed();
46        if elapsed < Duration::from_millis(FREQUENCY) {
47            sleep(Duration::from_millis(FREQUENCY) - elapsed);
48        }
49
50
51    }
52}