cellular_raza_core/backend/chili/aux_storage.rs
1use cellular_raza_concepts::CycleEvent;
2pub use circ_buffer::*;
3use serde::{Deserialize, Serialize};
4
5pub use cellular_raza_concepts::Xapy;
6
7// --------------------------------- UPDATE-MECHANICS --------------------------------
8/// Used to store intermediate information about last positions and velocities.
9/// Can store up to `N` values.
10pub trait UpdateMechanics<Pos, Vel, For, const N: usize> {
11 /// Stores the last position of the cell. May overwrite old results depending on
12 /// how many old results are being stored.
13 fn set_last_position(&mut self, pos: Pos);
14
15 /// Get all previous positions. This number maybe smaller than the maximum number of stored
16 /// positions but never exceeds it.
17 fn previous_positions<'a>(&'a self) -> RingBufferIterRef<'a, Pos, N>;
18
19 /// Stores the last velocity of the cell. Overwrites old results when stored amount
20 /// exceeds number of maximum stored values.
21 fn set_last_velocity(&mut self, vel: Vel);
22
23 /// Get all previous velocities. This number may be smaller than the maximum number of stored
24 /// velocities but never exceeds it.
25 fn previous_velocities<'a>(&'a self) -> RingBufferIterRef<'a, Vel, N>;
26
27 /// Get the number of previous values currently stored
28 ///
29 /// This number is by definition between 0 and `N`.
30 fn n_previous_values(&self) -> usize;
31
32 /// Add force to currently stored forces
33 fn add_force(&mut self, force: For);
34
35 /// Obtain current force on cell
36 fn get_current_force_and_reset(&mut self) -> For;
37}
38
39/// Stores intermediate information about the mechanics of a cell.
40#[derive(Clone, Deserialize, Serialize)]
41pub struct AuxStorageMechanics<Pos, Vel, For, const N: usize> {
42 positions: RingBuffer<Pos, N>,
43 velocities: RingBuffer<Vel, N>,
44 current_force: For,
45 zero_force: For,
46}
47
48// It is necessary to implement this trait by hand since with the current version of the Mechanics
49// concept, we need to specify next_random_mechanics_update: Some(0.0) in order for any updates to
50// be done at all.
51impl<Pos, Vel, For, const N: usize> Default for AuxStorageMechanics<Pos, Vel, For, N>
52where
53 For: num::Zero,
54{
55 fn default() -> Self {
56 Self {
57 positions: RingBuffer::<Pos, N>::default(),
58 velocities: RingBuffer::<Vel, N>::default(),
59 current_force: num::Zero::zero(),
60 zero_force: num::Zero::zero(),
61 }
62 }
63}
64
65/// Used to construct initial (empty) AuxStorage variants.
66pub trait DefaultFrom<T> {
67 /// Constructs the Type in question from a given value. This is typically a zero value.
68 /// If it can be constructed from the [num::Zero] trait, this method is not required and
69 /// `cellular_raza` will determine the initial zero-value correctly.
70 /// For other types (ie. dynamically-sized ones) additional entries may be necessary.
71 fn default_from(value: &T) -> Self;
72}
73
74impl<Pos, Vel, For, const N: usize> DefaultFrom<For> for AuxStorageMechanics<Pos, Vel, For, N>
75where
76 For: Clone,
77{
78 fn default_from(value: &For) -> Self {
79 let force: For = value.clone().into();
80 Self {
81 positions: RingBuffer::default(),
82 velocities: RingBuffer::default(),
83 current_force: force.clone(),
84 zero_force: force.clone(),
85 }
86 }
87}
88
89impl<Pos, Vel, For, const N: usize> UpdateMechanics<Pos, Vel, For, N>
90 for AuxStorageMechanics<Pos, Vel, For, N>
91where
92 For: Clone + core::ops::AddAssign<For>,
93{
94 #[inline]
95 fn previous_positions<'a>(&'a self) -> RingBufferIterRef<'a, Pos, N> {
96 self.positions.iter()
97 }
98
99 #[inline]
100 fn previous_velocities<'a>(&'a self) -> RingBufferIterRef<'a, Vel, N> {
101 self.velocities.iter()
102 }
103
104 #[inline]
105 fn n_previous_values(&self) -> usize {
106 self.positions.get_size()
107 }
108
109 #[inline]
110 fn set_last_position(&mut self, pos: Pos) {
111 self.positions.push(pos);
112 }
113
114 #[inline]
115 fn set_last_velocity(&mut self, vel: Vel) {
116 self.velocities.push(vel);
117 }
118
119 #[inline]
120 fn add_force(&mut self, force: For) {
121 self.current_force += force;
122 }
123
124 #[inline]
125 fn get_current_force_and_reset(&mut self) -> For {
126 let f = self.current_force.clone();
127 self.current_force = self.zero_force.clone();
128 f
129 }
130}
131
132// ----------------------------------- UPDATE-CYCLE ----------------------------------
133/// Trait which describes how to store intermediate
134/// information on the cell cycle.
135pub trait UpdateCycle {
136 /// Set all cycle events. This function is currently the
137 /// only way to change the contents of the stored events.
138 fn set_cycle_events(&mut self, events: Vec<CycleEvent>);
139
140 /// Get all cycle events currently stored.
141 fn get_cycle_events(&self) -> &Vec<CycleEvent>;
142
143 /// Drain all cycle events
144 fn drain_cycle_events<'a>(&'a mut self) -> std::vec::Drain<'a, CycleEvent>;
145
146 /// Add another cycle event to the storage.
147 fn add_cycle_event(&mut self, event: CycleEvent);
148}
149
150/// Stores intermediate information about the cell cycle.
151///
152/// This struct is used in the [build_aux_storage](crate::backend::chili::build_aux_storage) macro.
153/// It can in principle also be re-used on its own since it implements the [UpdateCycle] trait.
154///
155/// ```
156/// use cellular_raza_core::backend::chili::{AuxStorageCycle,UpdateCycle};
157/// use cellular_raza_concepts::CycleEvent;
158///
159/// // Construct a new empty AuxStorageCycle
160/// let mut aux_storage_cycle = AuxStorageCycle::default();
161///
162/// // Add one element
163/// aux_storage_cycle.add_cycle_event(CycleEvent::Division);
164/// assert_eq!(aux_storage_cycle.get_cycle_events().len(), 1);
165///
166/// // Drain all elements currently present
167/// let events = aux_storage_cycle.drain_cycle_events();
168/// assert_eq!(events.len(), 1);
169/// ```
170#[derive(Clone, Default, Deserialize, Serialize)]
171pub struct AuxStorageCycle {
172 cycle_events: Vec<CycleEvent>,
173}
174
175impl UpdateCycle for AuxStorageCycle {
176 #[inline]
177 fn set_cycle_events(&mut self, events: Vec<CycleEvent>) {
178 self.cycle_events = events;
179 }
180
181 #[inline]
182 fn get_cycle_events(&self) -> &Vec<CycleEvent> {
183 &self.cycle_events
184 }
185
186 #[inline]
187 fn drain_cycle_events<'a>(&'a mut self) -> std::vec::Drain<'a, CycleEvent> {
188 self.cycle_events.drain(..)
189 }
190
191 #[inline]
192 fn add_cycle_event(&mut self, event: CycleEvent) {
193 self.cycle_events.push(event);
194 }
195}
196
197// --------------------------------- UPDATE-REACTIONS --------------------------------
198/// Interface to store intermediate information about cellular reactions.
199pub trait UpdateReactions<Ri> {
200 /// Set the value of intracellular concentrations
201 fn set_conc(&mut self, conc: Ri);
202 /// Obtain the current value of intracellular concentrations
203 fn get_conc(&self) -> Ri;
204 /// Add concentrations to the current value
205 fn incr_conc(&mut self, incr: Ri);
206}
207
208/// Helper storage for values regarding intracellular concentrations for the
209/// [Reactions](cellular_raza_concepts::Reactions) trait.
210#[derive(Clone, Default, Deserialize, Serialize)]
211pub struct AuxStorageReactions<Ri> {
212 concentration: Ri,
213}
214
215impl<Ri> DefaultFrom<Ri> for AuxStorageReactions<Ri>
216where
217 Ri: Clone,
218{
219 fn default_from(value: &Ri) -> Self {
220 AuxStorageReactions {
221 concentration: value.clone(),
222 }
223 }
224}
225
226impl<R> UpdateReactions<R> for AuxStorageReactions<R>
227where
228 R: Clone + core::ops::Add<R, Output = R>,
229{
230 #[inline]
231 fn get_conc(&self) -> R {
232 self.concentration.clone()
233 }
234
235 #[inline]
236 fn incr_conc(&mut self, incr: R) {
237 self.concentration = self.concentration.clone() + incr;
238 }
239
240 #[inline]
241 fn set_conc(&mut self, conc: R) {
242 self.concentration = conc;
243 }
244}
245
246/// Used to update properties of the cell related to the
247/// [ReactionsContact](cellular_raza_concepts::ReactionsContact) trait.
248pub trait UpdateReactionsContact<Ri, const N: usize> {
249 /// Sets the current contact reactions increment
250 fn set_current_increment(&mut self, new_increment: Ri);
251 /// Adds to the current increment
252 fn incr_current_increment(&mut self, increment: Ri);
253 /// Obtains the current increment
254 fn get_current_increment(&self) -> Ri;
255 /// Obtain previous increments used for adams_bashforth integrators
256 fn previous_increments<'a>(&'a self) -> RingBufferIterRef<'a, Ri, N>;
257 /// Set the last increment in the ring buffer
258 fn set_last_increment(&mut self, increment: Ri);
259 /// Get the number of previous values to match against [circ_buffer::RingBufferIterRef]
260 fn n_previous_values(&self) -> usize;
261}
262
263/// Implementor of the [UpdateReactionsContact] trait.
264#[derive(Clone, Default, Deserialize, Serialize)]
265pub struct AuxStorageReactionsContact<Ri, const N: usize> {
266 current_increment: Ri,
267 increments: RingBuffer<Ri, N>,
268}
269
270impl<Ri, const N: usize> DefaultFrom<Ri> for AuxStorageReactionsContact<Ri, N>
271where
272 Ri: Clone,
273{
274 fn default_from(value: &Ri) -> Self {
275 AuxStorageReactionsContact {
276 current_increment: value.clone(),
277 increments: Default::default(),
278 }
279 }
280}
281
282impl<Ri, const N: usize> UpdateReactionsContact<Ri, N> for AuxStorageReactionsContact<Ri, N>
283where
284 Ri: Clone + core::ops::Add<Ri, Output = Ri>,
285{
286 #[inline]
287 fn get_current_increment(&self) -> Ri {
288 self.current_increment.clone()
289 }
290
291 #[inline]
292 fn incr_current_increment(&mut self, increment: Ri) {
293 self.current_increment = self.current_increment.clone() + increment;
294 }
295
296 #[inline]
297 fn set_current_increment(&mut self, new_increment: Ri) {
298 self.current_increment = new_increment;
299 }
300
301 #[inline]
302 fn previous_increments<'a>(&'a self) -> RingBufferIterRef<'a, Ri, N> {
303 self.increments.iter()
304 }
305
306 #[inline]
307 fn set_last_increment(&mut self, increment: Ri) {
308 self.increments.push(increment)
309 }
310
311 #[inline]
312 fn n_previous_values(&self) -> usize {
313 self.increments.get_size()
314 }
315}
316
317// -------------------------------- UPDATE-Neighbor-Sensing -------------------------------
318/// Interface to store intermediate information about neighbors.
319pub trait UpdateNeighborSensing<Acc> {
320 /// Obtains the internally held accumulator for the [cellular_raza_concepts::NeighborSensing]
321 /// trait
322 fn get_accumulator(&mut self) -> &mut Acc;
323}
324
325/// Helper storage to update information about neighbors
326#[derive(Clone, Default, Deserialize, Serialize)]
327pub struct AuxStorageNeighborSensing<Acc> {
328 accumulator: Acc,
329}
330
331impl<Acc> UpdateNeighborSensing<Acc> for AuxStorageNeighborSensing<Acc> {
332 fn get_accumulator(&mut self) -> &mut Acc {
333 &mut self.accumulator
334 }
335}
336
337#[allow(unused)]
338#[doc(hidden)]
339mod test_derive_aux_storage_compile {
340 /// ```
341 /// use cellular_raza_core::backend::chili::AuxStorage;
342 /// use cellular_raza_core::backend::chili::*;
343 ///
344 /// #[derive(AuxStorage)]
345 /// struct TestStructMechanics<Pos, Vel, For, const N: usize> {
346 /// #[UpdateMechanics(Pos, Vel, For, N)]
347 /// aux_mechanics: AuxStorageMechanics<Pos, Vel, For, N>,
348 /// }
349 /// ```
350 fn mechanics_default() {}
351
352 /// ```
353 /// use cellular_raza_core::backend::chili::AuxStorage;
354 /// use cellular_raza_core::backend::chili::*;
355 ///
356 /// #[derive(AuxStorage)]
357 /// pub struct TestStructMechanics<Pos, Vel, For, const N: usize> {
358 /// #[UpdateMechanics(Pos, Vel, For, N)]
359 /// aux_mechanics: AuxStorageMechanics<Pos, Vel, For, N>,
360 /// }
361 /// ```
362 fn mechanics_visibility_1() {}
363
364 /// ```
365 /// use cellular_raza_core::backend::chili::AuxStorage;
366 /// use cellular_raza_core::backend::chili::*;
367 ///
368 /// #[derive(AuxStorage)]
369 /// pub(crate) struct TestStructMechanics<Pos, Vel, For, const N: usize> {
370 /// #[UpdateMechanics(Pos, Vel, For, N)]
371 /// aux_mechanics: AuxStorageMechanics<Pos, Vel, For, N>,
372 /// }
373 /// ```
374 fn mechanics_visibility_2() {}
375
376 /// ```
377 /// mod some_module {
378 /// use cellular_raza_core::backend::chili::AuxStorage;
379 /// use cellular_raza_core::backend::chili::*;
380 ///
381 /// #[derive(AuxStorage)]
382 /// pub(super) struct TestStructMechanics<Pos, Vel, For, const N: usize> {
383 /// #[UpdateMechanics(Pos, Vel, For, N)]
384 /// aux_mechanics: AuxStorageMechanics<Pos, Vel, For, N>,
385 /// }
386 /// }
387 /// fn use_impl<T, Pos, Vel, For, const N: usize>(
388 /// mut aux_storage: T
389 /// ) -> For
390 /// where
391 /// T: cellular_raza_core::backend::chili::UpdateMechanics<Pos, Vel, For, N>,
392 /// {
393 /// aux_storage.get_current_force_and_reset()
394 /// }
395 /// ```
396 fn mechanics_visibility_3() {}
397
398 /// ```
399 /// use cellular_raza_core::backend::chili::AuxStorage;
400 /// use cellular_raza_core::backend::chili::*;
401 ///
402 /// #[derive(AuxStorage)]
403 /// struct TestStructMechanics<Pos, Vel, For, T, const N: usize> {
404 /// #[UpdateMechanics(Pos, Vel, For, N)]
405 /// aux_mechanics: AuxStorageMechanics<Pos, Vel, For, N>,
406 /// other: T,
407 /// }
408 /// ```
409 fn mechanics_more_struct_generics() {}
410
411 /// ```
412 /// use cellular_raza_core::backend::chili::AuxStorage;
413 /// use cellular_raza_core::backend::chili::*;
414 ///
415 /// #[derive(AuxStorage)]
416 /// struct TestStructMechanics<Pos, Vel, For, const N: usize, const M: usize> {
417 /// #[UpdateMechanics(Pos, Vel, For, N)]
418 /// aux_mechanics: AuxStorageMechanics<Pos, Vel, For, N>,
419 /// count: [i64; M],
420 /// }
421 /// ```
422 fn mechanics_more_struct_const_generics() {}
423
424 /// ```
425 /// use cellular_raza_core::backend::chili::AuxStorage;
426 /// use cellular_raza_core::backend::chili::*;
427 ///
428 /// #[derive(AuxStorage)]
429 /// struct TestStructMechanics<Pos, Vel, For, const N: usize>
430 /// where
431 /// Pos: Clone,
432 /// {
433 /// #[UpdateMechanics(Pos, Vel, For, N)]
434 /// aux_mechanics: AuxStorageMechanics<Pos, Vel, For, N>,
435 /// }
436 /// ```
437 fn mechanics_where_clause() {}
438
439 /// ```
440 /// use cellular_raza_core::backend::chili::AuxStorage;
441 /// use cellular_raza_core::backend::chili::*;
442 ///
443 /// #[derive(AuxStorage)]
444 /// struct TestStructMechanics<Pos, Vel, For, const N: usize> {
445 /// #[UpdateMechanics(Pos, Vel, For, N)]
446 /// #[cfg(not(test))]
447 /// aux_mechanics: AuxStorageMechanics<Pos, Vel, For, N>,
448 /// }
449 /// ```
450 fn mechanics_other_attributes() {}
451
452 /// ```
453 /// use cellular_raza_core::backend::chili::AuxStorage;
454 /// use cellular_raza_core::backend::chili::*;
455 /// use cellular_raza_concepts::CycleEvent;
456 ///
457 /// #[derive(AuxStorage)]
458 /// struct TestStructCycle {
459 /// #[UpdateCycle]
460 /// aux_cycle: AuxStorageCycle,
461 /// }
462 /// ```
463 fn cycle_default() {}
464
465 /// ```
466 /// use cellular_raza_core::backend::chili::AuxStorage;
467 /// use cellular_raza_core::backend::chili::*;
468 /// use cellular_raza_concepts::CycleEvent;
469 ///
470 /// #[derive(AuxStorage)]
471 /// pub struct TestStructCycle {
472 /// #[UpdateCycle]
473 /// aux_cycle: AuxStorageCycle,
474 /// }
475 /// ```
476 fn cycle_visibility_1() {}
477
478 /// ```
479 /// use cellular_raza_core::backend::chili::AuxStorage;
480 /// use cellular_raza_core::backend::chili::*;
481 /// use cellular_raza_concepts::CycleEvent;
482 ///
483 /// #[derive(AuxStorage)]
484 /// pub(crate) struct TestStructCycle {
485 /// #[UpdateCycle]
486 /// aux_cycle: AuxStorageCycle,
487 /// }
488 /// ```
489 fn cycle_visibility_2() {}
490
491 /// ```
492 /// use cellular_raza_core::backend::chili::AuxStorage;
493 /// use cellular_raza_core::backend::chili::*;
494 /// use cellular_raza_concepts::CycleEvent;
495 ///
496 /// #[derive(AuxStorage)]
497 /// pub struct TestStructCycle<T> {
498 /// #[UpdateCycle]
499 /// aux_cycle: AuxStorageCycle,
500 /// _generic: T,
501 /// }
502 /// ```
503 fn cycle_generic_param() {}
504
505 /// ```
506 /// use cellular_raza_core::backend::chili::AuxStorage;
507 /// use cellular_raza_core::backend::chili::*;
508 /// use cellular_raza_concepts::CycleEvent;
509 ///
510 /// #[derive(AuxStorage)]
511 /// pub struct TestStructCycle<const N: usize> {
512 /// #[UpdateCycle]
513 /// aux_cycle: AuxStorageCycle,
514 /// _generic: [f64; N],
515 /// }
516 /// ```
517 fn cycle_const_generic_param() {}
518
519 /// ```
520 /// use cellular_raza_core::backend::chili::AuxStorage;
521 /// use cellular_raza_core::backend::chili::*;
522 /// use cellular_raza_concepts::CycleEvent;
523 ///
524 /// #[derive(AuxStorage)]
525 /// pub struct TestStructCycle<T>
526 /// where
527 /// T: Clone,
528 /// {
529 /// #[UpdateCycle]
530 /// aux_cycle: AuxStorageCycle,
531 /// _generic: T,
532 /// }
533 /// ```
534 fn cycle_where_clause() {}
535
536 /// ```
537 /// use cellular_raza_core::backend::chili::AuxStorage;
538 /// use cellular_raza_core::backend::chili::*;
539 /// use cellular_raza_concepts::CycleEvent;
540 ///
541 /// #[derive(AuxStorage)]
542 /// struct TestStructCycle {
543 /// #[UpdateCycle]
544 /// #[cfg(not(test))]
545 /// aux_cycle: AuxStorageCycle,
546 /// }
547 /// ```
548 fn cycle_other_attributes() {}
549
550 /// ```
551 /// use cellular_raza_core::backend::chili::AuxStorage;
552 /// use cellular_raza_core::backend::chili::*;
553 ///
554 /// #[derive(AuxStorage)]
555 /// struct TestStructReactions<R> {
556 /// #[UpdateReactions(R)]
557 /// aux_cycle: AuxStorageReactions<R>,
558 /// }
559 /// ```
560 fn reactions_default() {}
561
562 /// ```
563 /// use cellular_raza_core::backend::chili::AuxStorage;
564 /// use cellular_raza_core::backend::chili::*;
565 ///
566 /// #[derive(AuxStorage)]
567 /// pub struct TestStructReactions<R> {
568 /// #[UpdateReactions(R)]
569 /// aux_cycle: AuxStorageReactions<R>,
570 /// }
571 /// ```
572 fn reactions_visibility_1() {}
573
574 /// ```
575 /// use cellular_raza_core::backend::chili::AuxStorage;
576 /// use cellular_raza_core::backend::chili::*;
577 ///
578 /// #[derive(AuxStorage)]
579 /// pub(crate) struct TestStructReactions<R> {
580 /// #[UpdateReactions(R)]
581 /// aux_cycle: AuxStorageReactions<R>,
582 /// }
583 /// ```
584 fn reactions_visibility_2() {}
585
586 /// ```
587 /// use cellular_raza_core::backend::chili::AuxStorage;
588 /// use cellular_raza_core::backend::chili::*;
589 ///
590 /// #[derive(AuxStorage)]
591 /// struct TestStructReactions<T, R> {
592 /// #[UpdateReactions(R)]
593 /// aux_cycle: AuxStorageReactions<R>,
594 /// generic: T,
595 /// }
596 /// ```
597 fn reactions_generic_param() {}
598
599 /// ```
600 /// use cellular_raza_core::backend::chili::AuxStorage;
601 /// use cellular_raza_core::backend::chili::*;
602 ///
603 /// #[derive(AuxStorage)]
604 /// struct TestStructReactions<R, const N: usize> {
605 /// #[UpdateReactions(R)]
606 /// aux_cycle: AuxStorageReactions<R>,
607 /// generic_array: [usize; N],
608 /// }
609 /// ```
610 fn reactions_const_generic_param() {}
611
612 /// ```
613 /// use cellular_raza_core::backend::chili::AuxStorage;
614 /// use cellular_raza_core::backend::chili::*;
615 ///
616 /// #[derive(AuxStorage)]
617 /// struct TestStructReactions<T, R>
618 /// where
619 /// T: Clone,
620 /// {
621 /// #[UpdateReactions(R)]
622 /// aux_cycle: AuxStorageReactions<R>,
623 /// generic: T,
624 /// }
625 /// ```
626 fn reactions_where_clause() {}
627
628 /// ```
629 /// use cellular_raza_core::backend::chili::AuxStorage;
630 /// use cellular_raza_core::backend::chili::*;
631 ///
632 /// #[derive(AuxStorage)]
633 /// struct TestStructReactions<R> {
634 /// #[cfg(not(test))]
635 /// #[UpdateReactions(R)]
636 /// aux_cycle: AuxStorageReactions<R>,
637 /// }
638 /// ```
639 fn reactions_other_attributes() {}
640
641 /// ```
642 /// use cellular_raza_core::backend::chili::AuxStorage;
643 /// use cellular_raza_core::backend::chili::*;
644 ///
645 /// #[derive(AuxStorage)]
646 /// struct TestStructInteraction<A> {
647 /// #[UpdateNeighborSensing(A)]
648 /// aux_interaction: AuxStorageNeighborSensing<A>,
649 /// }
650 /// ```
651 fn neighbor_sensing_default() {}
652
653 /// ```
654 /// use cellular_raza_core::backend::chili::AuxStorage;
655 /// use cellular_raza_core::backend::chili::*;
656 ///
657 /// #[derive(AuxStorage)]
658 /// pub struct TestStructInteraction<A> {
659 /// #[UpdateNeighborSensing(A)]
660 /// aux_interaction: AuxStorageNeighborSensing<A>,
661 /// }
662 /// ```
663 fn neighbor_sensing_visibility_1() {}
664
665 /// ```
666 /// use cellular_raza_core::backend::chili::AuxStorage;
667 /// use cellular_raza_core::backend::chili::*;
668 ///
669 /// #[derive(AuxStorage)]
670 /// pub(crate) struct TestStructInteraction<A> {
671 /// #[UpdateNeighborSensing(A)]
672 /// aux_interaction: AuxStorageNeighborSensing<A>,
673 /// }
674 /// ```
675 fn neighbor_sensing_visibility_2() {}
676
677 /// ```
678 /// use cellular_raza_core::backend::chili::AuxStorage;
679 /// use cellular_raza_core::backend::chili::*;
680 ///
681 /// #[derive(AuxStorage)]
682 /// struct TestStructInteraction<A, T> {
683 /// #[UpdateNeighborSensing(A)]
684 /// aux_interaction: AuxStorageNeighborSensing<A>,
685 /// generic: T,
686 /// }
687 /// ```
688 fn neighbor_sensing_generic_param() {}
689
690 /// ```
691 /// use cellular_raza_core::backend::chili::AuxStorage;
692 /// use cellular_raza_core::backend::chili::*;
693 ///
694 /// #[derive(AuxStorage)]
695 /// struct TestStructInteraction<A, const N: usize> {
696 /// #[UpdateNeighborSensing(A)]
697 /// aux_interaction: AuxStorageNeighborSensing<A>,
698 /// generic: [f64; N],
699 /// }
700 /// ```
701 fn neighbor_sensing_const_generic_param() {}
702
703 /// ```
704 /// use cellular_raza_core::backend::chili::AuxStorage;
705 /// use cellular_raza_core::backend::chili::*;
706 ///
707 /// #[derive(AuxStorage)]
708 /// struct TestStructInteraction<A, T>
709 /// where
710 /// T: Clone,
711 /// {
712 /// #[UpdateNeighborSensing(A)]
713 /// aux_interaction: AuxStorageNeighborSensing<A>,
714 /// generic: T,
715 /// }
716 /// ```
717 fn neighbor_sensing_where_clause() {}
718
719 /// ```
720 /// use cellular_raza_core::backend::chili::AuxStorage;
721 /// use cellular_raza_core::backend::chili::*;
722 ///
723 /// #[derive(AuxStorage)]
724 /// struct TestStructInteraction<A> {
725 /// #[UpdateNeighborSensing(A)]
726 /// #[cfg(not(test))]
727 /// aux_interaction: AuxStorageNeighborSensing<A>,
728 /// }
729 /// ```
730 fn neighbor_sensing_other_attributes() {}
731}
732
733#[cfg(test)]
734mod test_derive_aux_storage {
735 use super::*;
736 use cellular_raza_core_proc_macro::AuxStorage;
737
738 #[derive(AuxStorage)]
739 struct TestStructDouble<Pos, Vel, For, const N: usize> {
740 #[UpdateCycle]
741 aux_cycle: AuxStorageCycle,
742 #[UpdateMechanics(Pos, Vel, For, N)]
743 aux_mechanics: AuxStorageMechanics<Pos, Vel, For, N>,
744 }
745
746 #[derive(AuxStorage)]
747 struct TestStructCycle {
748 #[UpdateCycle]
749 aux_cycle: AuxStorageCycle,
750 }
751
752 #[derive(AuxStorage)]
753 struct TestStructMechanics<Pos, Vel, For, const N: usize> {
754 #[UpdateMechanics(Pos, Vel, For, N)]
755 aux_mechanics: AuxStorageMechanics<Pos, Vel, For, N>,
756 }
757
758 fn add_get_events<A>(aux_storage: &mut A)
759 where
760 A: UpdateCycle,
761 {
762 aux_storage.add_cycle_event(CycleEvent::Division);
763 let events = aux_storage.get_cycle_events();
764 assert_eq!(events, &vec![CycleEvent::Division]);
765 }
766
767 fn set_get_events<A>(aux_storage: &mut A)
768 where
769 A: UpdateCycle,
770 {
771 let initial_events = vec![
772 CycleEvent::Division,
773 CycleEvent::Division,
774 CycleEvent::PhasedDeath,
775 ];
776 aux_storage.set_cycle_events(initial_events.clone());
777 let events = aux_storage.get_cycle_events();
778 assert_eq!(events.len(), 3);
779 assert_eq!(events, &initial_events);
780 }
781
782 #[test]
783 fn cycle_add_get_events() {
784 let mut aux_storage = TestStructCycle {
785 aux_cycle: AuxStorageCycle::default(),
786 };
787 add_get_events(&mut aux_storage);
788 }
789
790 #[test]
791 fn cycle_set_get_events() {
792 let mut aux_storage = TestStructCycle {
793 aux_cycle: AuxStorageCycle::default(),
794 };
795 set_get_events(&mut aux_storage);
796 }
797
798 #[test]
799 fn mechanics() {
800 let mut aux_storage = TestStructMechanics::<_, _, _, 4> {
801 aux_mechanics: AuxStorageMechanics::default(),
802 };
803 aux_storage.set_last_position(3_f64);
804 aux_storage.set_last_velocity(5_f32);
805 aux_storage.add_force(1_f32);
806 }
807
808 #[test]
809 fn cycle_mechanics_add_get_events() {
810 let mut aux_storage = TestStructDouble::<_, _, _, 4> {
811 aux_cycle: AuxStorageCycle::default(),
812 aux_mechanics: AuxStorageMechanics::default(),
813 };
814 aux_storage.set_last_position(3_f64);
815 aux_storage.set_last_velocity(5_f32);
816 aux_storage.add_force(-5_f32);
817 add_get_events(&mut aux_storage);
818 }
819
820 #[test]
821 fn cycle_mechanics_set_get_events() {
822 let mut aux_storage = TestStructDouble::<_, _, _, 4> {
823 aux_cycle: AuxStorageCycle::default(),
824 aux_mechanics: AuxStorageMechanics::default(),
825 };
826 aux_storage.set_last_position(3_f64);
827 aux_storage.set_last_velocity(5_f32);
828 aux_storage.add_force(111_i64);
829 set_get_events(&mut aux_storage);
830 }
831}
832
833#[allow(unused)]
834#[doc(hidden)]
835mod test_build_aux_storage {
836 use crate::backend::chili::proc_macro::aux_storage_constructor;
837 macro_rules! construct (
838 (name:$test_name:ident,
839 aspects:[$($asp:ident),*]) => {
840 /// ```
841 /// use serde::{Deserialize, Serialize};
842 /// use cellular_raza_core::backend::chili::*;
843 /// build_aux_storage!(
844 #[doc = concat!("aspects: [", $(stringify!($asp,),)* "],")]
845 /// aux_storage_name: __cr_AuxStorage,
846 /// core_path: cellular_raza_core
847 /// );
848 // #[doc = concat!("let mut aux_storage = __cr_AuxStorage {", init!($($asp),*) "};")]
849 // #[doc = init!{@start $($asp),* end}]
850 #[doc = concat!(
851 "let mut aux_storage = (",
852 stringify!(aux_storage_constructor!(
853 aux_storage_name: __cr_AuxStorage,
854 core_path: cellular_raza_core,
855 aspects: [$($asp),*],
856 )),
857 ")(());",
858 )]
859 /// macro_rules! test_aspect (
860 /// (Mechanics) => {
861 /// {
862 /// use cellular_raza_core::backend::chili::UpdateMechanics;
863 /// aux_storage.set_last_position(1_f32);
864 /// aux_storage.set_last_position(3_f32);
865 /// let last_positions = aux_storage
866 /// .previous_positions()
867 /// .map(|f| *f)
868 /// .collect::<Vec<f32>>();
869 /// assert_eq!(last_positions, vec![1_f32, 3_f32]);
870 /// aux_storage.set_last_velocity(10_f32);
871 /// let last_velocities: cellular_raza_core::backend::chili::RingBufferIterRef<_, 4>
872 /// = aux_storage.previous_velocities();
873 /// let last_velocities = last_velocities.map(|f| *f).collect::<Vec<f32>>();
874 /// assert_eq!(last_velocities, vec![10_f32]);
875 /// aux_storage.add_force(22_f32);
876 /// assert_eq!(aux_storage.get_current_force_and_reset(), 22_f32);
877 /// }
878 /// };
879 /// (Interaction) => {};
880 /// (NeighborSensing) => {
881 /// {
882 /// use cellular_raza_core::backend::chili::UpdateNeighborSensing;
883 /// let mut acc: &mut Vec<usize> = aux_storage.get_accumulator();
884 /// acc.push(1);
885 /// assert_eq!(*aux_storage.get_accumulator(), vec![1]);
886 /// }
887 /// };
888 /// (Cycle) => {
889 /// {
890 /// use cellular_raza_core::backend::chili::UpdateCycle;
891 /// use cellular_raza_concepts::CycleEvent;
892 /// aux_storage.add_cycle_event(CycleEvent::Division);
893 /// assert_eq!(aux_storage.get_cycle_events(), &vec![CycleEvent::Division]);
894 /// }
895 /// };
896 /// (Reactions) => {
897 /// {
898 /// use cellular_raza_core::backend::chili::UpdateReactions;
899 /// aux_storage.set_conc(0_f32);
900 /// aux_storage.incr_conc(1.44_f32);
901 /// assert_eq!(aux_storage.get_conc(), 0_f32 + 1.44_f32);
902 /// }
903 /// };
904 /// (ReactionsContact) => {
905 /// {
906 /// use cellular_raza_core::backend::chili::UpdateReactionsContact;
907 /// aux_storage.set_last_increment(0f32);
908 /// aux_storage.set_last_increment(3f32);
909 /// assert_eq!(UpdateReactionsContact::n_previous_values(&aux_storage), 2);
910 /// let last_increments =
911 /// UpdateReactionsContact::<f32, 10>::previous_increments(
912 /// &aux_storage
913 /// );
914 /// let last_increments = last_increments.map(|f| *f).collect::<Vec<_>>();
915 /// assert_eq!(last_increments, vec![0.0, 3.0]);
916 /// }
917 /// };
918 /// );
919 #[doc = concat!($(
920 concat!("test_aspect!(", stringify!($asp), ");")
921 ,)*)]
922 /// ```
923 fn $test_name() {}
924 }
925 );
926
927 cellular_raza_core_proc_macro::run_test_for_aspects!(
928 test: construct,
929 aspects: [Mechanics, Interaction, NeighborSensing, Cycle, Reactions, ReactionsContact]
930 );
931}