1 use specs::prelude::*;
2 use super::{Rltk, ParticleLifetime, Position, Renderable};
3 use rltk::{RGB};
4
5 pub struct ParticleSpawnSystem {}
6
7 impl<'a> System<'a> for ParticleSpawnSystem {
8 #[allow(clippy::type_complexity)]
9 type SystemData = (
10 Entities<'a>,
11 WriteStorage<'a, Position>,
12 WriteStorage<'a, Renderable>,
13 WriteStorage<'a, ParticleLifetime>,
14 WriteExpect<'a, ParticleBuilder>
15 );
16
17 fn run(&mut self, data : Self::SystemData) {
18 let (entities, mut positions, mut renderables, mut particles, mut particle_builder) = data;
19 for new_particle in particle_builder.requests.iter() {
20 let p = entities.create();
21 positions.insert(p, Position{ x: new_particle.x, y: new_particle.y }).expect("Unable to inser position");
22 renderables.insert(p, Renderable{ fg: new_particle.fg, bg: new_particle.bg, glyph: new_particle.glyph, render_order: 0 }).expect("Unable to insert renderable");
23 particles.insert(p, ParticleLifetime{ lifetime_ms: new_particle.lifetime }).expect("Unable to insert lifetime");
24 }
25
26 particle_builder.requests.clear();
27 }
28 }
29
30 struct ParticleRequest {
31 x: i32,
32 y: i32,
33 fg: RGB,
34 bg: RGB,
35 glyph: rltk::FontCharType,
36 lifetime: f32
37 }
38
39 pub struct ParticleBuilder {
40 requests : Vec<ParticleRequest>
41 }
42
43 impl ParticleBuilder {
44 #[allow(clippy::new_without_default)]
45 pub fn new() -> ParticleBuilder {
46 ParticleBuilder{ requests : Vec::new() }
47 }
48
49 pub fn request(&mut self, x:i32, y:i32, fg: RGB, bg:RGB, glyph: rltk::FontCharType, lifetime: f32) {
50 self.requests.push(
51 ParticleRequest{
52 x, y, fg, bg, glyph, lifetime
53 }
54 );
55 }
56 }
57
58 pub fn cull_dead_particles(ecs : &mut World, ctx : &Rltk) {
59 let mut dead_particles : Vec<Entity> = Vec::new();
60 {
61 // Age out particles
62 let mut particles = ecs.write_storage::<ParticleLifetime>();
63 let entities = ecs.entities();
64 for (entity, mut particle) in (&entities, &mut particles).join() {
65 particle.lifetime_ms -= ctx.frame_time_ms;
66 if particle.lifetime_ms < 0.0 {
67 dead_particles.push(entity);
68 }
69 }
70 }
71 for dead in dead_particles.iter() {
72 ecs.delete_entity(*dead).expect("Particle will not die");
73 }
74 }