DEVELOPMENT ENVIRONMENT

~liljamo/bevy_dice

01253fe1583ba20eebbb57a9395631b3e395903f — Jonni Liljamo 3 days ago fe240c8
feat(demo): naive toast system for results
M Cargo.lock => Cargo.lock +277 -1
@@ 646,6 646,7 @@ dependencies = [
 "bevy_egui",
 "bevy_embedded_assets",
 "console_error_panic_hook",
 "web-time",
]

[[package]]


@@ 763,6 764,7 @@ dependencies = [
 "bevy_pbr",
 "bevy_reflect",
 "bevy_render",
 "bevy_sprite",
 "bevy_time",
 "bevy_transform",
 "bevy_utils",


@@ 918,8 920,10 @@ dependencies = [
 "bevy_sprite",
 "bevy_state",
 "bevy_tasks",
 "bevy_text",
 "bevy_time",
 "bevy_transform",
 "bevy_ui",
 "bevy_utils",
 "bevy_window",
 "bevy_winit",


@@ 1293,6 1297,36 @@ dependencies = [
]

[[package]]
name = "bevy_text"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ef071262c5a9afbc39caba4c0b282c7d045fbb5cf33bdab1924bd2343403833"
dependencies = [
 "bevy_app",
 "bevy_asset",
 "bevy_color",
 "bevy_derive",
 "bevy_ecs",
 "bevy_image",
 "bevy_log",
 "bevy_math",
 "bevy_platform",
 "bevy_reflect",
 "bevy_render",
 "bevy_sprite",
 "bevy_transform",
 "bevy_utils",
 "bevy_window",
 "cosmic-text",
 "serde",
 "smallvec",
 "sys-locale",
 "thiserror 2.0.12",
 "tracing",
 "unicode-bidi",
]

[[package]]
name = "bevy_time"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 1335,6 1369,40 @@ dependencies = [
]

[[package]]
name = "bevy_ui"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "110dc5d0059f112263512be8cd7bfe0466dfb7c26b9bf4c74529355249fd23f9"
dependencies = [
 "accesskit",
 "bevy_a11y",
 "bevy_app",
 "bevy_asset",
 "bevy_color",
 "bevy_core_pipeline",
 "bevy_derive",
 "bevy_ecs",
 "bevy_image",
 "bevy_input",
 "bevy_math",
 "bevy_platform",
 "bevy_reflect",
 "bevy_render",
 "bevy_sprite",
 "bevy_text",
 "bevy_transform",
 "bevy_utils",
 "bevy_window",
 "bytemuck",
 "derive_more",
 "nonmax",
 "smallvec",
 "taffy",
 "thiserror 2.0.12",
 "tracing",
]

[[package]]
name = "bevy_utils"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 1783,6 1851,29 @@ dependencies = [
]

[[package]]
name = "cosmic-text"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e418dd4f5128c3e93eab12246391c54a20c496811131f85754dc8152ee207892"
dependencies = [
 "bitflags 2.9.1",
 "fontdb",
 "log",
 "rangemap",
 "rustc-hash 1.1.0",
 "rustybuzz",
 "self_cell",
 "smol_str",
 "swash",
 "sys-locale",
 "ttf-parser 0.21.1",
 "unicode-bidi",
 "unicode-linebreak",
 "unicode-script",
 "unicode-segmentation",
]

[[package]]
name = "crc32fast"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 2165,6 2256,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"

[[package]]
name = "font-types"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02a596f5713680923a2080d86de50fe472fb290693cf0f701187a1c8b36996b7"
dependencies = [
 "bytemuck",
]

[[package]]
name = "fontconfig-parser"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbc773e24e02d4ddd8395fd30dc147524273a83e54e0f312d986ea30de5f5646"
dependencies = [
 "roxmltree",
]

[[package]]
name = "fontdb"
version = "0.16.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0299020c3ef3f60f526a4f64ab4a3d4ce116b1acbf24cdd22da0068e5d81dc3"
dependencies = [
 "fontconfig-parser",
 "log",
 "memmap2",
 "slotmap",
 "tinyvec",
 "ttf-parser 0.20.0",
]

[[package]]
name = "foreign-types"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 2419,6 2542,12 @@ dependencies = [
]

[[package]]
name = "grid"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36119f3a540b086b4e436bb2b588cf98a68863470e0e880f4d0842f112a3183a"

[[package]]
name = "guillotiere"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 3430,7 3559,7 @@ version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22ec719bbf3b2a81c109a4e20b1f129b5566b7dce654bc3872f6a05abf82b2c4"
dependencies = [
 "ttf-parser",
 "ttf-parser 0.25.1",
]

[[package]]


@@ 3800,6 3929,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3d6831663a5098ea164f89cff59c6284e95f4e3c76ce9848d4529f5ccca9bde"

[[package]]
name = "rangemap"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f60fcc7d6849342eff22c4350c8b9a989ee8ceabc4b481253e8946b9fe83d684"

[[package]]
name = "rav1e"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 3882,6 4017,16 @@ dependencies = [
]

[[package]]
name = "read-fonts"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ce8e2ca6b24313587a03ca61bb74c384e2a815bd90cf2866cfc9f5fb7a11fa0"
dependencies = [
 "bytemuck",
 "font-types",
]

[[package]]
name = "rectangle-pack"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 3980,6 4125,12 @@ dependencies = [
]

[[package]]
name = "roxmltree"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c20b6793b5c2fa6553b250154b78d6d0db37e72700ae35fad9387a46f487c97"

[[package]]
name = "rstar"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 4022,6 4173,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2"

[[package]]
name = "rustybuzz"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfb9cf8877777222e4a3bc7eb247e398b56baba500c38c1c46842431adc8b55c"
dependencies = [
 "bitflags 2.9.1",
 "bytemuck",
 "libm",
 "smallvec",
 "ttf-parser 0.21.1",
 "unicode-bidi-mirroring",
 "unicode-ccc",
 "unicode-properties",
 "unicode-script",
]

[[package]]
name = "ruzstd"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 4080,6 4248,12 @@ dependencies = [
]

[[package]]
name = "self_cell"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f7d95a54511e0c7be3f51e8867aa8cf35148d7b9445d44de2f943e2b206e749"

[[package]]
name = "send_wrapper"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 4170,6 4344,16 @@ dependencies = [
]

[[package]]
name = "skrifa"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbe6666ab11018ab91ff7b03f1a3b9fdbecfb610848436fefa5ce50343d3d913"
dependencies = [
 "bytemuck",
 "read-fonts",
]

[[package]]
name = "slab"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 4310,6 4494,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0193cc4331cfd2f3d2011ef287590868599a2f33c3e69bc22c1a3d3acf9e02fb"

[[package]]
name = "swash"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5dce3f0af95643c855cdc449fbaa17d8c2cd08e0b00a49a6babcbe6e71667f3d"
dependencies = [
 "skrifa",
 "yazi",
 "zeno",
]

[[package]]
name = "syn"
version = "2.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 4321,6 4516,15 @@ dependencies = [
]

[[package]]
name = "sys-locale"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eab9a99a024a169fe8a903cf9d4a3b3601109bcc13bd9e3c6fff259138626c4"
dependencies = [
 "libc",
]

[[package]]
name = "system-deps"
version = "6.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 4334,6 4538,18 @@ dependencies = [
]

[[package]]
name = "taffy"
version = "0.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab4f4d046dd956a47a7e1a2947083d7ac3e6aa3cfaaead36173ceaa5ab11878c"
dependencies = [
 "arrayvec",
 "grid",
 "serde",
 "slotmap",
]

[[package]]
name = "target-lexicon"
version = "0.12.16"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 4572,6 4788,18 @@ dependencies = [

[[package]]
name = "ttf-parser"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17f77d76d837a7830fe1d4f12b7b4ba4192c1888001c7164257e4bc6d21d96b4"

[[package]]
name = "ttf-parser"
version = "0.21.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8"

[[package]]
name = "ttf-parser"
version = "0.25.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2df906b07856748fa3f6e0ad0cbaa047052d4a7dd609e231c4f72cee8c36f31"


@@ 4595,12 4823,48 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f"

[[package]]
name = "unicode-bidi"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c1cb5db39152898a79168971543b1cb5020dff7fe43c8dc468b0885f5e29df5"

[[package]]
name = "unicode-bidi-mirroring"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23cb788ffebc92c5948d0e997106233eeb1d8b9512f93f41651f52b6c5f5af86"

[[package]]
name = "unicode-ccc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1df77b101bcc4ea3d78dafc5ad7e4f58ceffe0b2b16bf446aeb50b6cb4157656"

[[package]]
name = "unicode-ident"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"

[[package]]
name = "unicode-linebreak"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f"

[[package]]
name = "unicode-properties"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0"

[[package]]
name = "unicode-script"
version = "0.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fb421b350c9aff471779e262955939f565ec18b86c15364e6bdf0d662ca7c1f"

[[package]]
name = "unicode-segmentation"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"


@@ 5528,6 5792,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a62ce76d9b56901b19a74f19431b0d8b3bc7ca4ad685a746dfd78ca8f4fc6bda"

[[package]]
name = "yazi"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e01738255b5a16e78bbb83e7fbba0a1e7dd506905cfc53f4622d89015a03fbb5"

[[package]]
name = "zeno"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6df3dc4292935e51816d896edcd52aa30bc297907c26167fec31e2b0c6a32524"

[[package]]
name = "zerocopy"
version = "0.8.25"
source = "registry+https://github.com/rust-lang/crates.io-index"

M crates/bevy_dice_demo/Cargo.toml => crates/bevy_dice_demo/Cargo.toml +15 -2
@@ 5,8 5,18 @@ edition.workspace = true

[features]
default = ["debug", "wayland"]
debug = ["bevy_dice/debug", "avian3d/debug-plugin", "dep:bevy-inspector-egui"]
wasm = ["bevy/webgl2", "bevy_dice/wasm", "dep:console_error_panic_hook"]
debug = [
  "bevy_dice/debug",
  "bevy/bevy_ui_debug",
  "avian3d/debug-plugin",
  "dep:bevy-inspector-egui",
]
wasm = [
  "bevy/webgl2",
  "bevy_dice/wasm",
  "dep:console_error_panic_hook",
  "dep:web-time",
]
wayland = ["bevy/wayland"]

[dependencies]


@@ 19,8 29,10 @@ bevy = { version = "0.16", default-features = false, features = [
  "bevy_pbr",
  "bevy_render",
  "bevy_state",
  "bevy_ui",
  "bevy_window",
  "bevy_winit",
  "default_font",
  "multi_threaded",
  "png",
  "tonemapping_luts",


@@ 32,3 44,4 @@ bevy_egui = { version = "0.34", default-features = false, features = [
] }
bevy-inspector-egui = { version = "0.31", optional = true }
console_error_panic_hook = { version = "0.1", optional = true }
web-time = { version = "1", optional = true }

M crates/bevy_dice_demo/src/main.rs => crates/bevy_dice_demo/src/main.rs +11 -3
@@ 16,6 16,8 @@ use bevy_inspector_egui::quick::WorldInspectorPlugin;
#[cfg(feature = "wasm")]
extern crate console_error_panic_hook;

mod toast;

fn main() {
    #[cfg(feature = "wasm")]
    std::panic::set_hook(Box::new(console_error_panic_hook::hook));


@@ 48,7 50,13 @@ fn main() {
        WorldInspectorPlugin::default(),
    ));

    app.add_plugins(DicePlugin);
    #[cfg(feature = "debug")]
    app.insert_resource(UiDebugOptions {
        enabled: true,
        ..Default::default()
    });

    app.add_plugins(DicePlugin).add_plugins(toast::ToastPlugin);

    app.init_resource::<ExampleAssets>();
    app.init_state::<ExampleState>()


@@ 208,8 216,8 @@ fn despawn_dice(
    }
}

fn show_die_result(trigger: Trigger<DieResult>) {
    info!("{}: {}", trigger.id, trigger.result);
fn show_die_result(trigger: Trigger<DieResult>, mut commands: Commands) {
    commands.trigger(toast::ShowResultToast(trigger.id, trigger.result));
}

fn rotate_light(mut q_lights: Query<&mut Transform, With<PointLight>>, r_time: Res<Time>) {

A crates/bevy_dice_demo/src/toast.rs => crates/bevy_dice_demo/src/toast.rs +114 -0
@@ 0,0 1,114 @@
/*
 * Copyright (C) 2025 Jonni Liljamo <jonni@liljamo.com>
 *
 * This file is licensed under MIT, see LICENSE for more information.
 */

use std::time::Duration;
#[cfg(not(feature = "wasm"))]
use std::time::Instant;
#[cfg(feature = "wasm")]
use web_time::Instant;

use bevy::{color::palettes::tailwind::*, prelude::*};

pub struct ToastPlugin;

impl Plugin for ToastPlugin {
    fn build(&self, app: &mut App) {
        app.add_systems(Startup, setup)
            .add_systems(Update, cleanup_toasts);

        app.add_event::<ShowResultToast>()
            .add_observer(show_result_toast);
    }
}

#[derive(Component)]
struct ToastUI;

#[derive(Component)]
struct Toast {
    spawned: Instant,
}

fn setup(mut commands: Commands) {
    commands.spawn((
        Node {
            width: Val::Percent(100.0),
            height: Val::Percent(100.0),
            flex_direction: FlexDirection::Column,
            align_items: AlignItems::FlexEnd,
            padding: UiRect::all(Val::Px(8.0)),
            overflow: Overflow::scroll_y(),
            ..Default::default()
        },
        ToastUI,
    ));
}

#[derive(Event)]
pub struct ShowResultToast(pub u32, pub u8);

fn show_result_toast(
    trigger: Trigger<ShowResultToast>,
    mut commands: Commands,
    q_toast_ui: Query<Entity, With<ToastUI>>,
) {
    if let Ok(toast_ui) = q_toast_ui.single() {
        let toast = commands
            .spawn((
                Toast {
                    spawned: Instant::now(),
                },
                Node {
                    width: Val::Px(180.0),
                    height: Val::Px(60.0),
                    border: UiRect::all(Val::Px(2.0)),
                    flex_direction: FlexDirection::Column,
                    justify_content: JustifyContent::Center,
                    align_items: AlignItems::Center,
                    ..Default::default()
                },
                BackgroundColor(Color::from(EMERALD_400)),
                BorderColor(Color::from(EMERALD_700)),
                BorderRadius::all(Val::Px(10.0)),
                BoxShadow::new(
                    Color::BLACK.with_alpha(0.8),
                    Val::Px(4.0),
                    Val::Px(4.0),
                    Val::DEFAULT,
                    Val::DEFAULT,
                ),
                children![
                    (
                        Text::new(format!("Die {}", trigger.0)),
                        TextFont {
                            font_size: 18.0,
                            ..Default::default()
                        },
                        TextColor(Color::BLACK),
                    ),
                    (
                        Text::new(format!("Result: {}", trigger.1)),
                        TextFont {
                            font_size: 20.0,
                            ..Default::default()
                        },
                        TextColor(Color::WHITE),
                    )
                ],
            ))
            .id();

        commands.entity(toast_ui).add_child(toast);
    }
}

fn cleanup_toasts(mut commands: Commands, q_toast: Query<(Entity, &Toast)>) {
    for (entity, toast) in q_toast.iter() {
        if toast.spawned.elapsed() > Duration::from_secs(2) {
            commands.entity(entity).despawn();
        }
    }
}