1#![allow(incomplete_features)]
107#![feature(specialization)]
108
109#[doc(hidden)]
113pub use paste;
114#[cfg(feature = "rayon")]
115#[doc(hidden)]
116pub use rayon;
117#[cfg(feature = "serde")]
118#[doc(hidden)]
119pub use serde;
120#[doc(hidden)]
121pub use slotmap;
122
123#[doc(hidden)]
124pub trait IsType<T> {
125 const VALUE: bool = false;
126}
127
128impl<A, B> IsType<B> for A {
129 default const VALUE: bool = false;
130}
131
132impl<T> IsType<T> for T {
134 const VALUE: bool = true;
135}
136
137#[doc(hidden)]
139pub trait ErasedArena {
140 fn get(&self, key: slotmap::DefaultKey) -> Option<&dyn std::any::Any>;
141 fn get_mut(&mut self, key: slotmap::DefaultKey) -> Option<&mut dyn std::any::Any>;
142 unsafe fn get_unchecked(&self, key: slotmap::DefaultKey) -> &dyn std::any::Any;
143 unsafe fn get_unchecked_mut(&mut self, key: slotmap::DefaultKey) -> &mut dyn std::any::Any;
144 fn insert(&mut self, value: Box<dyn std::any::Any>) -> slotmap::DefaultKey;
145 fn insert_with_key(
146 &mut self,
147 f: Box<dyn FnOnce(slotmap::DefaultKey) -> Box<dyn std::any::Any>>,
148 ) -> slotmap::DefaultKey;
149 fn remove(&mut self, key: slotmap::DefaultKey) -> Option<Box<dyn std::any::Any>>;
150}
151
152impl<T: 'static> ErasedArena for slotmap::DenseSlotMap<slotmap::DefaultKey, T> {
153 fn get(&self, key: slotmap::DefaultKey) -> Option<&dyn std::any::Any> {
154 self.get(key).map(|e| e as &dyn std::any::Any)
155 }
156
157 fn get_mut(&mut self, key: slotmap::DefaultKey) -> Option<&mut dyn std::any::Any> {
158 self.get_mut(key).map(|e| e as &mut dyn std::any::Any)
159 }
160
161 unsafe fn get_unchecked(&self, key: slotmap::DefaultKey) -> &dyn std::any::Any {
162 unsafe {
163 <slotmap::DenseSlotMap<slotmap::DefaultKey, T>>::get_unchecked(self, key)
164 as &dyn std::any::Any
165 }
166 }
167
168 unsafe fn get_unchecked_mut(&mut self, key: slotmap::DefaultKey) -> &mut dyn std::any::Any {
169 unsafe {
170 <slotmap::DenseSlotMap<slotmap::DefaultKey, T>>::get_unchecked_mut(self, key)
171 as &mut dyn std::any::Any
172 }
173 }
174
175 fn insert(&mut self, value: Box<dyn std::any::Any>) -> slotmap::DefaultKey {
176 self.insert(*value.downcast::<T>().expect("Try mismatch in insert"))
178 }
179
180 fn insert_with_key(
181 &mut self,
182 f: Box<dyn FnOnce(slotmap::DefaultKey) -> Box<dyn std::any::Any>>,
183 ) -> slotmap::DefaultKey {
184 self.insert_with_key(|k| {
186 *f(k)
187 .downcast::<T>()
188 .expect("Type mismatch in insert_with_key")
189 })
190 }
191
192 fn remove(&mut self, key: slotmap::DefaultKey) -> Option<Box<dyn std::any::Any>> {
193 self.remove(key)
194 .map(|v| Box::new(v) as Box<dyn std::any::Any>)
195 }
196}
197
198#[doc(hidden)]
199pub trait ArenaCast<T> {
200 fn cast(&self) -> &slotmap::DenseSlotMap<slotmap::DefaultKey, T>;
201 fn cast_mut(&mut self) -> &mut slotmap::DenseSlotMap<slotmap::DefaultKey, T>;
202}
203
204impl<A, B> ArenaCast<B> for slotmap::DenseSlotMap<slotmap::DefaultKey, A> {
206 default fn cast(&self) -> &slotmap::DenseSlotMap<slotmap::DefaultKey, B> {
207 panic!(
208 "Arena type mismatch: {} cannot be cast to {}",
210 std::any::type_name::<A>(),
211 std::any::type_name::<B>()
212 );
213 }
214
215 default fn cast_mut(&mut self) -> &mut slotmap::DenseSlotMap<slotmap::DefaultKey, B> {
216 panic!(
217 "Arena type mismatch: {} cannot be cast to {}",
219 std::any::type_name::<A>(),
220 std::any::type_name::<B>()
221 );
222 }
223}
224
225impl<T> ArenaCast<T> for slotmap::DenseSlotMap<slotmap::DefaultKey, T> {
227 fn cast(&self) -> &slotmap::DenseSlotMap<slotmap::DefaultKey, T> {
228 self
229 }
230
231 fn cast_mut(&mut self) -> &mut slotmap::DenseSlotMap<slotmap::DefaultKey, T> {
232 self
233 }
234}
235
236#[cfg(feature = "serde")]
238#[doc(hidden)] pub trait SerdeArena<'de> {
240 fn serialize_arena<S>(&self, field_name: &'static str, state: &mut S) -> Result<(), S::Error>
242 where
243 S: serde::ser::SerializeStruct;
244
245 fn deserialize_arena<M>(map: &mut M) -> Result<Self, M::Error>
247 where
248 M: serde::de::MapAccess<'de>,
249 Self: Sized;
250
251 fn from_seq<V>(seq: &mut V, field_name: &str) -> Result<Self, V::Error>
253 where
254 V: serde::de::SeqAccess<'de>,
255 Self: Sized;
256
257 const ACTIVE: bool; }
259
260#[cfg(feature = "serde")]
262impl<'de, T> SerdeArena<'de> for slotmap::DenseSlotMap<slotmap::DefaultKey, T> {
263 default fn serialize_arena<S>(
264 &self,
265 _field_name: &'static str,
266 _state: &mut S,
267 ) -> Result<(), S::Error>
268 where
269 S: serde::ser::SerializeStruct,
270 {
271 Ok(())
272 }
273
274 default fn deserialize_arena<M>(_map: &mut M) -> Result<Self, M::Error>
275 where
276 M: serde::de::MapAccess<'de>,
277 {
278 Ok(slotmap::DenseSlotMap::new())
279 }
280
281 default fn from_seq<V>(_seq: &mut V, _field_name: &str) -> Result<Self, V::Error>
282 where
283 V: serde::de::SeqAccess<'de>,
284 {
285 Ok(slotmap::DenseSlotMap::new())
286 }
287
288 default const ACTIVE: bool = false;
289}
290
291#[cfg(feature = "serde")]
293impl<'de, T> SerdeArena<'de> for slotmap::DenseSlotMap<slotmap::DefaultKey, T>
294where
295 T: serde::Serialize + serde::Deserialize<'de>,
296{
297 fn serialize_arena<S>(&self, field_name: &'static str, state: &mut S) -> Result<(), S::Error>
298 where
299 S: serde::ser::SerializeStruct,
300 {
301 state.serialize_field(field_name, self)
302 }
303
304 fn deserialize_arena<M>(map: &mut M) -> Result<Self, M::Error>
305 where
306 M: serde::de::MapAccess<'de>,
307 {
308 map.next_value()
309 }
310
311 fn from_seq<V>(seq: &mut V, field_name: &str) -> Result<Self, V::Error>
312 where
313 V: serde::de::SeqAccess<'de>,
314 {
315 seq.next_element()?
316 .ok_or_else(|| serde::de::Error::custom(format!("Missing element for {}", field_name)))
317 }
318
319 const ACTIVE: bool = true;
320}
321
322#[doc(hidden)]
323#[macro_export]
324#[cfg(not(feature = "rayon"))]
325macro_rules! __world_define_rayon_trait_helpers {
326 ($struct_name:ident $( $trait_name:ident ),*) => {};
327}
328
329#[doc(hidden)]
330#[macro_export]
331#[cfg(feature = "rayon")]
332macro_rules! __world_define_rayon_trait_helpers {
333 ($struct_name:ident $( $trait_name:ident ),*) => {
334 $crate::paste::paste! {
335
336$(
337trait [<$struct_name ParVisitIf $trait_name>]<T> {
338 fn pv_if_applicable<F>(arena: &$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, handler: &F)
339 where
340 F: Fn(&dyn $trait_name) + Send + Sync;
341
342 fn pvm_if_applicable<F>(arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, handler: &F)
343 where
344 F: Fn(&mut dyn $trait_name) + Send + Sync;
345
346 fn pvk_if_applicable<F>(arena: &$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, handler: &F)
347 where
348 F: Fn(([<$struct_name ArenaID>], $crate::slotmap::DefaultKey), &dyn $trait_name) + Send + Sync;
349
350 fn pvkm_if_applicable<F>(arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, handler: &F)
351 where
352 F: Fn(([<$struct_name ArenaID>], $crate::slotmap::DefaultKey), &mut dyn $trait_name) + Send + Sync;
353
354 fn pr_if_applicable<P>(arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, predicate: &P)
355 where
356 P: Fn(&mut dyn $trait_name) -> bool + Send + Sync;
357
358 fn pd_if_applicable<D, F>(arena: &$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, handler: &F, out: &mut [std::mem::MaybeUninit<D>])
359 where
360 D: Send,
361 F: Fn(&dyn $trait_name) -> D + Send + Sync;
362
363 fn pdm_if_applicable<D, F>(arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, handler: &F, out: &mut [std::mem::MaybeUninit<D>])
364 where
365 D: Send,
366 F: Fn(&mut dyn $trait_name) -> D + Send + Sync;
367
368 fn pda_if_applicable<D, F>(arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, handler: &F, i: &[D])
370 where
371 D: Sync,
372 F: Fn(&mut dyn $trait_name, &D) + Send + Sync;
373
374 const ACTIVE: bool;
375}
376
377impl<T> [<$struct_name ParVisitIf $trait_name>]<T> for () {
378 default fn pv_if_applicable<F>(_arena: &$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, _handler: &F)
379 where F: Fn(&dyn $trait_name) + Send + Sync {}
380
381 default fn pvm_if_applicable<F>(_arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, _handler: &F)
382 where F: Fn(&mut dyn $trait_name) + Send + Sync {}
383
384 default fn pvk_if_applicable<F>(_arena: &$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, _handler: &F)
385 where F: Fn(([<$struct_name ArenaID>], $crate::slotmap::DefaultKey), &dyn $trait_name) + Send + Sync {}
386
387 default fn pvkm_if_applicable<F>(_arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, _handler: &F)
388 where F: Fn(([<$struct_name ArenaID>], $crate::slotmap::DefaultKey), &mut dyn $trait_name) + Send + Sync {}
389
390 default fn pr_if_applicable<P>(_arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, _predicate: &P)
391 where P: Fn(&mut dyn $trait_name) -> bool + Send + Sync {}
392
393 default fn pd_if_applicable<D, F>(_arena: &$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, _handler: &F, _out: &mut [std::mem::MaybeUninit<D>])
394 where
395 D: Send,
396 F: Fn(&dyn $trait_name) -> D + Send + Sync {}
397
398 default fn pdm_if_applicable<D, F>(_arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, _handler: &F, _out: &mut [std::mem::MaybeUninit<D>])
399 where
400 D: Send,
401 F: Fn(&mut dyn $trait_name) -> D + Send + Sync {}
402
403 default fn pda_if_applicable<D, F>(_arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, _handler: &F, _i: &[D])
404 where
405 D: Sync,
406 F: Fn(&mut dyn $trait_name, &D) + Send + Sync {}
407
408 default const ACTIVE: bool = false;
409}
410
411impl<T> [<$struct_name ParVisitIf $trait_name>]<T> for ()
412where
413 T: $trait_name + Send + Sync,
414{
415 fn pv_if_applicable<F>(arena: &$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, handler: &F)
416 where F: Fn(&dyn $trait_name) + Send + Sync
417 {
418 use $crate::rayon::iter::IntoParallelRefIterator;
419 use $crate::rayon::iter::ParallelIterator;
420 arena
421 .values_as_slice()
422 .par_iter()
423 .for_each(|entity| handler(entity));
424 }
425
426 fn pvm_if_applicable<F>(arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, handler: &F)
427 where F: Fn(&mut dyn $trait_name) + Send + Sync
428 {
429 use $crate::rayon::iter::IntoParallelRefMutIterator;
430 use $crate::rayon::iter::ParallelIterator;
431 arena
432 .values_as_mut_slice()
433 .par_iter_mut()
434 .for_each(|entity| handler(entity));
435 }
436
437 fn pvk_if_applicable<F>(arena: &$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, handler: &F)
438 where F: Fn(([<$struct_name ArenaID>], $crate::slotmap::DefaultKey), &dyn $trait_name) + Send + Sync
439 {
440 use $crate::rayon::iter::IntoParallelRefIterator;
441 use $crate::rayon::iter::IndexedParallelIterator;
442 use $crate::rayon::iter::ParallelIterator;
443 let keys = arena.keys_as_slice();
444 let values = arena.values_as_slice();
445 keys.par_iter()
446 .zip(values.par_iter())
447 .for_each(|(k, v)| handler(($struct_name::arena_id::<T>(), *k), v));
448 }
449
450 fn pvkm_if_applicable<F>(arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, handler: &F)
451 where F: Fn(([<$struct_name ArenaID>], $crate::slotmap::DefaultKey), &mut dyn $trait_name) + Send + Sync
452 {
453 use $crate::rayon::iter::IntoParallelRefIterator;
454 use $crate::rayon::iter::IntoParallelRefMutIterator;
455 use $crate::rayon::iter::IndexedParallelIterator;
456 use $crate::rayon::iter::ParallelIterator;
457 let (keys, values) = arena.keys_values_as_mut_slices();
458 keys.par_iter()
459 .zip(values.par_iter_mut())
460 .for_each(|(k, v)| handler(($struct_name::arena_id::<T>(), *k), v));
461 }
462
463 fn pr_if_applicable<P>(arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, predicate: &P)
464 where P: Fn(&mut dyn $trait_name) -> bool + Send + Sync
465 {
466 arena.retain(|_, entity| predicate(entity));
472 }
473
474 fn pd_if_applicable<D, F>(arena: &$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, handler: &F, out: &mut [std::mem::MaybeUninit<D>])
475 where
476 D: Send,
477 F: Fn(&dyn $trait_name) -> D + Sync + Send,
478 {
479 use $crate::rayon::iter::IntoParallelRefMutIterator;
480 use $crate::rayon::iter::IndexedParallelIterator;
481 use $crate::rayon::iter::IntoParallelRefIterator;
482 use $crate::rayon::iter::ParallelIterator;
483 arena
484 .values_as_slice()
485 .par_iter()
486 .zip(out.par_iter_mut())
487 .for_each(|(e, out_slot)| {
488 *out_slot = std::mem::MaybeUninit::new(handler(e));
489 });
490 }
491
492 fn pdm_if_applicable<D, F>(arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, handler: &F, out: &mut [std::mem::MaybeUninit<D>])
493 where
494 D: Send,
495 F: Fn(&mut dyn $trait_name) -> D + Sync + Send,
496 {
497 use $crate::rayon::iter::IntoParallelRefMutIterator;
498 use $crate::rayon::iter::IndexedParallelIterator;
499 use $crate::rayon::iter::ParallelIterator;
500 arena
501 .values_as_mut_slice()
502 .par_iter_mut()
503 .zip(out.par_iter_mut())
504 .for_each(|(e, out_slot)| {
505 *out_slot = std::mem::MaybeUninit::new(handler(e));
506 });
507 }
508
509 fn pda_if_applicable<D, F>(arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, handler: &F, i: &[D])
510 where
511 D: Sync,
512 F: Fn(&mut dyn $trait_name, &D) + Send + Sync {
513 use $crate::rayon::iter::IntoParallelRefMutIterator;
514 use $crate::rayon::iter::IndexedParallelIterator;
515 use $crate::rayon::iter::IntoParallelRefIterator;
516 use $crate::rayon::iter::ParallelIterator;
517 arena
518 .values_as_mut_slice()
519 .par_iter_mut()
520 .zip(i.par_iter())
521 .for_each(|(e, in_value)| {
522 handler(e, in_value);
523 });
524 }
525
526 const ACTIVE: bool = true;
527}
528
529)*
530 }
531 };
532}
533
534#[doc(hidden)]
535#[macro_export]
536macro_rules! __world_define_visitors_common {
537 (@pass_entity_tuple $struct_name:ident $($trait_name:ident),* @ $entity_tuple:tt) => {
541 $crate::paste::paste! {
542 $(
543 #[allow(unused)]
545 pub fn [<visit_ $trait_name:snake>]<F>(&self, mut handler: F)
546 where
547 F: FnMut(&dyn $trait_name)
548 {
549 $crate::__world_define_visitors_common!(@v_use_entity_tuple $struct_name $trait_name $entity_tuple self handler);
550 }
551
552 #[allow(unused)]
554 pub fn [<visit_mut_ $trait_name:snake>]<F>(&mut self, mut handler: F)
555 where
556 F: FnMut(&mut dyn $trait_name)
557 {
558 $crate::__world_define_visitors_common!(@vm_use_entity_tuple $struct_name $trait_name $entity_tuple self handler);
559 }
560
561 #[allow(unused)]
567 pub fn [<visit_key_ $trait_name:snake>]<F>(&self, mut handler: F)
568 where
569 F: FnMut(([<$struct_name ArenaID>], $crate::slotmap::DefaultKey), &dyn $trait_name)
570 {
571 $crate::__world_define_visitors_common!(@vk_use_entity_tuple $struct_name $trait_name $entity_tuple self handler);
572 }
573
574 #[allow(unused)]
580 pub fn [<visit_key_mut_ $trait_name:snake>]<F>(&mut self, mut handler: F)
581 where
582 F: FnMut(([<$struct_name ArenaID>], $crate::slotmap::DefaultKey), &mut dyn $trait_name)
583 {
584 $crate::__world_define_visitors_common!(@vkm_use_entity_tuple $struct_name $trait_name $entity_tuple self handler);
585 }
586
587 #[allow(unused)]
589 pub fn [<retain_ $trait_name:snake>]<F>(&mut self, mut predicate: F)
590 where
591 F: FnMut(&mut dyn $trait_name) -> bool
592 {
593 self.[<retain_with_default_ $trait_name:snake>]::<true, F>(predicate)
594 }
595
596 #[allow(unused)]
604 pub fn [<retain_with_default_ $trait_name:snake>]<const DEFAULT: bool, F>(&mut self, mut predicate: F)
605 where
606 F: FnMut(&mut dyn $trait_name) -> bool
607 {
608 $crate::__world_define_visitors_common!(@r_use_entity_tuple $struct_name $trait_name $entity_tuple self predicate DEFAULT);
609 }
610
611 #[allow(unused)]
617 pub fn [<diff_ $trait_name:snake>]<D, F>(&mut self, mut handler: F) -> Vec<D>
618 where
619 F: FnMut(&dyn $trait_name) -> D
620 {
621 $crate::__world_define_visitors_common!(@d_use_entity_tuple $struct_name $trait_name $entity_tuple self handler);
622 }
623
624 #[allow(unused)]
630 pub fn [<diff_mut_ $trait_name:snake>]<D, F>(&mut self, mut handler: F) -> Vec<D>
631 where
632 F: FnMut(&mut dyn $trait_name) -> D
633 {
634 $crate::__world_define_visitors_common!(@dm_use_entity_tuple $struct_name $trait_name $entity_tuple self handler);
635 }
636
637 #[allow(unused)]
642 pub fn [<diff_apply_ $trait_name:snake>]<D, F>(&mut self, diff: Vec<D>, mut handler: F)
643 where F: FnMut(&mut dyn $trait_name, &D)
644 {
645 $crate::__world_define_visitors_common!(@da_use_entity_tuple $struct_name $trait_name $entity_tuple self diff handler);
646 }
647
648 #[allow(unused)]
651 pub fn [<clear_ $trait_name:snake>](&mut self) {
652 $crate::__world_define_visitors_common!(@clear_use_entity_tuple $struct_name $trait_name $entity_tuple self);
653 }
654
655 #[allow(unused)]
657 pub fn [<len_ $trait_name:snake>](&self) -> usize {
658 $crate::__world_define_visitors_common!(@len_use_entity_tuple $struct_name $trait_name $entity_tuple self)
659 }
660
661 #[allow(unused)]
663 pub fn [<any_arenas_ $trait_name:snake>](&self) -> [&dyn $crate::ErasedArena; $crate::__world_define_visitors_common!(@any_arenas_count_use_entity_tuple $struct_name $trait_name $entity_tuple)] {
664 $crate::__world_define_visitors_common!(@any_arenas_use_entity_tuple $struct_name $trait_name $entity_tuple self)
665 }
666
667 #[allow(unused)]
669 pub fn [<any_arenas_mut_ $trait_name:snake>](&mut self) -> [&mut dyn $crate::ErasedArena; $crate::__world_define_visitors_common!(@any_arenas_count_use_entity_tuple $struct_name $trait_name $entity_tuple)] {
670 $crate::__world_define_visitors_common!(@any_arenas_mut_use_entity_tuple $struct_name $trait_name $entity_tuple self)
671 }
672 )*
673 }
674 };
675
676 (@v_use_entity_tuple $struct_name:ident $trait_name:ident ($( $entity:ty ),*) $self_ident:ident $handler_ident:ident) => {
677 $crate::paste::paste! {
678 $(
679 <() as [<$struct_name VisitIf $trait_name>]<$entity>>::v_if_applicable(
680 &$self_ident.[<$entity:snake>],
681 &mut $handler_ident,
682 );
683 )*
684 }
685 };
686
687 (@vk_use_entity_tuple $struct_name:ident $trait_name:ident ($( $entity:ty ),*) $self_ident:ident $handler_ident:ident) => {
688 $crate::paste::paste! {
689 $(
690 <() as [<$struct_name VisitIf $trait_name>]<$entity>>::vk_if_applicable(
691 &$self_ident.[<$entity:snake>],
692 &mut $handler_ident,
693 );
694 )*
695 }
696 };
697
698 (@vm_use_entity_tuple $struct_name:ident $trait_name:ident ($( $entity:ty ),*) $self_ident:ident $handler_ident:ident) => {
699 $crate::paste::paste! {
700 $(
701 <() as [<$struct_name VisitIf $trait_name>]<$entity>>::mv_if_applicable(
702 &mut $self_ident.[<$entity:snake>],
703 &mut $handler_ident,
704 );
705 )*
706 }
707 };
708
709 (@vkm_use_entity_tuple $struct_name:ident $trait_name:ident ($( $entity:ty ),*) $self_ident:ident $handler_ident:ident) => {
710 $crate::paste::paste! {
711 $(
712 <() as [<$struct_name VisitIf $trait_name>]<$entity>>::vkm_if_applicable(
713 &mut $self_ident.[<$entity:snake>],
714 &mut $handler_ident,
715 );
716 )*
717 }
718 };
719
720 (@r_use_entity_tuple $struct_name:ident $trait_name:ident ($( $entity:ty ),*) $self_ident:ident $predicate:ident $default:ident) => {
721 $crate::paste::paste! {
722 $(
723 if <() as [<$struct_name VisitIf $trait_name>]<$entity>>::ACTIVE {
724 <() as [<$struct_name VisitIf $trait_name>]<$entity>>::r_if_applicable::<_>(
725 &mut $self_ident.[<$entity:snake>],
726 &mut $predicate,
727 );
728 } else {
729 if !$default {
730 $self_ident.[<$entity:snake>].clear();
731 }
732 }
733 )*
734 }
735 };
736
737 (@d_use_entity_tuple $struct_name:ident $trait_name:ident ($( $entity:ty ),*) $self_ident:ident $handler_ident:ident) => {
738 $crate::paste::paste! {
739 let len = $self_ident.[<len_$trait_name:snake>]();
740 let mut out: Vec<std::mem::MaybeUninit<D>> = Vec::with_capacity(len);
742 unsafe { out.set_len(len); }
743 let mut offset = 0usize;
744 $(
745 let arena_len = <() as [<$struct_name VisitIf $trait_name>]<$entity>>::len_if_applicable(
746 & $self_ident.[<$entity:snake>],
747 );
748
749 <() as [<$struct_name VisitIf $trait_name>]<$entity>>::d_if_applicable(
750 & $self_ident.[<$entity:snake>],
751 &mut $handler_ident,
752 &mut out[offset..offset + arena_len],
753 );
754
755 offset += arena_len;
756 )*
757
758 return unsafe { let ptr = out.as_mut_ptr() as *mut D;
760 let len = out.len();
761 let cap = out.capacity();
762 ::std::mem::forget(out);
763 ::std::vec::Vec::from_raw_parts(ptr, len, cap)
764 };
765 }
766 };
767
768 (@dm_use_entity_tuple $struct_name:ident $trait_name:ident ($( $entity:ty ),*) $self_ident:ident $handler_ident:ident) => {
769 $crate::paste::paste! {
770 let len = $self_ident.[<len_$trait_name:snake>]();
771 let mut out: Vec<std::mem::MaybeUninit<D>> = Vec::with_capacity(len);
773 unsafe { out.set_len(len); }
774 let mut offset = 0usize;
775 $(
776 let arena_len = <() as [<$struct_name VisitIf $trait_name>]<$entity>>::len_if_applicable(
777 & $self_ident.[<$entity:snake>],
778 );
779
780 <() as [<$struct_name VisitIf $trait_name>]<$entity>>::dm_if_applicable(
781 &mut $self_ident.[<$entity:snake>],
782 &mut $handler_ident,
783 &mut out[offset..offset + arena_len],
784 );
785
786 offset += arena_len;
787 )*
788
789 return unsafe { let ptr = out.as_mut_ptr() as *mut D;
791 let len = out.len();
792 let cap = out.capacity();
793 ::std::mem::forget(out);
794 ::std::vec::Vec::from_raw_parts(ptr, len, cap)
795 };
796 }
797 };
798
799 (@da_use_entity_tuple $struct_name:ident $trait_name:ident ($( $entity:ty ),*) $self_ident:ident $diff_ident:ident $handler_ident:ident) => {
800 $crate::paste::paste! {
801 let mut offset = 0usize;
802 $(
803 let arena_len = <() as [<$struct_name VisitIf $trait_name>]<$entity>>::len_if_applicable(
804 & $self_ident.[<$entity:snake>],
805 );
806
807 <() as [<$struct_name VisitIf $trait_name>]<$entity>>::da_if_applicable(
808 &mut $self_ident.[<$entity:snake>],
809 &mut $handler_ident,
810 &$diff_ident[offset..offset + arena_len],
811 );
812
813 offset += arena_len;
814 )*
815 }
816 };
817
818 (@clear_use_entity_tuple $struct_name:ident $trait_name:ident ($( $entity:ty ),*) $self_ident:ident) => {
819 $crate::paste::paste! {
820 $(
821 <() as [<$struct_name VisitIf $trait_name>]<$entity>>::clear_if_applicable(
822 &mut $self_ident.[<$entity:snake>],
823 );
824 )*
825 }
826 };
827
828 (@len_use_entity_tuple $struct_name:ident $trait_name:ident ($( $entity:ty ),*) $self_ident:ident) => {
829 $crate::paste::paste! {
830 {
831 let mut total = 0usize;
832 $(
833 total += <() as [<$struct_name VisitIf $trait_name>]<$entity>>::len_if_applicable(
834 & $self_ident.[<$entity:snake>],
835 );
836 )*
837 total
838 }
839 }
840 };
841
842 (@any_arenas_count_use_entity_tuple $struct_name:ident $trait_name:ident ($( $entity:ty ),*) ) => {
843 $crate::paste::paste! {
844 {
845 0 $(+ if <() as [<$struct_name VisitIf $trait_name>]<$entity>>::ACTIVE {1} else {0})*
846 }
847 }
848 };
849
850 (@any_arenas_use_entity_tuple $struct_name:ident $trait_name:ident ($( $entity:ty ),*) $self_ident:ident) => {
851 $crate::paste::paste! {
852 {
853 const NUM_ARENAS: usize = 0 $(+ if <() as [<$struct_name VisitIf $trait_name>]<$entity>>::ACTIVE {1} else {0})*;
854 let mut tmp: [std::mem::MaybeUninit<&dyn $crate::ErasedArena>; NUM_ARENAS] = unsafe { std::mem::MaybeUninit::uninit().assume_init() };
855 let mut idx = 0;
856 $(
857 if <() as [<$struct_name VisitIf $trait_name>]<$entity>>::ACTIVE {
858 tmp[idx] = std::mem::MaybeUninit::new(&$self_ident.[<$entity:snake>] as &dyn $crate::ErasedArena);
859 idx += 1;
860 }
861 )*
862 unsafe {
863 std::mem::transmute::<
864 [std::mem::MaybeUninit<&dyn $crate::ErasedArena>; NUM_ARENAS],
865 [&dyn $crate::ErasedArena; NUM_ARENAS]
866 >(tmp)
867 }
868 }
869 }
870 };
871
872 (@any_arenas_mut_use_entity_tuple $struct_name:ident $trait_name:ident ($( $entity:ty ),*) $self_ident:ident) => {
873 $crate::paste::paste! {
874 {
875 const NUM_ARENAS: usize = 0 $(+ if <() as [<$struct_name VisitIf $trait_name>]<$entity>>::ACTIVE {1} else {0})*;
876 let mut tmp: [std::mem::MaybeUninit<&mut dyn $crate::ErasedArena>; NUM_ARENAS] = unsafe { std::mem::MaybeUninit::uninit().assume_init() };
877 let mut idx = 0;
878 $(
879 if <() as [<$struct_name VisitIf $trait_name>]<$entity>>::ACTIVE {
880 tmp[idx] = std::mem::MaybeUninit::new(&mut $self_ident.[<$entity:snake>] as &mut dyn $crate::ErasedArena);
881 idx += 1;
882 }
883 )*
884 unsafe {
885 std::mem::transmute::<
886 [std::mem::MaybeUninit<&mut dyn $crate::ErasedArena>; NUM_ARENAS],
887 [&mut dyn $crate::ErasedArena; NUM_ARENAS]
888 >(tmp)
889 }
890 }
891 }
892 };
893}
894
895#[doc(hidden)]
896#[macro_export]
897#[cfg(not(feature = "rayon"))]
898macro_rules! __world_define_visitors {
899 (@pass_entity_tuple $struct_name:ident $($trait_name:ident),* @ $entity_tuple:tt) => {
901 $crate::__world_define_visitors_common!(@pass_entity_tuple $struct_name $($trait_name),* @ $entity_tuple);
902 };
903}
904
905#[doc(hidden)]
906#[macro_export]
907#[cfg(feature = "rayon")]
908macro_rules! __world_define_visitors {
909 (@pass_entity_tuple $struct_name:ident $($trait_name:ident),* @ $entity_tuple:tt) => {
913 $crate::__world_define_visitors_common!(@pass_entity_tuple $struct_name $($trait_name),* @ $entity_tuple);
915
916 $crate::paste::paste! {
918 $(
919 #[allow(unused)]
921 pub fn [<par_visit_ $trait_name:snake>]<F>(&self, handler: F)
922 where
923 F: Fn(&dyn $trait_name) + Send + Sync
924 {
925 $crate::__world_define_visitors!(@pv_use_entity_tuple $struct_name $trait_name $entity_tuple self handler);
926 }
927
928 #[allow(unused)]
930 pub fn [<par_visit_mut_ $trait_name:snake>]<F>(&mut self, handler: F)
931 where
932 F: Fn(&mut dyn $trait_name) + Send + Sync
933 {
934 $crate::__world_define_visitors!(@pvm_use_entity_tuple $struct_name $trait_name $entity_tuple self handler);
935 }
936
937 #[allow(unused)]
944 pub fn [<par_visit_key_ $trait_name:snake>]<F>(&self, handler: F)
945 where
946 F: Fn(([<$struct_name ArenaID>], $crate::slotmap::DefaultKey), &dyn $trait_name) + Send + Sync
947 {
948 $crate::__world_define_visitors!(@pvk_use_entity_tuple $struct_name $trait_name $entity_tuple self handler);
949 }
950
951 #[allow(unused)]
958 pub fn [<par_visit_key_mut_ $trait_name:snake>]<F>(&mut self, handler: F)
959 where
960 F: Fn(([<$struct_name ArenaID>], $crate::slotmap::DefaultKey), &mut dyn $trait_name) + Send + Sync
961 {
962 $crate::__world_define_visitors!(@pvkm_use_entity_tuple $struct_name $trait_name $entity_tuple self handler);
963 }
964
965 #[allow(unused)]
967 pub fn [<par_retain_ $trait_name:snake>]<F>(&mut self, mut predicate: F)
968 where
969 F: Fn(&mut dyn $trait_name) -> bool + Send + Sync
970 {
971 self.[<par_retain_with_default_ $trait_name:snake>]::<true, F>(predicate)
972 }
973
974 #[allow(unused)]
985 pub fn [<par_retain_with_default_ $trait_name:snake>]<const DEFAULT: bool, F>(&mut self, mut predicate: F)
986 where
987 F: Fn(&mut dyn $trait_name) -> bool + Send + Sync
988 {
989 $crate::__world_define_visitors!(@pr_use_entity_tuple $struct_name $trait_name $entity_tuple self predicate DEFAULT);
990 }
991
992 #[allow(unused)]
997 pub fn [<par_diff_ $trait_name:snake>]<D, F>(&mut self, mut handler: F) -> Vec<D>
998 where
999 D: Send,
1000 F: Fn(&dyn $trait_name) -> D + Send + Sync
1001 {
1002 $crate::__world_define_visitors!(@pd_use_entity_tuple $struct_name $trait_name $entity_tuple self handler);
1003 }
1004
1005 #[allow(unused)]
1011 pub fn [<par_diff_mut_ $trait_name:snake>]<D, F>(&mut self, mut handler: F) -> Vec<D>
1012 where
1013 D: Send,
1014 F: Fn(&mut dyn $trait_name) -> D + Send + Sync
1015 {
1016 $crate::__world_define_visitors!(@pdm_use_entity_tuple $struct_name $trait_name $entity_tuple self handler);
1017 }
1018
1019 #[allow(unused)]
1024 pub fn [<par_diff_apply_ $trait_name:snake>]<D, F>(&mut self, diff: Vec<D>, handler: F)
1025 where
1026 D: Sync,
1027 F: Fn(&mut dyn $trait_name, &D) + Send + Sync
1028 {
1029 $crate::__world_define_visitors!(@pda_use_entity_tuple $struct_name $trait_name $entity_tuple self diff handler);
1030 }
1031 )*
1032 }
1033 };
1034
1035 (@pv_use_entity_tuple $struct_name:ident $trait_name:ident ($( $entity:ty ),*) $self_ident:ident $handler_ident:ident) => {
1036 $crate::paste::paste! {
1037 use $crate::rayon::scope;
1038 scope(|s| {
1039 $(
1040 if <() as [<$struct_name ParVisitIf $trait_name>]<$entity>>::ACTIVE {
1041 let arena_ref = &$self_ident.[<$entity:snake>];
1042 s.spawn(|_| {
1043 <() as [<$struct_name ParVisitIf $trait_name>]<$entity>>::pv_if_applicable(
1044 arena_ref,
1045 &$handler_ident,
1046 );
1047 });
1048 }
1049 )*
1050 });
1051 }
1052 };
1053
1054 (@pvk_use_entity_tuple $struct_name:ident $trait_name:ident ($( $entity:ty ),*) $self_ident:ident $handler_ident:ident) => {
1055 $crate::paste::paste! {
1056 use $crate::rayon::scope;
1057 scope(|s| {
1058 $(
1059 if <() as [<$struct_name ParVisitIf $trait_name>]<$entity>>::ACTIVE {
1060 let arena_ref = &$self_ident.[<$entity:snake>];
1061 s.spawn(|_| {
1062 <() as [<$struct_name ParVisitIf $trait_name>]<$entity>>::pvk_if_applicable(
1063 arena_ref,
1064 &$handler_ident,
1065 );
1066 });
1067 }
1068 )*
1069 });
1070 }
1071 };
1072
1073 (@pvm_use_entity_tuple $struct_name:ident $trait_name:ident ($( $entity:ty ),*) $self_ident:ident $handler_ident:ident) => {
1074 $crate::paste::paste! {
1075 use $crate::rayon::scope;
1076 scope(|s| {
1077 $(
1078 if <() as [<$struct_name ParVisitIf $trait_name>]<$entity>>::ACTIVE {
1079 s.spawn(|_| {
1080 <() as [<$struct_name ParVisitIf $trait_name>]<$entity>>::pvm_if_applicable(
1081 &mut $self_ident.[<$entity:snake>],
1082 &$handler_ident,
1083 );
1084 });
1085 }
1086 )*
1087 });
1088 }
1089 };
1090
1091 (@pvkm_use_entity_tuple $struct_name:ident $trait_name:ident ($( $entity:ty ),*) $self_ident:ident $handler_ident:ident) => {
1092 $crate::paste::paste! {
1093 use $crate::rayon::scope;
1094 scope(|s| {
1095 $(
1096 if <() as [<$struct_name ParVisitIf $trait_name>]<$entity>>::ACTIVE {
1097 s.spawn(|_| {
1098 <() as [<$struct_name ParVisitIf $trait_name>]<$entity>>::pvkm_if_applicable(
1099 &mut $self_ident.[<$entity:snake>],
1100 &$handler_ident,
1101 );
1102 });
1103 }
1104 )*
1105 });
1106 }
1107 };
1108
1109 (@pr_use_entity_tuple $struct_name:ident $trait_name:ident ($( $entity:ty ),*) $self_ident:ident $predicate_ident:ident $default:ident) => {
1110 $crate::paste::paste! {
1111 use $crate::rayon::scope;
1112 scope(|s| {
1113 $(
1114 if <() as [<$struct_name ParVisitIf $trait_name>]<$entity>>::ACTIVE {
1115 s.spawn(|_| {
1116 <() as [<$struct_name ParVisitIf $trait_name>]<$entity>>::pr_if_applicable::<_>(
1117 &mut $self_ident.[<$entity:snake>],
1118 &$predicate_ident,
1119 );
1120 });
1121 } else {
1122 if !$default {
1123 $self_ident.[<$entity:snake>].clear();
1124 }
1125 }
1126 )*
1127 });
1128 }
1129 };
1130
1131 (@pd_use_entity_tuple $struct_name:ident $trait_name:ident ($( $entity:ty ),*) $self_ident:ident $handler_ident:ident) => {
1132 $crate::paste::paste! {
1133 let len = $self_ident.[<len_$trait_name:snake>]();
1134 let mut out: Vec<std::mem::MaybeUninit<D>> = Vec::with_capacity(len);
1136 unsafe { out.set_len(len); }
1137 use $crate::rayon::scope;
1138 scope(|s| {
1139 let mut remaining: &mut [_] = &mut out[..];
1140 $(
1141 if <() as [<$struct_name ParVisitIf $trait_name>]<$entity>>::ACTIVE {
1142 let arena_len = <() as [<$struct_name VisitIf $trait_name>]<$entity>>::len_if_applicable(
1143 & $self_ident.[<$entity:snake>],
1144 );
1145
1146 let (arena_slice, rest) = remaining.split_at_mut(arena_len);
1147 remaining = rest;
1148 let arena_ref = &$self_ident.[<$entity:snake>];
1149 let handler_ref = &$handler_ident;
1150 s.spawn(move |_| {
1151 <() as [<$struct_name ParVisitIf $trait_name>]<$entity>>::pd_if_applicable(
1152 arena_ref,
1153 handler_ref,
1154 arena_slice,
1155 );
1156 });
1157 }
1158 )*
1159 });
1160
1161 return unsafe { let ptr = out.as_mut_ptr() as *mut D;
1163 let len = out.len();
1164 let cap = out.capacity();
1165 ::std::mem::forget(out);
1166 ::std::vec::Vec::from_raw_parts(ptr, len, cap)
1167 };
1168 }
1169 };
1170
1171 (@pdm_use_entity_tuple $struct_name:ident $trait_name:ident ($( $entity:ty ),*) $self_ident:ident $handler_ident:ident) => {
1172 $crate::paste::paste! {
1173 let len = $self_ident.[<len_$trait_name:snake>]();
1174 let mut out: Vec<std::mem::MaybeUninit<D>> = Vec::with_capacity(len);
1176 unsafe { out.set_len(len); }
1177 use $crate::rayon::scope;
1178 scope(|s| {
1179 let mut remaining: &mut [_] = &mut out[..];
1180 $(
1181 if <() as [<$struct_name ParVisitIf $trait_name>]<$entity>>::ACTIVE {
1182 let arena_len = <() as [<$struct_name VisitIf $trait_name>]<$entity>>::len_if_applicable(
1183 & $self_ident.[<$entity:snake>],
1184 );
1185
1186 let (arena_slice, rest) = remaining.split_at_mut(arena_len);
1187 remaining = rest;
1188 let arena_ref = &mut $self_ident.[<$entity:snake>];
1189 let handler_ref = &$handler_ident;
1190 s.spawn(move |_| {
1191 <() as [<$struct_name ParVisitIf $trait_name>]<$entity>>::pdm_if_applicable(
1192 arena_ref,
1193 handler_ref,
1194 arena_slice,
1195 );
1196 });
1197 }
1198 )*
1199 });
1200
1201 return unsafe { let ptr = out.as_mut_ptr() as *mut D;
1203 let len = out.len();
1204 let cap = out.capacity();
1205 ::std::mem::forget(out);
1206 ::std::vec::Vec::from_raw_parts(ptr, len, cap)
1207 };
1208 }
1209 };
1210
1211 (@pda_use_entity_tuple $struct_name:ident $trait_name:ident ($( $entity:ty ),*) $self_ident:ident $diff_ident:ident $handler_ident:ident) => {
1212 $crate::paste::paste! {
1213 use $crate::rayon::scope;
1214 scope(|s| {
1215 let mut remaining: &[_] = &$diff_ident[..];
1216 $(
1217 if <() as [<$struct_name ParVisitIf $trait_name>]<$entity>>::ACTIVE {
1218 let arena_len = <() as [<$struct_name VisitIf $trait_name>]<$entity>>::len_if_applicable(
1219 & $self_ident.[<$entity:snake>],
1220 );
1221
1222 let (arena_slice, rest) = remaining.split_at(arena_len);
1223 remaining = rest;
1224 let arena_ref = &mut $self_ident.[<$entity:snake>];
1225 let handler_ref = &$handler_ident;
1226
1227 s.spawn(move |_| {
1228 <() as [<$struct_name ParVisitIf $trait_name>]<$entity>>::pda_if_applicable(
1229 arena_ref,
1230 handler_ref,
1231 arena_slice,
1232 );
1233 });
1234 }
1235 )*
1236 });
1237 }
1238};
1239}
1240
1241#[doc(hidden)]
1242#[macro_export]
1243#[cfg(not(feature = "debug"))]
1244macro_rules! __world_define_struct {
1245 ($struct_name:ident, $( $entity:ty ),*) => {
1246 $crate::paste::paste! {
1247 #[derive(Default)]
1248 #[allow(private_interfaces)] pub struct $struct_name {
1250 $(
1251 pub [<$entity:snake>]: $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, $entity>,
1252 )*
1253 }
1254 }
1255 };
1256}
1257
1258#[doc(hidden)]
1259#[macro_export]
1260#[cfg(feature = "debug")]
1261macro_rules! __world_define_struct {
1262 ($struct_name:ident, $( $entity:ty ),*) => {
1263 $crate::paste::paste! {
1264 #[derive(Default, Debug)]
1265 #[allow(private_interfaces)] pub struct $struct_name {
1267 $(
1268 pub [<$entity:snake>]: $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, $entity>,
1269 )*
1270 }
1271 }
1272 };
1273}
1274
1275#[doc(hidden)]
1276#[macro_export]
1277#[cfg(not(feature = "serde"))]
1278macro_rules! __world_serde_support {
1279 ($struct_name:ident $( $entity:ty ),*) => {};
1280}
1281
1282#[doc(hidden)]
1283#[macro_export]
1284#[cfg(feature = "serde")]
1285macro_rules! __world_serde_support {
1286 ($struct_name:ident $( $entity:ty ),*) => {
1287 $crate::paste::paste! {
1288
1289impl $crate::serde::Serialize for [<$struct_name ArenaID>] {
1290 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1291 where
1292 S: $crate::serde::Serializer,
1293 {
1294 let s = match self.0 {
1295 $(
1296 i if i == $struct_name::arena_id::<$entity>().0 => stringify!($entity),
1297 )*
1298 _ => return Err($crate::serde::ser::Error::custom(format!("Unknown ArenaID {}", self.0))),
1300 };
1301 serializer.serialize_str(s)
1302 }
1303}
1304
1305impl<'de> $crate::serde::Deserialize<'de> for [<$struct_name ArenaID>] {
1306 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1307 where
1308 D: $crate::serde::Deserializer<'de>,
1309 {
1310 let s = String::deserialize(deserializer)?;
1311 let id = match s.as_str() {
1312 $(
1313 stringify!($entity) => $struct_name::arena_id::<$entity>().0,
1314 )*
1315 _ => return Err($crate::serde::de::Error::custom(format!("Unknown ArenaID string {}", s))),
1317 };
1318 Ok([<$struct_name ArenaID>](id))
1319 }
1320}
1321
1322impl $crate::serde::ser::Serialize for $struct_name {
1323 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
1324 where
1325 S: $crate::serde::ser::Serializer,
1326 {
1327 use $crate::SerdeArena;
1328 use $crate::serde::ser::SerializeStruct;
1329
1330 let field_count = 0 $( + if <$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, $entity> as $crate::SerdeArena<'static>>::ACTIVE { 1 } else { 0 } )*;
1331 let mut state = serializer.serialize_struct(
1332 stringify!($struct_name),
1333 field_count
1334 )?;
1335 $(
1336 self.[<$entity:snake>].serialize_arena(stringify!($entity), &mut state)?;
1337 )*
1338 state.end()
1339 }
1340}
1341
1342static [<$struct_name:upper _DESERIALIZE_FIELDS>]: &'static [&'static str] = &{
1344 const TMP: [Option<&'static str>; { 0 $(+ { let _ = stringify!($entity); 1 })* }] = [
1345 $(
1346 if <$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, $entity>
1347 as $crate::SerdeArena<'static>>::ACTIVE {
1348 Some(stringify!($entity))
1349 } else {
1350 None
1351 }
1352 ),*
1353 ];
1354
1355 const COUNT: usize = 0 $(+ if (<$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, $entity>
1356 as $crate::SerdeArena<'static>>::ACTIVE) {1} else {0})*;
1357
1358 let mut arr: [&'static str; COUNT] = [""; COUNT];
1359 let mut j = 0;
1360 let mut k = 0;
1361 while j < TMP.len() {
1362 if let Some(s) = TMP[j] {
1363 arr[k] = s;
1364 k += 1;
1365 }
1366 j += 1;
1367 }
1368
1369 arr
1370};
1371
1372impl<'de> $crate::serde::Deserialize<'de> for $struct_name {
1373 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1374 where
1375 D: $crate::serde::Deserializer<'de>,
1376 {
1377 use $crate::serde::de::{MapAccess, SeqAccess, Visitor, Error};
1378 use std::fmt;
1379
1380 struct WorldVisitor;
1381
1382 impl<'de> Visitor<'de> for WorldVisitor {
1383 type Value = $struct_name;
1384
1385 fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
1386 write!(f, "struct {}", stringify!($struct_name))
1387 }
1388
1389 fn visit_map<V>(self, mut map: V) -> Result<$struct_name, V::Error>
1391 where
1392 V: MapAccess<'de>,
1393 {
1394 let mut world = $struct_name::default();
1395
1396 while let Some(key) = map.next_key::<String>()? {
1397 match key.as_str() {
1398 $(
1399 stringify!($entity) => {
1400 world.[<$entity:snake>] =
1401 <$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, $entity> as $crate::SerdeArena<'de>>::deserialize_arena(&mut map)?;
1402 }
1403 )*
1404 other => {
1405 return Err(V::Error::custom(format!(
1406 "Unknown field '{}' for {}",
1407 other,
1408 stringify!($struct_name)
1409 )));
1410 }
1411 }
1412 }
1413
1414 Ok(world)
1415 }
1416
1417 fn visit_seq<V>(self, mut seq: V) -> Result<$struct_name, V::Error>
1420 where
1421 V: SeqAccess<'de>,
1422 {
1423 Ok($struct_name {
1424 $(
1425 [<$entity:snake>]: <$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, $entity> as $crate::SerdeArena<'de>>::from_seq(&mut seq, stringify!($entity))?,
1426 )*
1427 })
1428 }
1429 }
1430
1431 deserializer.deserialize_struct(
1436 stringify!($struct_name),
1437 &[<$struct_name:upper _DESERIALIZE_FIELDS>],
1438 WorldVisitor,
1439 )
1440 }
1441}
1442 }
1443 };
1444}
1445
1446#[macro_export]
1457macro_rules! world {
1458 (
1460 $struct_name:ident, $( $entity:ty ),* $(,)? ;$( $trait_name:ident ),* $(,)? ) => {
1467 $crate::paste::paste! {
1468
1469#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
1474pub struct [<$struct_name ArenaID>](usize);
1475
1476$crate::__world_define_struct!($struct_name, $($entity),*);
1477
1478$(
1479 trait [<$struct_name VisitIf $trait_name>]<T> {
1480 fn v_if_applicable<F>(arena: &$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, handler: F)
1481 where
1482 F: FnMut(&dyn $trait_name);
1483
1484 fn mv_if_applicable<F>(arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, handler: F)
1485 where
1486 F: FnMut(&mut dyn $trait_name);
1487
1488 fn vk_if_applicable<F>(arena: &$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, handler: F)
1489 where
1490 F: FnMut(([<$struct_name ArenaID>], $crate::slotmap::DefaultKey), &dyn $trait_name);
1491
1492 fn vkm_if_applicable<F>(arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, handler: F)
1493 where
1494 F: FnMut(([<$struct_name ArenaID>], $crate::slotmap::DefaultKey), &mut dyn $trait_name);
1495
1496 fn r_if_applicable<P>(arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, predicate: P)
1497 where
1498 P: FnMut(&mut dyn $trait_name) -> bool;
1499
1500 fn d_if_applicable<D, F>(arena: &$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, handler: F, out: &mut [std::mem::MaybeUninit<D>])
1501 where
1502 F: FnMut(&dyn $trait_name) -> D;
1503
1504 fn dm_if_applicable<D, F>(arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, handler: F, out: &mut [std::mem::MaybeUninit<D>])
1505 where
1506 F: FnMut(&mut dyn $trait_name) -> D;
1507
1508 fn da_if_applicable<D, F>(arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, handler: F, i: &[D])
1509 where
1510 F: FnMut(&mut dyn $trait_name, &D);
1511
1512 fn clear_if_applicable(arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>);
1513
1514 fn len_if_applicable(arena: & $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>) -> usize;
1515
1516 const ACTIVE: bool;
1517 }
1518
1519 impl<T> [<$struct_name VisitIf $trait_name>]<T> for () {
1521 default fn v_if_applicable<F>(_arena: &$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, _handler: F)
1522 where F: FnMut(&dyn $trait_name) {}
1523
1524 default fn mv_if_applicable<F>(_arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, _handler: F)
1525 where F: FnMut(&mut dyn $trait_name) {}
1526
1527 default fn vk_if_applicable<F>(_arena: &$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, _handler: F)
1528 where F: FnMut(([<$struct_name ArenaID>], $crate::slotmap::DefaultKey), &dyn $trait_name) {}
1529
1530 default fn vkm_if_applicable<F>(_arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, _handler: F)
1531 where F: FnMut(([<$struct_name ArenaID>], $crate::slotmap::DefaultKey), &mut dyn $trait_name) {}
1532
1533 default fn r_if_applicable<P>(_arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, _predicate: P)
1534 where P: FnMut(&mut dyn $trait_name) -> bool {}
1535
1536 default fn d_if_applicable<D, F>(_arena: &$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, _handler: F, _out: &mut [std::mem::MaybeUninit<D>])
1537 where
1538 F: FnMut(&dyn $trait_name) -> D {}
1539
1540 default fn dm_if_applicable<D, F>(_arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, _handler: F, _out: &mut [std::mem::MaybeUninit<D>])
1541 where
1542 F: FnMut(&mut dyn $trait_name) -> D {}
1543
1544 default fn da_if_applicable<D, F>(_arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, _handler: F, _i: &[D])
1545 where
1546 F: FnMut(&mut dyn $trait_name, &D) {}
1547
1548 default fn clear_if_applicable(_arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>) {}
1549
1550 default fn len_if_applicable(_arena: & $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>) -> usize { 0 }
1551
1552 default const ACTIVE: bool = false;
1553 }
1554
1555 impl<T: $trait_name> [<$struct_name VisitIf $trait_name>]<T> for () {
1556 fn v_if_applicable<F>(arena: &$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, mut handler: F)
1557 where F: FnMut(&dyn $trait_name)
1558 {
1559 arena
1560 .values_as_slice()
1561 .iter()
1562 .for_each(|entity| handler(entity));
1563 }
1564
1565 fn mv_if_applicable<F>(arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, mut handler: F)
1566 where F: FnMut(&mut dyn $trait_name)
1567 {
1568 arena
1569 .values_as_mut_slice()
1570 .iter_mut()
1571 .for_each(|entity| handler(entity));
1572 }
1573
1574 fn r_if_applicable<P>(arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, mut predicate: P)
1575 where P: FnMut(&mut dyn $trait_name) -> bool
1576 {
1577 arena.retain(|_, entity| predicate(entity));
1578 }
1579
1580 fn d_if_applicable<D, F>(arena: &$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, mut handler: F, out: &mut [std::mem::MaybeUninit<D>])
1581 where
1582 F: FnMut(&dyn $trait_name) -> D {
1583 for (e, out_slot) in arena.values_as_slice().iter().zip(out.iter_mut()) {
1584 *out_slot = std::mem::MaybeUninit::new(handler(e));
1585 }
1586 }
1587
1588 fn dm_if_applicable<D, F>(arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, mut handler: F, out: &mut [std::mem::MaybeUninit<D>])
1589 where
1590 F: FnMut(&mut dyn $trait_name) -> D {
1591 for (e, out_slot) in arena.values_as_mut_slice().iter_mut().zip(out.iter_mut()) {
1592 *out_slot = std::mem::MaybeUninit::new(handler(e));
1593 }
1594 }
1595
1596 fn da_if_applicable<D, F>(arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, mut handler: F, i: &[D])
1597 where
1598 F: FnMut(&mut dyn $trait_name, &D) {
1599 for (e, in_value) in arena.values_as_mut_slice().iter_mut().zip(i.iter()) {
1600 handler(e, in_value);
1601 }
1602 }
1603
1604 fn vk_if_applicable<F>(arena: &$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, mut handler: F)
1605 where F: FnMut(([<$struct_name ArenaID>], $crate::slotmap::DefaultKey), &dyn $trait_name)
1606 {
1607 let keys = arena.keys_as_slice();
1608 let values = arena.values_as_slice();
1609 keys.iter()
1610 .zip(values.iter())
1611 .for_each(|(k, v)| handler(($struct_name::arena_id::<T>(), *k), v));
1612 }
1613
1614 fn vkm_if_applicable<F>(arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>, mut handler: F)
1615 where F: FnMut(([<$struct_name ArenaID>], $crate::slotmap::DefaultKey), &mut dyn $trait_name)
1616 {
1617 let (keys, values) = arena.keys_values_as_mut_slices();
1618 keys.iter()
1619 .zip(values.iter_mut())
1620 .for_each(|(k, v)| handler(($struct_name::arena_id::<T>(), *k), v));
1621 }
1622
1623 fn clear_if_applicable(arena: &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>) {
1624 arena.clear();
1625 }
1626
1627 fn len_if_applicable(arena: & $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T>) -> usize {
1628 arena.len()
1629 }
1630
1631 default const ACTIVE: bool = true;
1632 }
1633
1634)*
1635
1636impl $struct_name {
1637 $crate::__world_define_visitors!(@pass_entity_tuple $struct_name $($trait_name),* @ ($($entity),*));
1638
1639 #[allow(unused)]
1644 pub fn arena<T>(&self) -> &$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T> {
1645 use $crate::ArenaCast;
1646 $(
1647 if <T as $crate::IsType<$entity>>::VALUE {
1648 return <$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, $entity> as ArenaCast<T>>::cast(&self.[<$entity:snake>]);
1649 }
1650 )* panic!("In call to {}::arena::<{}>(), {} not registered", stringify!($struct_name), std::any::type_name::<T>(), std::any::type_name::<T>());
1652 }
1653
1654 #[allow(unused)]
1659 pub fn arena_mut<T>(&mut self) -> &mut $crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, T> {
1660 use $crate::ArenaCast;
1661 $(
1662 if <T as $crate::IsType<$entity>>::VALUE {
1663 return <$crate::slotmap::DenseSlotMap<$crate::slotmap::DefaultKey, $entity> as ArenaCast<T>>::cast_mut(&mut self.[<$entity:snake>]);
1664 }
1665 )*
1666 panic!("In call to {}::arena_mut::<{}>(), {} not registered", stringify!($struct_name), std::any::type_name::<T>(), std::any::type_name::<T>());
1667 }
1668
1669 #[allow(unused)]
1677 pub fn arena_id<T>() -> [<$struct_name ArenaID>] {
1678 let mut i = 0usize;
1679 $(
1680 if <T as $crate::IsType<$entity>>::VALUE {
1681 return [<$struct_name ArenaID>](i);
1682 }
1683 i += 1;
1684 )*
1685 panic!("In call to {}::arena_id::<{}>(), {} not registered", stringify!($struct_name), std::any::type_name::<T>(), std::any::type_name::<T>());
1686 }
1687
1688 #[allow(unused)]
1690 pub fn any_arena(&self, which: [<$struct_name ArenaID>]) -> &dyn $crate::ErasedArena {
1691 match which.0 {
1692 $(
1693 i if i == Self::arena_id::<$entity>().0 => &self.[<$entity:snake>] as &dyn $crate::ErasedArena,
1694 )*
1695 _ => panic!("No arena for type id {}", which.0),
1696 }
1697 }
1698
1699 #[allow(unused)]
1701 pub fn any_arena_mut(&mut self, which: [<$struct_name ArenaID>]) -> &mut dyn $crate::ErasedArena {
1702 match which.0 {
1703 $(
1704 i if i == Self::arena_id::<$entity>().0 => &mut self.[<$entity:snake>] as &mut dyn $crate::ErasedArena,
1705 )*
1706 _ => panic!("No mutable arena for type id {}", which.0),
1707 }
1708 }
1709
1710 #[allow(unused)]
1711 pub fn clear(&mut self) {
1712 $(
1713 self.[<$entity:snake>].clear();
1714 )*
1715 }
1716
1717 #[allow(unused)]
1718 pub fn len(&self) -> usize {
1719 0 $( + self.[<$entity:snake>].len() )*
1720 }
1721}
1722
1723$crate::__world_serde_support!($struct_name $($entity),*);
1724
1725$crate::__world_define_rayon_trait_helpers!($struct_name $($trait_name),*);
1726
1727 }
1728 };
1729}