Skip to content

Repository files navigation

Crates.io VersionDocs.rsFollowing released Bevy versions

in bengali, jonmo means "birth"

jonmo provides an ergonomic, functional, and declarative API for specifying Bevy system dependency graphs, where "output" handles to nodes of the graph are canonically referred to as "signals". Building upon these signals, jonmo offers a high level entity builder which enables one to declare reactive entities, components, and children using a familiar fluent syntax with semantics and API ported from the incredible FRP signals of futures-signals and its web UI dependents MoonZoon and Dominator.

The runtime of jonmo is quite simple; every frame, the outputs of systems are forwarded to their dependants, recursively. The complexity and power of jonmo really emerges from its monadic signal combinators, defined within the SignalExt, SignalVecExt, and SignalMapExt traits (ported from futures-signals' traits of the same name), which internally manage special Bevy systems that allow for the declarative composition of complex data flows with minimalistic, high-level, signals-oriented methods.

assorted features:

  • fine-grained reactivity for all entities, components, and children
  • diff-less constant-time reactive updates for collections (available through MutableVec and MutableBTreeMap)
  • automated system lifecycle management when using the builder API, simple component on-remove hook when not
  • polling API for when one needs an escape hatch from the regular push-based output semantics (polling is used sparsely internally for some combinators)
  • either wrappers (a la https://github.com/rayon-rs/either) and type-erased signals (via boxing) for cheap and flexible management of distinct signal types from different branches of logic
  • no_std compatible

examples

//! Simple counter example, ported from a similar example in haalka.use bevy::prelude::*;use jonmo::prelude::*;fnmain(){App::new().add_plugins((DefaultPlugins,JonmoPlugin)).add_systems(Startup,(
|world:&mutWorld| {ui_root().spawn(world);},
camera,),).run();}#[derive(Component,Clone,Deref,DerefMut)]structCounter(i32);fnui_root() -> jonmo::Builder{let counter_holder = LazyEntity::new();
jonmo::Builder::from(Node{width:Val::Percent(100.0),height:Val::Percent(100.0),justify_content:JustifyContent::Center,align_items:AlignItems::Center,
..default()}).child(
jonmo::Builder::from(Node{flex_direction:FlexDirection::Row,column_gap:Val::Px(15.0),align_items:AlignItems::Center,padding:UiRect::all(Val::Px(25.)),
..default()}).insert(Counter(0)).lazy_entity(counter_holder.clone()).child(counter_button(counter_holder.clone(),PINK,"-", -1)).child(
jonmo::Builder::from((Node::default(),TextFont::from_font_size(25.))).component_signal(
signal::from_component_changed::<Counter>(counter_holder.clone()).map_in(deref_copied).map_in_ref(ToString::to_string).map_in(Text).map_in(Some),),).child(counter_button(counter_holder,BLUE,"+",1)),)}fncounter_button(counter_holder:LazyEntity,color:Color,label:&'staticstr,step:i32) -> jonmo::Builder{
jonmo::Builder::from((Node{width:Val::Px(45.0),justify_content:JustifyContent::Center,align_items:AlignItems::Center,border_radius:BorderRadius::MAX,
..default()},BackgroundColor(color),)).observe(move |_:On<Pointer<Click>>,mutcounters:Query<&mutCounter>| {**counters.get_mut(*counter_holder).unwrap() += step;}).child(jonmo::Builder::from((Text::from(label),TextFont::from_font_size(25.))))}fncamera(mutcommands:Commands){
commands.spawn(Camera2d);}

on the web

All examples are compiled to wasm for both webgl2 and webgpu (check compatibility) and deployed to github pages.

  • basicwebgl2webgpu

    a simple increasing timer without using the entity builder, showcasing the least invasive way to start using jonmo signals in existing Bevy apps

  • basic_builder_injectwebgl2webgpu

    a simple increasing timer injecting the entity builder into an existing entity, showcasing a less invasive way to start using jonmo signals in existing Bevy apps.

  • basic_builderwebgl2webgpu

    a simple increasing timer using the entity builder, showcasing the recommended, idiomatic way to use jonmo signals

  • counterwebgl2webgpu

    the example above, a simple counter

  • lifetimeswebgl2webgpu

    a reactive enumerated list of colors, each with an independent lifetime timer

  • letterswebgl2webgpu

    key press counter with swappable save states, showcasing map reactivity

  • filterswebgl2webgpu

    diverse filtering options for a list of items, showcasing vector reactivity

Bevy compatibility

bevyjonmo
0.180.7
0.170.6
0.160.3
0.150.1

license

All code in this repository is dual-licensed under either:

at your option.

your contributions

Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.

About

ergonomic Bevy-native reactivity powered by FRP signals

Resources

Stars

24 stars

Watchers

2 watching

Forks

Releases

Used by

Contributors

Languages