1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
use bevy::prelude::{App, Commands, Deref, EventWriter, Plugin, Res, ResMut, Resource};
use nannou_osc as osc;
use osc::{Connected, Receiver, Sender};

#[derive(Resource)]
pub struct OscReceiver {
    receiver: Receiver,
}

#[derive(Resource, Deref)]
#[allow(dead_code)]
pub struct OscSender {
    pub sender: Sender<Connected>,
}

#[derive(Resource, Clone)]
pub struct OscLog {
    pub received_packets: Vec<(std::net::SocketAddr, osc::Packet)>,
}

pub struct OscEvent {
    pub addr: std::net::SocketAddr,
    pub packet: osc::Packet,
}

#[derive(Resource)]
pub struct OscSettings {
    pub max_log_packets: usize,
    pub recv_addr: Option<&'static str>,
    pub send_addr: Option<&'static str>,
    pub dbg: bool,
    pub log: bool,
}

impl Default for OscSettings {
    fn default() -> Self {
        Self {
            recv_addr: Some("127.0.0.1:34254"),
            send_addr: None,
            dbg: true,
            log: true,
            max_log_packets: 5,
        }
    }
}

pub struct Osc;
impl Plugin for Osc {
    fn build(&self, app: &mut App) {
        app.init_resource::<OscSettings>()
            .add_startup_system(osc_setup)
            .add_event::<OscEvent>()
            .add_system(osc_listener_update);
    }
}

fn osc_setup(mut commands: Commands, settings: Res<OscSettings>) {
    if settings.recv_addr.is_some() {
        commands.insert_resource(OscReceiver {
            receiver: Receiver::bind_to(settings.recv_addr.unwrap()).unwrap(), /*osc::receiver(34254).unwrap(),*/
        });
        if settings.dbg {
            println!("OSC Listening on {}", settings.recv_addr.unwrap());
        }
    }

    if settings.send_addr.is_some() {
        commands.insert_resource(OscSender {
            sender: osc::sender()
                .unwrap()
                .connect(settings.send_addr.unwrap())
                .unwrap(),
        });
        if settings.dbg {
            println!("OSC Sending on {}", settings.send_addr.unwrap());
        }
    }

    commands.insert_resource(OscLog {
        received_packets: Vec::with_capacity(settings.max_log_packets),
    });
}

fn osc_listener_update(
    rec: Res<OscReceiver>,
    settings: Res<OscSettings>,
    mut log: ResMut<OscLog>,
    mut osc_events: EventWriter<OscEvent>,
) {
    for (packet, addr) in rec.receiver.try_iter() {
        if log.received_packets.len() > settings.max_log_packets {
            log.received_packets.remove(0);
        }

        let address = addr;

        log.received_packets.push((address, packet.clone()));

        if settings.log {
            osc_log_update(log.clone())
        }

        osc_events.send(OscEvent {
            addr: address,
            packet: packet.clone(),
        });
    }
}

fn osc_log_update(log: OscLog) {
    println!("Log");
    for (_add, p) in log.received_packets.iter() {
        println!("{:?}", p);
    }
}