Skip to content

Commit

Permalink
Add removal_detection example (#945)
Browse files Browse the repository at this point in the history
Co-authored-by: Carter Anderson <mcanders1@gmail.com>
  • Loading branch information
lukors and cart committed Nov 30, 2020
1 parent f35f813 commit d9c428e
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 0 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ current changes on git with [previous release tags][git_tag_comparison].
## Unreleased

### Added

- [`bevy_log`][836]
- Adds logging functionality as a Plugin.
- Changes internal logging to work with the new implementation.
Expand All @@ -21,7 +22,10 @@ current changes on git with [previous release tags][git_tag_comparison].
- [Added `set_cursor_position` to `Window`][917]
- [Added new Bevy reflection system][926]
- Replaces the properties system
- [Add removal_detection example][945]

### Changed

- [FileAssetIo includes full path on error][821]
- [Removed ECS query APIs that could easily violate safety from the public interface][829]
- [Changed Query filter API to be easier to understand][834]
Expand All @@ -33,7 +37,9 @@ current changes on git with [previous release tags][git_tag_comparison].
- Created getters to get `Time` state and made members private.
- Modifying `Time`'s values directly is no longer possible outside of bevy.
- [Use `mailbox` instead of `fifo` for vsync on supported systems][920]

### Fixed

- [Fixed typos in KeyCode identifiers][857]
- [Don't draw text that isn't visible][893]
- [Use `instant::Instant` for WASM compatibility][895]
Expand All @@ -60,6 +66,7 @@ current changes on git with [previous release tags][git_tag_comparison].
[926]: https://github.com/bevyengine/bevy/pull/926
[931]: https://github.com/bevyengine/bevy/pull/931
[934]: https://github.com/bevyengine/bevy/pull/934
[945]: https://github.com/bevyengine/bevy/pull/945
[955]: https://github.com/bevyengine/bevy/pull/955

## Version 0.3.0 (2020-11-03)
Expand Down
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,10 @@ path = "examples/window/multiple_windows.rs"
name = "window_settings"
path = "examples/window/window_settings.rs"

[[example]]
name = "removal_detection"
path = "examples/ecs/removal_detection.rs"

[[example]]
name = "hello_wasm"
path = "examples/wasm/hello_wasm.rs"
Expand Down
74 changes: 74 additions & 0 deletions examples/ecs/removal_detection.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// This example shows how you can know when a `Component` has been removed, so you can react to it.

use bevy::prelude::*;

fn main() {
// Information regarding removed `Component`s is discarded at the end of each frame, so you need
// to react to the removal before the frame is over.
//
// Also, `Components` are removed via a `Command`. `Command`s are applied after a stage has
// finished executing. So you need to react to the removal at some stage after the
// `Component` is removed.
//
// With these constraints in mind we make sure to place the system that removes a `Component` on
// the `stage::UPDATE` stage, and the system that reacts on the removal on the
// `stage::POST_UPDATE` stage.
App::build()
.add_plugins(DefaultPlugins)
.add_startup_system(setup.system())
.add_system_to_stage(stage::UPDATE, remove_component.system())
.add_system_to_stage(stage::POST_UPDATE, react_on_removal.system())
.run();
}

// This `Struct` is just used for convenience in this example. This is the `Component` we'll be
// giving to the `Entity` so we have a `Component` to remove in `remove_component()`.
struct MyComponent;

fn setup(
commands: &mut Commands,
asset_server: Res<AssetServer>,
mut materials: ResMut<Assets<ColorMaterial>>,
) {
let texture = asset_server.load("branding/icon.png");

commands
.spawn(Camera2dBundle::default())
.spawn(SpriteBundle {
material: materials.add(texture.into()),
..Default::default()
})
.with(MyComponent); // Add the `Component`.
}

fn remove_component(
time: Res<Time>,
commands: &mut Commands,
query: Query<Entity, With<MyComponent>>,
) {
// After two seconds have passed the `Component` is removed.
if time.seconds_since_startup() > 2.0 {
if let Some(entity) = query.iter().next() {
commands.remove_one::<MyComponent>(entity);
}
}
}

fn react_on_removal(
mut materials: ResMut<Assets<ColorMaterial>>,
query: Query<(Entity, &Handle<ColorMaterial>)>,
) {
// Note: usually this isn't how you would handle a `Query`. In this example it makes things
// a bit easier to read.
let (query_entity, material) = query.iter().next().unwrap();

// `Query.removed<T>` returns an array with the `Entity`s in the `Query` that had its
// `Component` `T` (in this case `MyComponent`) removed at some point earlier during the frame.
for entity in query.removed::<MyComponent>() {
// We compare the `Entity` that had its `MyComponent` `Component` removed with the `Entity`
// in the current `Query`. If they match all red is removed from the material.
if query_entity == *entity {
materials.get_mut(material).unwrap().color.set_r(0.0);
}
}
}

0 comments on commit d9c428e

Please sign in to comment.