1use 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#[derive(Default)]
33pub struct EntityBuilder {
34 inner: Common<()>,
35}
36
37impl EntityBuilder {
38 pub fn new() -> Self {
40 Self::default()
41 }
42
43 pub fn add<T: Component>(&mut self, component: T) -> &mut Self {
48 self.add_bundle((component,))
49 }
50
51 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 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 pub fn has<T: Component>(&self) -> bool {
76 self.inner.has::<T>()
77 }
78
79 pub fn get<'a, T: ComponentRefShared<'a>>(&'a self) -> Option<T> {
85 self.inner.get::<T>()
86 }
87
88 pub fn get_mut<'a, T: ComponentRef<'a>>(&'a mut self) -> Option<T> {
90 self.inner.get_mut::<T>()
91 }
92
93 pub fn component_types(&self) -> impl Iterator<Item = TypeId> + '_ {
95 self.inner.component_types()
96 }
97
98 pub fn clear(&mut self) {
103 self.inner.clear()
104 }
105}
106
107pub 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 self.builder.clear();
140 }
141}
142
143#[derive(Clone, Default)]
159pub struct EntityBuilderClone {
160 inner: Common<DynamicClone>,
161}
162
163impl EntityBuilderClone {
164 pub fn new() -> Self {
166 Self::default()
167 }
168
169 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 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 pub fn build(self) -> BuiltEntityClone {
200 self.into()
201 }
202
203 pub fn has<T: Component>(&self) -> bool {
205 self.inner.has::<T>()
206 }
207
208 pub fn get<'a, T: ComponentRefShared<'a>>(&'a self) -> Option<T> {
214 self.inner.get::<T>()
215 }
216
217 pub fn get_mut<'a, T: ComponentRef<'a>>(&'a mut self) -> Option<T> {
219 self.inner.get_mut::<T>()
220 }
221
222 pub fn component_types(&self) -> impl Iterator<Item = TypeId> + '_ {
224 self.inner.component_types()
225 }
226
227 pub fn clear(&mut self) {
232 self.inner.clear()
233 }
234}
235
236#[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 ty.drop(storage);
356
357 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 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 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}