Taken from the minimal
example, here we have a goblin wearing a few pieces of armor. An Attack
event can target any of these entities. If an Attack
reaches a piece of armor, the armor will try
to absorb the attack. Any damage it is not able to absorb will bubble to the goblin wearing the armor.
commands
.spawn((
Name::new("Goblin"),
HitPoints(50),
On::<Attack>::run(take_damage),
))
.with_children(|parent| {
parent.spawn((
Name::new("Helmet"),
Armor(5),
On::<Attack>::run(block_attack),
));
parent.spawn((
Name::new("Socks"),
Armor(10),
On::<Attack>::run(block_attack),
));
});
This library is intended to be upstreamed to bevy for use in making interactive UI. However, as demonstrated above, event bubbling is applicable to any kind of event that needs to traverse an entity hierarchy. This follows the basic principles of ECS patterns: it works on any entity with the required components, not just UI.
This library was initially extracted from the 0.13
version of bevy_mod_picking, as it became obvious that
this is a generically useful feature.
Using DOM data from the most complex websites I could find, the stress test example was built to help benchmark the performance of this implementation with a representative dataset. Using a DOM complexity:
The blue line can be read as "how long does it take all of these events to bubble up a hierarchy and trigger callbacks at ~20% of the 64 nodes as it traverses depth?". A graph is built for every event as an acceleration structure, which allows us to have linearly scaling performance.
The runtime cost of each event decreases as the total number of events increase, this is because graph construction is a fixed cost for each type of event. Adding more events simply amortizes that cost across more events. At 50 events the runtime cost is only ~500ns/event, and about 25us total. To reiterate, this is using an entity hierarchy similar to the most complex websites I could find.
bevy | bevy_eventlistener |
---|---|
0.14 | 0.8 |
0.13 | 0.7 |
0.12 | 0.6 |
0.11 | 0.5 |
All code in this repository is dual-licensed under either:
at your option. This means you can select the license you prefer.
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.