Crates.io | bevy_kot_ecs |
lib.rs | bevy_kot_ecs |
version | 0.11.0 |
source | src |
created_at | 2023-11-07 20:40:27.411376 |
updated_at | 2024-01-11 03:58:19.675812 |
description | ECS utilities for bevy_kot |
homepage | |
repository | https://github.com/UkoeHB/bevy_kot |
max_upload_size | |
id | 1028424 |
size | 122,473 |
[ReactCommands
] makes it easy to register and unregister ECS hooks. Reactors are most useful when you need to pass information (e.g. entity IDs) into a reaction system.
A reactor will run in the first apply_deferred
after its reaction trigger is detected. If a reactor triggers other reactors, they will run immediately after the initial reactor (until the entire tree of reactions terminates). Recursive reactions are currently not supported.
Reactors are registered with [ReactCommands
]. You must specify a 'reaction trigger':
fn setup(mut rcommands: ReactCommands)
{
rcommands.on(resource_mutation::<A>(),
|a: ReactRes<A>|
{
//...
}
);
}
The available reaction triggers are:
resource_mutation<R: ReactResource>()
]insertion<C: ReactComponent>()
]mutation<C: ReactComponent>()
]removal<C: ReactComponent>()
]entity_insertion<C: ReactComponent>(entity)
]entity_mutation<C: ReactComponent>(entity)
]entity_removal<C: ReactComponent>(entity)
]event<E>()
]A reactor can be associated with multiple reaction triggers:
fn setup(mut rcommands: ReactCommands)
{
rcommands.on((resource_mutation::<A>(), entity_insertion<B>(entity)),
move |a: ReactRes<A>, q: Query<&B>|
{
q.get(entity);
//...etc.
}
);
}
Reactors can be revoked with [RevokeToken
]s obtained on registration.
let token = rcommands.on(resource_mutation::<A>(), || { todo!(); });
rcommands.revoke(token);
Add a reactive resource to your app:
#[derive(ReactResource)]
struct Counter(u32);
app.add_plugins(ReactPlugin)
.add_react_resource(Counter);
Mutate the resource:
fn increment(mut rcommands: ReactCommands, mut counter: ReactResMut<Counter>)
{
counter.get_mut(&mut rcommands).0 += 1;
}
React to the resource mutation:
fn setup(mut rcommands: ReactCommands)
{
rcommands.on(resource_mutation::<Counter>(),
|counter: ReactRes<Counter>|
{
println!("count: {}", counter.0);
}
);
}
#[derive(ReactComponent)]
struct Health(u16);
fn setup(mut rcommands: ReactCommands)
{
let entity = rcommands.commands().spawn_empty().id();
rcommands.insert(entity, Health(0u16));
rcommands.on(entity_mutation::<Health>(entity)
move |q: Query<&React<Health>>|
{
let health = q.get(entity).unwrap();
println!("health: {}", health.0);
}
);
}
fn add_health(mut rcommands: ReactCommands, mut q: Query<&mut React<Health>>)
{
for health in q.iter_mut()
{
health.get_mut(&mut rcommands).0 += 10;
}
}
Entity-agnostic triggers (insertion<C>()
, mutation<C>()
, removal<C>()
) can only be grouped with each other, since their reactor requires an In<Entity>
system parameter:
#[derive(ReactComponent)]
struct A;
#[derive(ReactComponent)]
struct B;
rcommands.on((insertion::<A>(), removal::<B>()),
|In(entity): In<Entity>, a: Query<(Option<&React<A>>, Option<&React<B>>)>|
{
//...
}
);
Register a react event:
app.add_react_event::<u32>();
Send an event:
rcommands.send(0u32);
React to the event, using the [ReactEventReader
] to access event data:
rcommands.on(event::<u32>(),
|mut events: ReactEventReader<u32>|
{
for event in events.iter()
{
println!("react u32: {}", event);
}
}
);
React to despawns with the [ReactCommands::on_despawn()
] method:
rcommands.on_despawn(entity, move || println!("entity despawned: {}", entity));
If you only want a reactor to run once, use [ReactCommands::once()
]:
let entity = rcommands.commands().spawn(Player);
rcommands.once(event::<ResetEverything>(),
move |world: &mut World|
{
world.despawn(entity);
}
);