nphysics2d/force_generator/
force_generator.rs

1#![allow(missing_docs)] // for downcast.
2
3use downcast_rs::Downcast;
4use generational_arena::Arena;
5use na::RealField;
6
7use crate::object::{BodyHandle, BodySet, DefaultBodyHandle};
8use crate::solver::IntegrationParameters;
9
10/// Default force generator set based on an arena with generational indices.
11pub type DefaultForceGeneratorSet<N: RealField + Copy, Handle: BodyHandle = DefaultBodyHandle> =
12    Arena<Box<dyn ForceGenerator<N, Handle>>>;
13
14/// Trait implemented by sets of force generators.
15///
16/// A set of bodies maps a force generator handle to a force generator instance.
17pub trait ForceGeneratorSet<N: RealField + Copy, Handle: BodyHandle> {
18    /// Type of a force generator stored in this set.
19    type ForceGenerator: ?Sized + ForceGenerator<N, Handle>;
20    /// Type of a force generator handle identifying a force generator in this set.
21    type Handle: Copy;
22
23    /// Gets a reference to the force generator identified by `handle`.
24    fn get(&self, handle: Self::Handle) -> Option<&Self::ForceGenerator>;
25    /// Gets a mutable reference to the force generator identified by `handle`.
26    fn get_mut(&mut self, handle: Self::Handle) -> Option<&mut Self::ForceGenerator>;
27
28    /// Check if this set contains a force generator identified by `handle`.
29    fn contains(&self, handle: Self::Handle) -> bool;
30
31    /// Iterate through all the force generators on this set, applying the closure `f` on them.
32    fn foreach(&self, f: impl FnMut(Self::Handle, &Self::ForceGenerator));
33    /// Mutable iterates through all the force generators on this set, applying the closure `f` on them.
34    fn foreach_mut(&mut self, f: impl FnMut(Self::Handle, &mut Self::ForceGenerator));
35}
36
37impl<N: RealField + Copy, Handle: BodyHandle> ForceGeneratorSet<N, Handle>
38    for DefaultForceGeneratorSet<N, Handle>
39{
40    type ForceGenerator = dyn ForceGenerator<N, Handle>;
41    type Handle = DefaultForceGeneratorHandle;
42
43    fn get(&self, handle: Self::Handle) -> Option<&Self::ForceGenerator> {
44        self.get(handle).map(|c| &**c)
45    }
46
47    fn get_mut(&mut self, handle: Self::Handle) -> Option<&mut Self::ForceGenerator> {
48        self.get_mut(handle).map(|c| &mut **c)
49    }
50
51    fn contains(&self, handle: Self::Handle) -> bool {
52        self.contains(handle)
53    }
54
55    fn foreach(&self, mut f: impl FnMut(Self::Handle, &Self::ForceGenerator)) {
56        for (h, b) in self.iter() {
57            f(h, &**b)
58        }
59    }
60
61    fn foreach_mut(&mut self, mut f: impl FnMut(Self::Handle, &mut Self::ForceGenerator)) {
62        for (h, b) in self.iter_mut() {
63            f(h, &mut **b)
64        }
65    }
66}
67
68/// The handle of a force generator.
69pub type DefaultForceGeneratorHandle = generational_arena::Index;
70
71/// A persistent force generator.
72///
73/// A force generator applies a force to one or several bodies at each step of the simulation.
74pub trait ForceGenerator<N: RealField + Copy, Handle: BodyHandle>: Downcast + Send + Sync {
75    /// Apply forces to some bodies.
76    fn apply(
77        &mut self,
78        parameters: &IntegrationParameters<N>,
79        bodies: &mut dyn BodySet<N, Handle = Handle>,
80    );
81}
82
83impl_downcast!(ForceGenerator<N, Handle> where N: RealField + Copy, Handle: BodyHandle);