Merge 7d1d8d7192
into 877d278785
This commit is contained in:
commit
aa09589613
@ -1,5 +1,7 @@
|
||||
use bevy_ecs::system::{Commands, SystemId, SystemInput};
|
||||
use bevy_ecs::world::{DeferredWorld, World};
|
||||
use bevy_ecs::system::{Commands, EntityCommands, IntoSystem, SystemId, SystemInput};
|
||||
use bevy_ecs::world::{DeferredWorld, EntityWorldMut, World};
|
||||
|
||||
use crate::owner::OwnedBy;
|
||||
|
||||
/// A callback defines how we want to be notified when a widget changes state. Unlike an event
|
||||
/// or observer, callbacks are intended for "point-to-point" communication that cuts across the
|
||||
@ -111,3 +113,88 @@ impl Notify for DeferredWorld<'_> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Methods for registering scoped callbacks.
|
||||
pub trait RegisterOwnedCallback {
|
||||
/// Registers a scoped one-shot system, with no input, that will be removed when the parent
|
||||
/// entity is despawned.
|
||||
fn register_owned_callback<M, I: IntoSystem<(), (), M> + 'static>(
|
||||
&mut self,
|
||||
callback: I,
|
||||
) -> Callback;
|
||||
|
||||
/// Registers a scoped one-shot systemm, with input, that will be removed when the
|
||||
/// parent entity is despawned.
|
||||
fn register_owned_callback_with<
|
||||
M,
|
||||
A: SystemInput + Send + 'static,
|
||||
I: IntoSystem<A, (), M> + 'static,
|
||||
>(
|
||||
&mut self,
|
||||
callback: I,
|
||||
) -> Callback<A>;
|
||||
}
|
||||
|
||||
impl RegisterOwnedCallback for EntityCommands<'_> {
|
||||
fn register_owned_callback<M, I: IntoSystem<(), (), M> + 'static>(
|
||||
&mut self,
|
||||
callback: I,
|
||||
) -> Callback {
|
||||
let system_id = self.commands().register_system(callback);
|
||||
let owner = self.id();
|
||||
self.commands()
|
||||
.entity(owner)
|
||||
.add_one_related::<OwnedBy>(system_id.entity());
|
||||
Callback::System(system_id)
|
||||
}
|
||||
|
||||
fn register_owned_callback_with<
|
||||
M,
|
||||
A: SystemInput + Send + 'static,
|
||||
I: IntoSystem<A, (), M> + 'static,
|
||||
>(
|
||||
&mut self,
|
||||
callback: I,
|
||||
) -> Callback<A> {
|
||||
let owner = self.id();
|
||||
let system_id = self.commands().register_system(callback);
|
||||
self.commands()
|
||||
.entity(owner)
|
||||
.add_one_related::<OwnedBy>(system_id.entity());
|
||||
Callback::System(system_id)
|
||||
}
|
||||
}
|
||||
|
||||
impl RegisterOwnedCallback for EntityWorldMut<'_> {
|
||||
fn register_owned_callback<M, I: IntoSystem<(), (), M> + 'static>(
|
||||
&mut self,
|
||||
callback: I,
|
||||
) -> Callback {
|
||||
let owner = self.id();
|
||||
let system_id = self.world_scope(|world| world.register_system(callback));
|
||||
self.world_scope(|world| {
|
||||
world
|
||||
.entity_mut(owner)
|
||||
.add_one_related::<OwnedBy>(system_id.entity());
|
||||
});
|
||||
Callback::System(system_id)
|
||||
}
|
||||
|
||||
fn register_owned_callback_with<
|
||||
M,
|
||||
A: SystemInput + Send + 'static,
|
||||
I: IntoSystem<A, (), M> + 'static,
|
||||
>(
|
||||
&mut self,
|
||||
callback: I,
|
||||
) -> Callback<A> {
|
||||
let owner = self.id();
|
||||
let system_id = self.world_scope(|world| world.register_system(callback));
|
||||
self.world_scope(|world| {
|
||||
world
|
||||
.entity_mut(owner)
|
||||
.add_one_related::<OwnedBy>(system_id.entity());
|
||||
});
|
||||
Callback::System(system_id)
|
||||
}
|
||||
}
|
||||
|
@ -20,11 +20,12 @@ mod core_checkbox;
|
||||
mod core_radio;
|
||||
mod core_scrollbar;
|
||||
mod core_slider;
|
||||
pub mod owner;
|
||||
|
||||
use bevy_app::{PluginGroup, PluginGroupBuilder};
|
||||
|
||||
use bevy_ecs::entity::Entity;
|
||||
pub use callback::{Callback, Notify};
|
||||
pub use callback::{Callback, Notify, RegisterOwnedCallback};
|
||||
pub use core_button::{CoreButton, CoreButtonPlugin};
|
||||
pub use core_checkbox::{CoreCheckbox, CoreCheckboxPlugin, SetChecked, ToggleChecked};
|
||||
pub use core_radio::{CoreRadio, CoreRadioGroup, CoreRadioGroupPlugin};
|
||||
|
51
crates/bevy_core_widgets/src/owner.rs
Normal file
51
crates/bevy_core_widgets/src/owner.rs
Normal file
@ -0,0 +1,51 @@
|
||||
//! Defines relationships for ownership of an entity, with no other inherited semantics.
|
||||
use core::slice;
|
||||
|
||||
use bevy_ecs::{component::Component, entity::Entity};
|
||||
|
||||
/// A component that represents the owner of an entity. Ownership only determines lifetime,
|
||||
/// such that the owned entity will be despawned when its owner is despawned. It does not imply
|
||||
/// any other kind of semantic connection between the two entities.
|
||||
// TODO: Consider renaming and/or moving this.
|
||||
#[derive(Component, Clone, PartialEq, Eq, Debug)]
|
||||
#[relationship(relationship_target = Owned)]
|
||||
pub struct OwnedBy(pub Entity);
|
||||
|
||||
impl OwnedBy {
|
||||
/// Return the owned entity.
|
||||
pub fn get(&self) -> Entity {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for OwnedBy {
|
||||
fn default() -> Self {
|
||||
OwnedBy(Entity::PLACEHOLDER)
|
||||
}
|
||||
}
|
||||
|
||||
/// A component that represents a collection of entities that are owned by another entity.
|
||||
// #[derive(Component, Default, Reflect)]
|
||||
// #[reflect(Component)]
|
||||
#[derive(Component, Default)]
|
||||
#[relationship_target(relationship = OwnedBy, linked_spawn)]
|
||||
pub struct Owned(Vec<Entity>);
|
||||
|
||||
impl<'a> IntoIterator for &'a Owned {
|
||||
type Item = <Self::IntoIter as Iterator>::Item;
|
||||
|
||||
type IntoIter = slice::Iter<'a, Entity>;
|
||||
|
||||
#[inline(always)]
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.0.iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl core::ops::Deref for Owned {
|
||||
type Target = [Entity];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user