Skip to main content

ReactAppExt

Trait ReactAppExt 

Source
pub trait ReactAppExt {
    // Required methods
    fn add_react_message<T>(&mut self) -> &mut Self
       where T: ReactPayload,
             for<'a> <T as Event>::Trigger<'a>: Default;
    fn add_react_handler<E, B, M, S>(&mut self, observer: S) -> &mut Self
       where E: ReactPayload,
             for<'a> <E as Event>::Trigger<'a>: Default,
             B: Bundle,
             S: IntoObserverSystem<E, B, M>;
    fn add_react_request<T>(&mut self) -> &mut Self
       where T: ReactRequest;
    fn add_react_request_handler<E, B, M, S>(
        &mut self,
        observer: S,
    ) -> &mut Self
       where E: Event + RequestEvent,
             for<'a> <E as Event>::Trigger<'a>: Default,
             B: Bundle,
             S: IntoObserverSystem<E, B, M>;
    fn add_react_event<E>(&mut self) -> &mut Self
       where E: ReactEvent;
    fn add_react_filter<T>(&mut self) -> &mut Self
       where T: ReactFilter + DeserializeOwned + TS;
    fn export_react_typescript(&self, path: impl AsRef<Path>) -> Result<()>;
}
Expand description

Registers typed React message payloads on a Bevy App.

Required Methods§

Source

fn add_react_message<T>(&mut self) -> &mut Self
where T: ReactPayload, for<'a> <T as Event>::Trigger<'a>: Default,

Register a typed React message payload without attaching an observer.

After this, an emit(T::NAME, value) from the React app deserializes value into T and triggers it. Prefer add_react_handler unless you want to register the type and observe it separately.

Source

fn add_react_handler<E, B, M, S>(&mut self, observer: S) -> &mut Self
where E: ReactPayload, for<'a> <E as Event>::Trigger<'a>: Default, B: Bundle, S: IntoObserverSystem<E, B, M>,

Register a payload and attach an observer for it in one call.

The payload type is inferred from the observer’s On<T> parameter, so you never name it twice. Call it again with another observer to add more handlers for the same message — registration is idempotent.

app.add_react_handler(|count: On<Count>, mut desired: ResMut<DesiredCubes>| {
    desired.0 = count.event().0;
});
Source

fn add_react_request<T>(&mut self) -> &mut Self
where T: ReactRequest,

Register a typed React request without attaching an observer. Prefer add_react_request_handler.

Source

fn add_react_request_handler<E, B, M, S>(&mut self, observer: S) -> &mut Self
where E: Event + RequestEvent, for<'a> <E as Event>::Trigger<'a>: Default, B: Bundle, S: IntoObserverSystem<E, B, M>,

Register a request and attach its observer in one call.

The request type is inferred from the observer’s On<Request<T>> parameter. The observer answers the request via Request::respond.

app.add_react_request_handler(|req: On<Request<BoardGet>>, board: Res<Board>| {
    req.respond(board.clone());
});
Source

fn add_react_event<E>(&mut self) -> &mut Self
where E: ReactEvent,

Register a Bevy → React event type so it appears in the generated ReactEvents map and bevy.on typing. Sending an event with ReactEvents does not require this, but then the type won’t be known to the exporter.

Source

fn add_react_filter<T>(&mut self) -> &mut Self

Register a custom filter type (usually a #[react_filter] struct) so the filter style chain can resolve it by T::NAME — and so the exporter can mirror its params type into the generated TypeScript.

The built-in filters (blur, brightness, …) are registered automatically by ReactUiPlugin; call this only for your own filters. Like events, keep the call in your single register_bindings site so the exporter path sees the same filters the running app does — a filter registered only at runtime never appears in the generated typing (see export_react_typescript).

To shadow a built-in name, register after ReactUiPlugin is added: the plugin’s build registers the built-ins and would replace an earlier custom (with a warn), while the exporter — which never runs the plugin — would still show yours, silently diverging the generated types from runtime.

Source

fn export_react_typescript(&self, path: impl AsRef<Path>) -> Result<()>

Write a self-contained TypeScript module (conventionally src/bevy.ts) mirroring every registered React binding to path.

The generated module covers all four typed surfaces in one pass: a type declaration per payload (mirrored from the #[react_message] / #[react_request] / #[react_event] structs and the filter params types via ts-rs), the ReactMessages/ReactRequests/ReactEvents name→type maps, a declare module "bevy-react" block augmenting the BevyFilters interface with every registered filter (built-ins included, so the filter style field types each name’s params), typed emit/request/ on wrappers, and a structured bevy proxy whose nested methods come from dotted request names ("board.get"bevy.board.get()). App code imports that typed surface from ./bevy instead of the untyped functions from "bevy-react", so every call is checked against the same structs Bevy serializes and deserializes.

Keep a single registration site: put your add_react_* calls in a register_bindings(app) function that both the real app (e.g. your plugin’s build) and a small exporter entry point call, so a binding can never exist at runtime without appearing in the generated types. Wire the exporter to a CLI flag that returns before app.run(), commit the output, and have CI regenerate + git diff --exit-code to guarantee the TypeScript never drifts from Rust. (See examples/demos/main.rs and its --export-bindings flag, exposed as npm run bevy:generate.)

if std::env::args().nth(1).as_deref() == Some("--export-bindings") {
    let path = std::env::args().nth(2).expect("output path");
    let mut app = App::new();
    register_bindings(&mut app); // the same fn the real app calls
    app.export_react_typescript(&path)?;
    return;
}

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementations on Foreign Types§

Source§

impl ReactAppExt for App

Source§

fn add_react_message<T>(&mut self) -> &mut Self
where T: ReactPayload, for<'a> <T as Event>::Trigger<'a>: Default,

Source§

fn add_react_handler<E, B, M, S>(&mut self, observer: S) -> &mut Self
where E: ReactPayload, for<'a> <E as Event>::Trigger<'a>: Default, B: Bundle, S: IntoObserverSystem<E, B, M>,

Source§

fn add_react_request<T>(&mut self) -> &mut Self
where T: ReactRequest,

Source§

fn add_react_request_handler<E, B, M, S>(&mut self, observer: S) -> &mut Self
where E: Event + RequestEvent, for<'a> <E as Event>::Trigger<'a>: Default, B: Bundle, S: IntoObserverSystem<E, B, M>,

Source§

fn add_react_event<E>(&mut self) -> &mut Self
where E: ReactEvent,

Source§

fn add_react_filter<T>(&mut self) -> &mut Self

Source§

fn export_react_typescript(&self, path: impl AsRef<Path>) -> Result<()>

Implementors§