7 releases (breaking)

0.7.0 May 11, 2024
0.6.0 Mar 7, 2023
0.5.0 Nov 17, 2022
0.4.0 Oct 16, 2022
0.1.0 May 29, 2022

#789 in Network programming

MIT/Apache

33KB
255 lines

bevy_rosc

Bevy tracking crates.io docs.rs

Send and receive OSC 1.0 messages in bevy with rosc.

Usage

To quickly get started just add the plugin to your app:

use bevy::prelude::*;

use bevy_rosc::OscMethod;
use bevy_rosc::{BevyRoscPlugin, SingleAddressOscMethod};

fn main() {
    App::new()
        // Minimal Bevy plugins
        .add_plugins(MinimalPlugins)
        // Add the bevy_rosc plugin and have it listen on port 31337
        .add_plugins(BevyRoscPlugin::new("0.0.0.0:31337").unwrap())
        .run();
}

Now you can add just add SingleAddressOscMethod or MultiAddressOscMethod to your entities.

OSC methods are components that have one or more OSC address and can receive OSC messages that have a matching address pattern.

fn spawn_entity(mut commands: Commands) {
    commands.
        spawn(
            SingleAddressOscMethod::new(vec!["/some/osc/address".into()]).unwrap()
        );
}

Then you can start retrieving OSC messages from the component!

/// System that listens for any `SingleAddressOscMethod` that has changed and prints received message
fn print_received_osc_packets(
    mut query: Query<&mut SingleAddressOscMethod, Changed<SingleAddressOscMethod>>,
) {
    for mut osc_receiver in query.iter_mut() {
        let new_msg = osc_receiver.get_message(); // Gets the oldest received message, or `None` if there are no more left
        if let Some(msg) = new_msg { println!("Method {:?} received: {:?}", osc_receiver.get_addresses(), msg) }
    }
}

See examples/plugin.rs for a full example.

If you want to receive OSC messages directly into your custom component, see examples/custom_osc_method.rs

Data flow

graph TD;
    server1[UDP Server 1] --> dispatcher
    server2[UDP Server 2] --> dispatcher
    serverdot[...] --> dispatcher
    server3[Any other source] --> dispatcher
    dispatcher -- Write --> OscDispatchEvent{{OscDispatchEvent}}
    OscDispatchEvent -. Read .-> system1["method_dispatcher_system::&ltSingleAddressOscMethod&gt"]
    OscDispatchEvent -. Read ..-> system2["method_dispatcher_system::&ltMultiAddressOscMethod&gt"]
    OscDispatchEvent -. Read ...-> system3["method_dispatcher_system::&ltMyOscMethod&gt"]
    system1 -- Match & Receive --> comp1[(SingleAddressOscMethod)]
    system2 -- Match & Receive --> comp2[(MultiAddressOscMethod)]
    system3 -- Match & Receive --> comp3[(MyOscMethod)]

Any OSC packet that was received by any means (usually a UDP server) is sent to the dispatcher. It unpacks the OSC packet, retrieves all messages from it and writes an OscDispatchEvent containing them. From there, the method dispatcher system (One for each OscMethod-component) reads the event and iterates over all OSC method components. If the component's address matches the message's address pattern, the message is received by the component.

The default OSC methods SingleAddressOscMethod and MultiAddressOscMethod will just store the received message in a vector, from which you have to retrieve them to do anything with them. Your custom OSC component however can directly act on receiving the messages.

Bevy Compatibility

bevy bevy_rosc
0.13 0.7
0.10 0.6
0.9 0.5
0.8 0.4
0.7 0.1

Dependencies

~19–46MB
~753K SLoC