use bevy::{
ecs::component::{ComponentHooks, StorageType},
prelude::*,
};
use std::collections::HashMap;
#[derive(Debug)]
struct MyComponent(KeyCode);
impl Component for MyComponent {
const STORAGE_TYPE: StorageType = StorageType::Table;
fn register_component_hooks(_hooks: &mut ComponentHooks) {
}
}
#[derive(Resource, Default, Debug, Deref, DerefMut)]
struct MyComponentIndex(HashMap<KeyCode, Entity>);
#[derive(Event)]
struct MyEvent;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_systems(Startup, setup)
.add_systems(Update, trigger_hooks)
.init_resource::<MyComponentIndex>()
.add_event::<MyEvent>()
.run();
}
fn setup(world: &mut World) {
world
.register_component_hooks::<MyComponent>()
.on_add(|mut world, entity, component_id| {
let value = world.get::<MyComponent>(entity).unwrap().0;
println!("Component: {component_id:?} added to: {entity:?} with value {value:?}");
world
.resource_mut::<MyComponentIndex>()
.insert(value, entity);
world.send_event(MyEvent);
})
.on_insert(|world, _, _| {
println!("Current Index: {:?}", world.resource::<MyComponentIndex>());
})
.on_replace(|mut world, entity, _| {
let value = world.get::<MyComponent>(entity).unwrap().0;
world.resource_mut::<MyComponentIndex>().remove(&value);
})
.on_remove(|mut world, entity, component_id| {
let value = world.get::<MyComponent>(entity).unwrap().0;
println!("Component: {component_id:?} removed from: {entity:?} with value {value:?}");
world.commands().entity(entity).despawn();
});
}
fn trigger_hooks(
mut commands: Commands,
keys: Res<ButtonInput<KeyCode>>,
index: Res<MyComponentIndex>,
) {
for (key, entity) in index.iter() {
if !keys.pressed(*key) {
commands.entity(*entity).remove::<MyComponent>();
}
}
for key in keys.get_just_pressed() {
commands.spawn(MyComponent(*key));
}
}