pub struct BoundEntity<'w> { /* private fields */ }Expand description
Implementations§
Source§impl<'w> BoundEntity<'w>
impl<'w> BoundEntity<'w>
Sourcepub const fn handle(self) -> EntityHandle
pub const fn handle(self) -> EntityHandle
Returns an EntityHandle for storage.
Sourcepub fn get<T: Component>(self) -> Option<&'w T>
pub fn get<T: Component>(self) -> Option<&'w T>
Gets a component from this entity.
Returns None if the entity doesn’t exist or doesn’t have the component.
Examples found in repository?
73fn find_team_member<'w>(leader: BoundEntity<'w>, target_name: &str) -> Option<BoundEntity<'w>> {
74 leader.get::<Team>().and_then(|team| {
75 team.0.iter().find_map(|h| {
76 let member = h.bind(leader.world());
77 if member.get::<Name>().map(|n| n.0) == Some(target_name) {
78 Some(member)
79 } else {
80 None
81 }
82 })
83 })
84}
85
86fn main() {
87 let mut world = World::new();
88
89 println!("=== Mixed Usage Example ===\n");
90
91 // Build a linked list: a -> b -> c -> d
92 println!("Building linked list: a -> b -> c -> d\n");
93
94 let d = world.spawn((Name("d"), LinkedList { next: None })).id();
95 let c = world
96 .spawn((
97 Name("c"),
98 LinkedList {
99 next: Some(EntityHandle::new(d)),
100 },
101 ))
102 .id();
103 let b = world
104 .spawn((
105 Name("b"),
106 LinkedList {
107 next: Some(EntityHandle::new(c)),
108 },
109 ))
110 .id();
111 let a = world
112 .spawn((
113 Name("a"),
114 LinkedList {
115 next: Some(EntityHandle::new(b)),
116 },
117 ))
118 .id();
119
120 // Store handle for later use (EntityHandle is Send + Sync)
121 let a_handle = EntityHandle::new(a);
122
123 // === BoundEntity approach ===
124 println!("--- BoundEntity Approach (explicit &World) ---");
125
126 let bound = a_handle.bind(&world);
127 let length = count_chain_length_bound(bound);
128 println!("Chain length from 'a': {}", length);
129 assert_eq!(length, 4);
130
131 // Get component with explicit world
132 let name = a_handle.get::<Name>(&world).unwrap().0;
133 println!("Starting node name: {}", name);
134
135 // === EntityPtr approach ===
136 println!("\n--- EntityPtr Approach (ergonomic) ---");
137
138 // No unsafe needed! WorldExt provides ergonomic access
139 let ptr = world.entity_ptr(a_handle.entity()); // Convert handle to ptr
140
141 let length = count_chain_length_ptr(ptr);
142 println!("Chain length from 'a': {}", length);
143 assert_eq!(length, 4);
144
145 // Convert back to handle
146 let back_to_handle = ptr.handle();
147 assert_eq!(back_to_handle.entity(), a_handle.entity());
148 println!("Round-trip handle conversion: OK");
149
150 // === Team example ===
151 println!("\n--- Team Example ---");
152
153 // Create team members
154 let alice = world.spawn((Name("Alice"), Health(100))).id();
155 let bob = world.spawn((Name("Bob"), Health(80))).id();
156 let charlie = world.spawn((Name("Charlie"), Health(120))).id();
157
158 // Create team leader with team
159 let leader = world
160 .spawn((
161 Name("Leader"),
162 Health(150),
163 Team(vec![
164 EntityHandle::new(alice),
165 EntityHandle::new(bob),
166 EntityHandle::new(charlie),
167 ]),
168 ))
169 .id();
170
171 // Calculate total team health using EntityPtr
172 let leader_ptr = world.entity_ptr(leader);
173 let total = team_health(leader_ptr);
174 println!("Total team health: {}", total);
175 println!(" Expected: 150 + 100 + 80 + 120 = 450");
176 assert_eq!(total, 450);
177
178 // Find team member using BoundEntity
179 let leader_bound = EntityHandle::new(leader).bind(&world);
180 let bob_bound = find_team_member(leader_bound, "Bob").unwrap();
181 let bob_health = bob_bound.get::<Health>().unwrap().0;
182 println!("Bob's health: {}", bob_health);
183 assert_eq!(bob_health, 80);
184
185 // === Stale Reference Handling ===
186 println!("\n--- Stale Reference Handling ---");
187
188 let temp = world.spawn((Name("Temporary"), Health(50))).id();
189 let temp_handle = EntityHandle::new(temp);
190
191 // Check it's alive
192 println!("Before despawn:");
193 println!(" is_alive: {}", temp_handle.is_alive(&world));
194 println!(" name: {:?}", temp_handle.get::<Name>(&world).map(|n| n.0));
195 assert!(temp_handle.is_alive(&world));
196
197 // Despawn the entity
198 world.despawn(temp);
199
200 // Handle gracefully returns None
201 println!("After despawn:");
202 println!(" is_alive: {}", temp_handle.is_alive(&world));
203 println!(" name: {:?}", temp_handle.get::<Name>(&world).map(|n| n.0));
204 assert!(!temp_handle.is_alive(&world));
205 assert!(temp_handle.get::<Name>(&world).is_none());
206
207 // === Mixing approaches in computation ===
208 println!("\n--- Mixing Approaches ---");
209
210 // Start with a stored handle
211 let leader_handle = EntityHandle::new(leader);
212
213 // Use BoundEntity for one part of the computation
214 let bound = leader_handle.bind(&world);
215 let leader_name = bound.get::<Name>().unwrap().0;
216
217 // Switch to EntityPtr for another part
218 let ptr = world.entity_ptr(leader_handle.entity());
219 let total_health = team_health(ptr);
220
221 println!(
222 "{}'s team has total health of {}",
223 leader_name, total_health
224 );
225
226 // Can also convert EntityPtr back to BoundEntity's handle
227 let ptr_handle = ptr.handle();
228 let rebound = ptr_handle.bind(&world);
229 assert_eq!(rebound.get::<Name>().unwrap().0, leader_name);
230 println!("Seamless conversion between approaches: OK");
231
232 println!("\nAll assertions passed!");
233}Sourcepub fn has<T: Component>(self) -> bool
pub fn has<T: Component>(self) -> bool
Checks if this entity has a component of type T.
Returns false if the entity doesn’t exist.
Sourcepub fn follow<T, F>(self, f: F) -> Option<BoundEntity<'w>>
pub fn follow<T, F>(self, f: F) -> Option<BoundEntity<'w>>
Follows a reference component to another entity.
The component must contain an EntityHandle. Use follow_opt for optional references.
Returns None if this entity doesn’t have the component.
Sourcepub fn follow_opt<T, F>(self, f: F) -> Option<BoundEntity<'w>>
pub fn follow_opt<T, F>(self, f: F) -> Option<BoundEntity<'w>>
Follows an optional reference component to another entity.
The extractor function returns Option<EntityHandle>.
Returns None if this entity doesn’t have the component or the reference is None.
Returns a navigator for this entity, enabling HasParent/HasChildren navigation.
This method is always available but navigation methods require the nav-traits feature.
Sourcepub const fn world(self) -> &'w World
pub const fn world(self) -> &'w World
Returns the world reference.
This allows access to the underlying world for advanced use cases.
Examples found in repository?
73fn find_team_member<'w>(leader: BoundEntity<'w>, target_name: &str) -> Option<BoundEntity<'w>> {
74 leader.get::<Team>().and_then(|team| {
75 team.0.iter().find_map(|h| {
76 let member = h.bind(leader.world());
77 if member.get::<Name>().map(|n| n.0) == Some(target_name) {
78 Some(member)
79 } else {
80 None
81 }
82 })
83 })
84}Trait Implementations§
Source§impl<'w> Clone for BoundEntity<'w>
impl<'w> Clone for BoundEntity<'w>
Source§fn clone(&self) -> BoundEntity<'w>
fn clone(&self) -> BoundEntity<'w>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for BoundEntity<'_>
impl Debug for BoundEntity<'_>
impl<'w> Copy for BoundEntity<'w>
Auto Trait Implementations§
impl<'w> Freeze for BoundEntity<'w>
impl<'w> !RefUnwindSafe for BoundEntity<'w>
impl<'w> Send for BoundEntity<'w>
impl<'w> Sync for BoundEntity<'w>
impl<'w> Unpin for BoundEntity<'w>
impl<'w> !UnwindSafe for BoundEntity<'w>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.