1use std::marker::PhantomData;
2
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6pub trait ParticleSystem {
8 type ParticleType: Particle;
10
11 type EmitterType: ParticleEmitter<ParticleType = Self::ParticleType>;
13
14 fn iter_particles(&self) -> impl Iterator<Item = &Self::ParticleType>;
16
17 fn iter_particles_mut(&mut self) -> impl Iterator<Item = &mut Self::ParticleType>;
19
20 fn iter_emitters(&self) -> impl Iterator<Item = &Self::EmitterType>;
22
23 fn iter_emitters_mut(&mut self) -> impl Iterator<Item = &mut Self::EmitterType>;
25
26 fn add_particle(&mut self, particle: Self::ParticleType);
28
29 fn add_emitter(&mut self, emitter: Self::EmitterType);
31
32 fn update_particles(&mut self, dt: f64) {
34 for particle in self.iter_particles_mut() {
35 particle.update(dt);
36 }
37 }
38
39 fn update_emitters(&mut self, dt: f64) -> Vec<Self::ParticleType> {
41 self.iter_emitters_mut()
42 .flat_map(|emitter| emitter.update(dt))
43 .collect()
44 }
45
46 fn clean_particles(&mut self);
48
49 fn clean_emitters(&mut self);
51
52 fn update(&mut self, dt: f64) {
59 let new_particles = self.update_emitters(dt);
60
61 for new_particle in new_particles {
62 self.add_particle(new_particle);
63 }
64
65 self.update_particles(dt);
66
67 self.clean_particles();
68 self.clean_emitters();
69 }
70}
71
72#[derive(Debug, Clone)]
76#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
77pub struct VecParticleSystem<P, E> {
78 particles: Vec<P>,
79 emitters: Vec<E>,
80}
81
82impl<P, E> Default for VecParticleSystem<P, E>
83{
84 fn default() -> Self {
85 Self {
86 particles: Vec::default(),
87 emitters: Vec::default(),
88 }
89 }
90}
91
92impl<P: Particle, E: ParticleEmitter<ParticleType = P>> ParticleSystem for VecParticleSystem<P, E> {
93 type ParticleType = P;
95
96 type EmitterType = E;
98
99 fn iter_particles(&self) -> impl Iterator<Item = &Self::ParticleType> {
100 self.particles.iter()
101 }
102
103 fn iter_particles_mut(&mut self) -> impl Iterator<Item = &mut Self::ParticleType> {
104 self.particles.iter_mut()
105 }
106
107 fn iter_emitters(&self) -> impl Iterator<Item = &Self::EmitterType> {
108 self.emitters.iter()
109 }
110
111 fn iter_emitters_mut(&mut self) -> impl Iterator<Item = &mut Self::EmitterType> {
112 self.emitters.iter_mut()
113 }
114
115 fn add_particle(&mut self, particle: Self::ParticleType) {
116 self.particles.push(particle);
117 }
118
119 fn add_emitter(&mut self, emitter: Self::EmitterType) {
120 self.emitters.push(emitter);
121 }
122
123 fn clean_particles(&mut self) {
124 self.particles.retain(|particle| particle.is_alive());
125 }
126
127 fn clean_emitters(&mut self) {
128 self.emitters.retain(|emitter| emitter.is_alive());
129 }
130}
131
132pub type BaseParticleSystem<C> = VecParticleSystem<
133 Box<dyn Particle<Coordinate = C>>,
134 Box<dyn ParticleEmitter<ParticleType = Box<dyn Particle<Coordinate = C>>>>,
135>;
136
137pub trait ParticleEmitter {
139 type ParticleType: Particle;
141
142 fn update(&mut self, dt: f64) -> Vec<Self::ParticleType>;
144
145 fn is_alive(&self) -> bool;
147}
148
149impl<E: ParticleEmitter + ?Sized> ParticleEmitter for Box<E> {
150 type ParticleType = E::ParticleType;
151
152 fn update(&mut self, dt: f64) -> Vec<Self::ParticleType> {
153 E::update(self, dt)
154 }
155
156 fn is_alive(&self) -> bool {
157 E::is_alive(self)
158 }
159}
160
161#[derive(Debug, Clone, Copy)]
164#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
165pub struct NullParticleEmitter<P> {
166 phantom: PhantomData<P>,
167}
168
169impl<P: Particle> ParticleEmitter for NullParticleEmitter<P> {
170 type ParticleType = P;
171
172 fn update(&mut self, _dt: f64) -> Vec<Self::ParticleType> {
173 vec![]
174 }
175
176 fn is_alive(&self) -> bool {
177 false
178 }
179}
180
181pub trait Particle {
183 type Coordinate;
185
186 fn get_position(&self) -> Self::Coordinate;
188
189 fn update(&mut self, dt: f64);
191
192 fn is_alive(&self) -> bool;
194}
195
196impl<P: Particle + ?Sized> Particle for Box<P> {
197 type Coordinate = P::Coordinate;
198
199 fn get_position(&self) -> Self::Coordinate {
200 P::get_position(self)
201 }
202
203 fn update(&mut self, dt: f64) {
204 P::update(self, dt);
205 }
206
207 fn is_alive(&self) -> bool {
208 P::is_alive(self)
209 }
210}
211
212pub trait Aging {
214 fn get_age(&self) -> f64;
216
217 fn set_age(&mut self, age: f64);
219}
220
221pub trait MaxAging: Aging {
223 fn get_max_age(&self) -> f64;
225
226 fn get_age_percent(&self) -> f64 {
228 self.get_age() / self.get_max_age()
229 }
230
231 fn is_alive(&self) -> bool {
233 self.get_age_percent() < 1.0
234 }
235}