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