144 lines
4.3 KiB
Rust
144 lines
4.3 KiB
Rust
use std::fmt::Display;
|
|
|
|
use crate::genetics::flow::Flow;
|
|
|
|
#[derive(PartialEq,Eq,Clone)]
|
|
pub struct Gene {
|
|
pub plant_source: GeneSource,
|
|
pub place: String,
|
|
pub kind: GeneType
|
|
}
|
|
|
|
pub struct GeneContext {
|
|
pub flow: Flow
|
|
}
|
|
|
|
#[derive(PartialEq,Eq,Clone,Copy)]
|
|
pub enum GeneSource {
|
|
Peashooter,
|
|
Sunflower,
|
|
CherryBomb,
|
|
PotatoMine,
|
|
}
|
|
|
|
/// GeneType is an enum that defines behaviour of gene.
|
|
#[derive(PartialEq,Eq,Clone)]
|
|
pub enum GeneType {
|
|
/// Without functional behaviour. Doesn't pass through flow.
|
|
Structural,
|
|
/// Only creates flow. Can be set up to not create flow if flow isn't empty.
|
|
PureProducer {
|
|
create_flow: fn(GeneContext) -> Flow
|
|
},
|
|
/// Creates or modifies flow. Needs to decide whether to create or modify flow.
|
|
Producer {
|
|
create_flow: fn(GeneContext) -> Flow,
|
|
modify_single: fn(GeneContext) -> Flow,
|
|
modify_all: fn(GeneContext) -> Flow,
|
|
decide_modification_type: fn(GeneContext) -> ProduceDecision,
|
|
},
|
|
/// Allows flow to pass through.
|
|
Transport {
|
|
distribute_between_children: fn(GeneContext) -> ChildDistribution
|
|
},
|
|
/// Consumes flow, destroying it in process.
|
|
Consumer {
|
|
consume: fn(GeneContext)
|
|
},
|
|
/// Modifies flow
|
|
Modifier {
|
|
modify_flow: fn(GeneContext) -> Flow
|
|
},
|
|
/// Conditionally passes through flow. Acts like transport.
|
|
Trigger {
|
|
check_trigger: fn(GeneContext) -> bool,
|
|
distribute_between_children: fn(GeneContext) -> ChildDistribution
|
|
},
|
|
/// Observes flow. Acts like transport.
|
|
Observer {
|
|
observe: fn(GeneContext),
|
|
distribute_between_children: fn(GeneContext) -> ChildDistribution
|
|
},
|
|
}
|
|
|
|
pub enum ChildDistribution{
|
|
Single,
|
|
Multiple{amount: usize},
|
|
All,
|
|
Custom{child_indicies: Vec<usize>}
|
|
}
|
|
|
|
pub enum ProduceDecision {
|
|
Create,
|
|
ModifyAll,
|
|
ModifySingle,
|
|
}
|
|
|
|
impl Gene {
|
|
pub fn new(plant_source: GeneSource, place_str: impl Into<String>, kind: GeneType) -> Self {
|
|
Self {
|
|
plant_source,
|
|
place: place_str.into(),
|
|
kind,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Display for GeneSource {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
write!(f,"{}",match self {
|
|
GeneSource::Peashooter => "Peashooter",
|
|
GeneSource::Sunflower => "Sunflower",
|
|
GeneSource::CherryBomb => "CherryBomb",
|
|
GeneSource::PotatoMine => "PotatoMine",
|
|
});
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl Display for Gene {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
write!(f,"({}) {}",self.plant_source,self.place);
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl GeneType {
|
|
/// Creates pure producer with create function.
|
|
pub fn pure_producer(flow_function: fn(GeneContext) -> Flow) -> Self {
|
|
Self::PureProducer { create_flow: flow_function }
|
|
}
|
|
/// Creates transport with random distribution.
|
|
pub fn random_distribution() -> Self {
|
|
Self::Transport { distribute_between_children: Self::distribute_between_random }
|
|
}
|
|
/// Creates transport with distribution between all children.
|
|
pub fn fill_all() -> Self {
|
|
Self::Transport { distribute_between_children: Self::distribute_between_all }
|
|
}
|
|
/// Creates consumer with consumer function.
|
|
pub fn consumer(consumer_function: fn(GeneContext)) -> Self {
|
|
Self::Consumer { consume: consumer_function }
|
|
}
|
|
/// Creates modifier with modifier function.
|
|
pub fn modifier(modifier_function: fn(GeneContext) -> Flow) -> Self {
|
|
Self::Modifier { modify_flow: modifier_function }
|
|
}
|
|
/// Creates trigger with distribution between all children.
|
|
pub fn trigger_all(trigger_function: fn(GeneContext) -> bool) -> Self {
|
|
Self::Trigger { check_trigger: trigger_function, distribute_between_children: Self::distribute_between_all }
|
|
}
|
|
/// Creates observer with distribution between all children.
|
|
pub fn observer_all(observer_function: fn(GeneContext)) -> Self {
|
|
Self::Observer { observe: observer_function, distribute_between_children: Self::distribute_between_all }
|
|
}
|
|
|
|
|
|
fn distribute_between_random(_: GeneContext) -> ChildDistribution {
|
|
ChildDistribution::Single
|
|
}
|
|
fn distribute_between_all(_: GeneContext) -> ChildDistribution {
|
|
ChildDistribution::All
|
|
}
|
|
}
|
|
|