gled-core 2.30.1

The engine of gled without a user interface: inputs, timing, rendering, Art-Net/DMX output and storage
Documentation
//! Capturing MIDI messages for learning a controller binding: the engine
//! side. The learning itself runs in the interface (`gled_ui::midi_learn`).

use kanal::{Receiver, Sender, unbounded};
use once_cell::sync::OnceCell;
use std::sync::atomic::{AtomicBool, Ordering::Relaxed};

static STREAM_ENABLED: AtomicBool = AtomicBool::new(false);
static LEARN_ACTIVE: AtomicBool = AtomicBool::new(false);
static SENDER: OnceCell<Sender<[u8; 3]>> = OnceCell::new();

pub(crate) fn init() -> Receiver<[u8; 3]> {
    let (sender, receiver) = unbounded();
    let _ = SENDER.set(sender);
    receiver
}

pub(crate) fn set_streaming_enabled(enabled: bool) {
    STREAM_ENABLED.store(enabled, Relaxed);

    if !enabled {
        LEARN_ACTIVE.store(false, Relaxed);
    }
}

/// Whether an interface waits for learn input; only then is it captured.
pub(crate) fn set_learn_active(active: bool) {
    LEARN_ACTIVE.store(active, Relaxed);
}

pub(crate) fn capture(message: &[u8]) -> bool {
    if message.len() != 3 {
        return false;
    }

    if !STREAM_ENABLED.load(Relaxed) || !LEARN_ACTIVE.load(Relaxed) {
        return false;
    }

    if let Some(sender) = SENDER.get() {
        let _ = sender.send([message[0], message[1], message[2]]);
        return true;
    }

    false
}