From b020a45e650a8a805b1d231b8ec4def30e126c20 Mon Sep 17 00:00:00 2001 From: Daniel Gallups Date: Wed, 4 Sep 2024 00:43:52 -0400 Subject: [PATCH] feat: parallelize consuming plugin --- src/cell/mouth.rs | 9 +-- src/environment/mod.rs | 4 +- src/organism/mod.rs | 62 +++++----------- src/organism/plugin.rs | 156 ++++++++++++++++++++++++----------------- 4 files changed, 115 insertions(+), 116 deletions(-) diff --git a/src/cell/mouth.rs b/src/cell/mouth.rs index cc8bcde..74ef16b 100644 --- a/src/cell/mouth.rs +++ b/src/cell/mouth.rs @@ -1,6 +1,6 @@ use bevy::prelude::*; -use crate::{neighbor::VecExt as _, organism::Organism, CellTree, GameState}; +use crate::{neighbor::VecExt as _, organism::Belly, CellTree, GameState}; use super::Food; @@ -19,7 +19,7 @@ fn consume_food( mut commands: Commands, locations: Res, mouths: Query<(&GlobalTransform, &Parent), With>, - mut organisms: Query<&mut Organism>, + mut organisms: Query<&mut Belly>, food: Query<&Food>, ) { for (mouth, mouth_parent) in &mouths { @@ -40,10 +40,7 @@ fn consume_food( } if food_eaten > 0 { - organisms - .get_mut(mouth_parent.get()) - .unwrap() - .ate_food(food_eaten); + organisms.get_mut(mouth_parent.get()).unwrap().0 += food_eaten; } } } diff --git a/src/environment/mod.rs b/src/environment/mod.rs index e4a1490..fb9ab89 100644 --- a/src/environment/mod.rs +++ b/src/environment/mod.rs @@ -1,7 +1,7 @@ pub use bevy::prelude::*; use mouse_hover::hover_over_organism; -use crate::cell::CellType; +use crate::{cell::CellType, organism::Belly}; use super::{ organism::{Organism, OrganismPlugin}, @@ -121,5 +121,5 @@ fn clear_background(mut color: ResMut) { /// Creates the first organism. [`Organism::insert_at`] is used to unify spawning of the organism in the ECS /// as well as placing itself in the [`OccupiedLocations`] hashmap. fn spawn_first_organism(mut commands: Commands) { - Organism::first_organism().insert_at(&mut commands, Vec2::new(10., 10.)); + Organism::first_organism().insert_at(&mut commands, Vec2::new(10., 10.), Belly(3)); } diff --git a/src/organism/mod.rs b/src/organism/mod.rs index 6973964..c1fe9b3 100644 --- a/src/organism/mod.rs +++ b/src/organism/mod.rs @@ -12,6 +12,15 @@ pub use plugin::*; mod reproduction; use reproduction::*; +#[derive(Component, Clone)] +pub struct Belly(pub u64); + +#[derive(Component)] +pub struct Age(pub u64); + +#[derive(Component)] +pub struct StarvedAt(pub u64); + #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum BrainType { Predator, @@ -23,17 +32,12 @@ pub struct Organism { genome: Genome, brain: Option, can_move: bool, - belly: u64, - /// in millis - time_born: u64, - offspring: u64, /// in millis - last_starved: u64, can_reproduce_at: u64, } impl Organism { - fn new(genome: Genome, belly: u64, time_born: u64) -> Self { + fn new(genome: Genome) -> Self { let mut has_producer = false; let mut has_eye = false; let mut has_mover = false; @@ -69,15 +73,11 @@ impl Organism { genome, brain: brain_type, can_move: has_mover && !has_producer, - belly, - time_born, - offspring: 0, - last_starved: 0, can_reproduce_at, } } - pub fn ready_to_reproduce(&self) -> bool { - self.belly >= self.can_reproduce_at + pub fn ready_to_reproduce(&self, belly: &Belly) -> bool { + belly.0 >= self.can_reproduce_at } /// returns the number of cells this organism takes up based on its genome @@ -102,47 +102,20 @@ impl Organism { self.can_move } - pub fn reproduce(&mut self, current_tick: u64) -> Option { - //always lose half of one's belly - self.belly /= 2; + pub fn reproduce(&self) -> Option { let child_genome = self.genome.reproduce(); if child_genome.num_cells() < 2 { return None; } - self.offspring += 1; - Some(Self::new(child_genome, self.belly, current_tick)) + Some(Self::new(child_genome)) } pub fn first_organism() -> Self { - Self::new(Genome::first_organism(), 3, 0) - } - pub fn ate_food(&mut self, amt: u64) { - if self.belly < self.can_reproduce_at { - self.belly += amt; - } - } - - pub fn lost_food(&mut self, amt: u64, time: u64) { - self.belly = self.belly.saturating_sub(amt); - self.last_starved = time; - //info!("Organism lost food, belly is at {}", self.belly) - } - - /// returns the millisecond last starved - pub fn time_last_starved(&self) -> u64 { - self.last_starved - } - - pub fn time_born(&self) -> u64 { - self.time_born - } - - pub fn belly(&self) -> u64 { - self.belly + Self::new(Genome::first_organism()) } /// Uses both the ECS and the global positioning hashmap to insert itself. - pub fn insert_at(self, commands: &mut Commands, location: impl VecExt) { + pub fn insert_at(self, commands: &mut Commands, location: impl VecExt, belly: Belly) { /*info!( "\nInserting Organism into the world:\nLocation: {:?}\nto insert:{:#?}", global_location, self @@ -157,6 +130,9 @@ impl Organism { ..Default::default() }, self, + belly, + Age(0), + StarvedAt(0), )) .with_children(|child_builder| { genome.spawn_cells(child_builder); diff --git a/src/organism/plugin.rs b/src/organism/plugin.rs index b3548fd..88c2a4d 100644 --- a/src/organism/plugin.rs +++ b/src/organism/plugin.rs @@ -8,7 +8,7 @@ use crate::{ CellTree, GameState, }; -use super::Organism; +use super::{Age, Belly, Organism, StarvedAt}; /// Combines the systems of cells and organism actions pub struct OrganismPlugin; @@ -27,6 +27,8 @@ impl Plugin for OrganismPlugin { .add_systems( Update, ( + age_organism.run_if(in_state(GameState::Playing)), + organism_hunger.run_if(in_state(GameState::Playing)), starve_organism.run_if(in_state(GameState::Playing)), reproduce_organism.run_if(in_state(GameState::Playing)), ), @@ -34,44 +36,62 @@ impl Plugin for OrganismPlugin { } } -fn starve_organism( +fn age_organism(time: Res