despero_hecs/
entity_builder.rs

1// Copyright 2019 Google LLC
2//
3// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5// http://opensource.org/licenses/MIT>, at your option. This file may not be
6// copied, modified, or distributed except according to those terms.
7
8use crate::alloc::alloc::{alloc, dealloc, Layout};
9use crate::alloc::vec::Vec;
10use crate::bundle::{DynamicBundleClone, DynamicClone};
11use core::any::TypeId;
12use core::ptr::{self, NonNull};
13
14use hashbrown::hash_map::Entry;
15
16use crate::archetype::{TypeIdMap, TypeInfo};
17use crate::{align, Component, ComponentRef, ComponentRefShared, DynamicBundle};
18
19/// Helper for incrementally constructing a bundle of components with dynamic component types
20///
21/// Prefer reusing the same builder over creating new ones repeatedly.
22///
23/// ```
24/// # use hecs::*;
25/// let mut world = World::new();
26/// let mut builder = EntityBuilder::new();
27/// builder.add(123).add("abc");
28/// let e = world.spawn(builder.build()); // builder can now be reused
29/// assert_eq!(*world.get::<&i32>(e).unwrap(), 123);
30/// assert_eq!(*world.get::<&&str>(e).unwrap(), "abc");
31/// ```
32#[derive(Default)]
33pub struct EntityBuilder {
34    inner: Common<()>,
35}
36
37impl EntityBuilder {
38    /// Create a builder representing an entity with no components
39    pub fn new() -> Self {
40        Self::default()
41    }
42
43    /// Add `component` to the entity.
44    ///
45    /// If the bundle already contains a component of type `T`, it will
46    /// be dropped and replaced with the most recently added one.
47    pub fn add<T: Component>(&mut self, component: T) -> &mut Self {
48        self.add_bundle((component,))
49    }
50
51    /// Add all components in `bundle` to the entity.
52    ///
53    /// If the bundle contains any component which matches the type of a component
54    /// already in the `EntityBuilder`, the newly added component from the bundle
55    /// will replace the old component and the old component will be dropped.
56    pub fn add_bundle(&mut self, bundle: impl DynamicBundle) -> &mut Self {
57        unsafe {
58            bundle.put(|ptr, ty| self.inner.add(ptr, ty, ()));
59        }
60        self
61    }
62
63    /// Construct a `Bundle` suitable for spawning
64    pub fn build(&mut self) -> BuiltEntity<'_> {
65        self.inner.info.sort_unstable_by_key(|x| x.0);
66        self.inner
67            .ids
68            .extend(self.inner.info.iter().map(|x| x.0.id()));
69        BuiltEntity {
70            builder: &mut self.inner,
71        }
72    }
73
74    /// Checks to see if the component of type `T` exists
75    pub fn has<T: Component>(&self) -> bool {
76        self.inner.has::<T>()
77    }
78
79    /// Borrow a shared reference `T` to some component type, if it exists
80    ///
81    /// Takes a reference as its type parameter for consistency with
82    /// [`EntityRef::get`](crate::EntityRef::get), even though it cannot be a unique reference
83    /// because `EntityBuilder` does not perform dynamic borrow checking.
84    pub fn get<'a, T: ComponentRefShared<'a>>(&'a self) -> Option<T> {
85        self.inner.get::<T>()
86    }
87
88    /// Borrow a shared or unique reference `T` to some component type, if it exists
89    pub fn get_mut<'a, T: ComponentRef<'a>>(&'a mut self) -> Option<T> {
90        self.inner.get_mut::<T>()
91    }
92
93    /// Enumerate the types of the entity builder's components
94    pub fn component_types(&self) -> impl Iterator<Item = TypeId> + '_ {
95        self.inner.component_types()
96    }
97
98    /// Drop previously `add`ed components
99    ///
100    /// The builder is cleared implicitly when an entity is built, so this doesn't usually need to
101    /// be called.
102    pub fn clear(&mut self) {
103        self.inner.clear()
104    }
105}
106
107/// The output of an [`EntityBuilder`], suitable for passing to
108/// [`World::spawn`](crate::World::spawn) or [`World::insert`](crate::World::insert)
109pub struct BuiltEntity<'a> {
110    builder: &'a mut Common<()>,
111}
112
113unsafe impl DynamicBundle for BuiltEntity<'_> {
114    fn has<T: Component>(&self) -> bool {
115        self.builder.has::<T>()
116    }
117
118    fn with_ids<T>(&self, f: impl FnOnce(&[TypeId]) -> T) -> T {
119        f(&self.builder.ids)
120    }
121
122    #[doc(hidden)]
123    fn type_info(&self) -> Vec<TypeInfo> {
124        self.builder.info.iter().map(|x| x.0).collect()
125    }
126
127    unsafe fn put(self, mut f: impl FnMut(*mut u8, TypeInfo)) {
128        for (ty, offset, ()) in self.builder.info.drain(..) {
129            let ptr = self.builder.storage.as_ptr().add(offset);
130            f(ptr, ty);
131        }
132    }
133}
134
135impl Drop for BuiltEntity<'_> {
136    fn drop(&mut self) {
137        // Ensures components aren't leaked if `store` was never called, and prepares the builder
138        // for reuse.
139        self.builder.clear();
140    }
141}
142
143/// Variant of [`EntityBuilder`] that clones components on use
144///
145/// ```
146/// # use hecs::*;
147/// let mut world = World::new();
148/// let mut builder = EntityBuilderClone::new();
149/// builder.add(123).add("abc");
150/// let bundle = builder.build();
151/// let e = world.spawn(&bundle);
152/// let f = world.spawn(&bundle); // `&bundle` can be used many times
153/// assert_eq!(*world.get::<&i32>(e).unwrap(), 123);
154/// assert_eq!(*world.get::<&&str>(e).unwrap(), "abc");
155/// assert_eq!(*world.get::<&i32>(f).unwrap(), 123);
156/// assert_eq!(*world.get::<&&str>(f).unwrap(), "abc");
157/// ```
158#[derive(Clone, Default)]
159pub struct EntityBuilderClone {
160    inner: Common<DynamicClone>,
161}
162
163impl EntityBuilderClone {
164    /// Create a builder representing an entity with no components
165    pub fn new() -> Self {
166        Self::default()
167    }
168
169    /// Add `component` to the entity.
170    ///
171    /// If the bundle already contains a component of type `T`, it will be dropped and replaced with
172    /// the most recently added one.
173    pub fn add<T: Component + Clone>(&mut self, mut component: T) -> &mut Self {
174        unsafe {
175            self.inner.add(
176                (&mut component as *mut T).cast(),
177                TypeInfo::of::<T>(),
178                DynamicClone::new::<T>(),
179            );
180        }
181        core::mem::forget(component);
182        self
183    }
184
185    /// Add all components in `bundle` to the entity.
186    ///
187    /// If the bundle contains any component which matches the type of a component
188    /// already in the `EntityBuilder`, the newly added component from the bundle
189    /// will replace the old component and the old component will be dropped.
190    pub fn add_bundle(&mut self, bundle: impl DynamicBundleClone) -> &mut Self {
191        unsafe {
192            bundle.put_with_clone(|ptr, ty, cloneable| self.inner.add(ptr, ty, cloneable));
193        }
194        self
195    }
196
197    /// Convert into a value whose shared references are [`DynamicBundle`]s suitable for repeated
198    /// spawning
199    pub fn build(self) -> BuiltEntityClone {
200        self.into()
201    }
202
203    /// Checks to see if the component of type `T` exists
204    pub fn has<T: Component>(&self) -> bool {
205        self.inner.has::<T>()
206    }
207
208    /// Borrow a shared reference `T` to some component type, if it exists
209    ///
210    /// Takes a reference as its type parameter for consistency with
211    /// [`EntityRef::get`](crate::EntityRef::get), even though it cannot be a unique reference
212    /// because `EntityBuilderClone` does not perform dynamic borrow checking.
213    pub fn get<'a, T: ComponentRefShared<'a>>(&'a self) -> Option<T> {
214        self.inner.get::<T>()
215    }
216
217    /// Borrow a shared or unique reference `T` to some component type, if it exists
218    pub fn get_mut<'a, T: ComponentRef<'a>>(&'a mut self) -> Option<T> {
219        self.inner.get_mut::<T>()
220    }
221
222    /// Enumerate the types of the entity builder's components
223    pub fn component_types(&self) -> impl Iterator<Item = TypeId> + '_ {
224        self.inner.component_types()
225    }
226
227    /// Drop previously `add`ed components
228    ///
229    /// The builder is cleared implicitly when an entity is built, so this doesn't usually need to
230    /// be called.
231    pub fn clear(&mut self) {
232        self.inner.clear()
233    }
234}
235
236/// A collection of components that implement [`Clone`]
237///
238/// Built from, and convertible back into, [`EntityBuilderClone`]. `DynamicBundle` is implemented
239/// for *references to* this type, allowing it to be e.g. spawned repeatedly.
240#[derive(Clone)]
241pub struct BuiltEntityClone(Common<DynamicClone>);
242
243unsafe impl DynamicBundle for &'_ BuiltEntityClone {
244    fn has<T: Component>(&self) -> bool {
245        self.0.has::<T>()
246    }
247
248    fn with_ids<T>(&self, f: impl FnOnce(&[TypeId]) -> T) -> T {
249        f(&self.0.ids)
250    }
251
252    fn type_info(&self) -> Vec<TypeInfo> {
253        self.0.info.iter().map(|x| x.0).collect()
254    }
255
256    unsafe fn put(self, mut f: impl FnMut(*mut u8, TypeInfo)) {
257        for &(_, offset, clone) in &self.0.info {
258            let ptr = self.0.storage.as_ptr().add(offset);
259            (clone.func)(ptr, &mut f);
260        }
261    }
262}
263
264unsafe impl DynamicBundleClone for &'_ BuiltEntityClone {
265    unsafe fn put_with_clone(self, mut f: impl FnMut(*mut u8, TypeInfo, DynamicClone)) {
266        for &(_, offset, clone) in &self.0.info {
267            let ptr = self.0.storage.as_ptr().add(offset);
268            (clone.func)(ptr, &mut |src, ty| f(src, ty, clone));
269        }
270    }
271}
272
273impl From<EntityBuilderClone> for BuiltEntityClone {
274    fn from(mut x: EntityBuilderClone) -> Self {
275        x.inner.info.sort_unstable_by_key(|y| y.0);
276        x.inner.ids.extend(x.inner.info.iter().map(|y| y.0.id()));
277        Self(x.inner)
278    }
279}
280
281impl From<BuiltEntityClone> for EntityBuilderClone {
282    fn from(mut x: BuiltEntityClone) -> Self {
283        x.0.ids.clear();
284        EntityBuilderClone { inner: x.0 }
285    }
286}
287
288struct Common<M> {
289    storage: NonNull<u8>,
290    layout: Layout,
291    cursor: usize,
292    info: Vec<(TypeInfo, usize, M)>,
293    ids: Vec<TypeId>,
294    indices: TypeIdMap<usize>,
295}
296
297impl<M> Common<M> {
298    fn has<T: Component>(&self) -> bool {
299        self.indices.contains_key(&TypeId::of::<T>())
300    }
301
302    fn get<'a, T: ComponentRefShared<'a>>(&'a self) -> Option<T> {
303        let index = self.indices.get(&TypeId::of::<T::Component>())?;
304        let (_, offset, _) = self.info[*index];
305        unsafe {
306            let storage = self.storage.as_ptr().add(offset).cast::<T::Component>();
307            Some(T::from_raw(storage))
308        }
309    }
310
311    fn get_mut<'a, T: ComponentRef<'a>>(&'a self) -> Option<T> {
312        let index = self.indices.get(&TypeId::of::<T::Component>())?;
313        let (_, offset, _) = self.info[*index];
314        unsafe {
315            let storage = self.storage.as_ptr().add(offset).cast::<T::Component>();
316            Some(T::from_raw(storage))
317        }
318    }
319
320    fn component_types(&self) -> impl Iterator<Item = TypeId> + '_ {
321        self.info.iter().map(|(info, _, _)| info.id())
322    }
323
324    unsafe fn grow(
325        min_size: usize,
326        cursor: usize,
327        align: usize,
328        storage: NonNull<u8>,
329    ) -> (NonNull<u8>, Layout) {
330        let layout = Layout::from_size_align(min_size.next_power_of_two().max(64), align).unwrap();
331        let new_storage = NonNull::new_unchecked(alloc(layout));
332        ptr::copy_nonoverlapping(storage.as_ptr(), new_storage.as_ptr(), cursor);
333        (new_storage, layout)
334    }
335
336    fn clear(&mut self) {
337        self.ids.clear();
338        self.indices.clear();
339        self.cursor = 0;
340        unsafe {
341            for (ty, offset, _) in self.info.drain(..) {
342                ty.drop(self.storage.as_ptr().add(offset));
343            }
344        }
345    }
346
347    unsafe fn add(&mut self, ptr: *mut u8, ty: TypeInfo, meta: M) {
348        match self.indices.entry(ty.id()) {
349            Entry::Occupied(occupied) => {
350                let index = *occupied.get();
351                let (ty, offset, _) = self.info[index];
352                let storage = self.storage.as_ptr().add(offset);
353
354                // Drop the existing value
355                ty.drop(storage);
356
357                // Overwrite the old value with our new one.
358                ptr::copy_nonoverlapping(ptr, storage, ty.layout().size());
359            }
360            Entry::Vacant(vacant) => {
361                let offset = align(self.cursor, ty.layout().align());
362                let end = offset + ty.layout().size();
363                if end > self.layout.size() || ty.layout().align() > self.layout.align() {
364                    let new_align = self.layout.align().max(ty.layout().align());
365                    let (new_storage, new_layout) =
366                        Self::grow(end, self.cursor, new_align, self.storage);
367                    if self.layout.size() != 0 {
368                        dealloc(self.storage.as_ptr(), self.layout);
369                    }
370                    self.storage = new_storage;
371                    self.layout = new_layout;
372                }
373
374                let addr = self.storage.as_ptr().add(offset);
375                ptr::copy_nonoverlapping(ptr, addr, ty.layout().size());
376
377                vacant.insert(self.info.len());
378                self.info.push((ty, offset, meta));
379                self.cursor = end;
380            }
381        }
382    }
383}
384
385unsafe impl<M> Send for Common<M> {}
386unsafe impl<M> Sync for Common<M> {}
387
388impl<M> Drop for Common<M> {
389    fn drop(&mut self) {
390        // Ensure buffered components aren't leaked
391        self.clear();
392        if self.layout.size() != 0 {
393            unsafe {
394                dealloc(self.storage.as_ptr(), self.layout);
395            }
396        }
397    }
398}
399
400impl<M> Default for Common<M> {
401    /// Create a builder representing an entity with no components
402    fn default() -> Self {
403        Self {
404            storage: NonNull::dangling(),
405            layout: Layout::from_size_align(0, 8).unwrap(),
406            cursor: 0,
407            info: Vec::new(),
408            ids: Vec::new(),
409            indices: Default::default(),
410        }
411    }
412}
413
414impl Clone for Common<DynamicClone> {
415    fn clone(&self) -> Self {
416        unsafe {
417            let result = Common {
418                storage: NonNull::new_unchecked(alloc(self.layout)),
419                layout: self.layout,
420                cursor: self.cursor,
421                info: self.info.clone(),
422                ids: self.ids.clone(),
423                indices: self.indices.clone(),
424            };
425            for &(_, offset, ref clone) in &self.info {
426                (clone.func)(self.storage.as_ptr().add(offset), &mut |src, ty| {
427                    result
428                        .storage
429                        .as_ptr()
430                        .add(offset)
431                        .copy_from_nonoverlapping(src, ty.layout().size())
432                });
433            }
434            result
435        }
436    }
437}