terrain-forge 0.7.0

A modular procedural generation engine for terrain, dungeons, and maps
Documentation
//! Pipeline for sequential algorithm execution.
//!
//! This is the lightweight, algorithm-only pipeline (not the ops pipeline).

use crate::{Algorithm, Cell, Grid};

/// Sequential algorithm pipeline.
///
/// # Examples
///
/// ```
/// use terrain_forge::Grid;
/// use terrain_forge::compose::Pipeline;
/// use terrain_forge::algorithms::{Bsp, CellularAutomata};
///
/// let mut grid = Grid::new(40, 30);
/// let pipe = Pipeline::new()
///     .then(Bsp::default())
///     .then(CellularAutomata::default());
/// pipe.execute(&mut grid, 42);
/// ```
pub struct Pipeline<C: Cell> {
    steps: Vec<Box<dyn Algorithm<C> + Send + Sync>>,
}

impl<C: Cell> Pipeline<C> {
    pub fn new() -> Self {
        Self { steps: Vec::new() }
    }

    pub fn then<A: Algorithm<C> + 'static>(mut self, algorithm: A) -> Self {
        self.steps.push(Box::new(algorithm));
        self
    }

    pub fn execute(&self, grid: &mut Grid<C>, seed: u64) {
        for (i, step) in self.steps.iter().enumerate() {
            step.generate(grid, seed.wrapping_add(i as u64 * 1000));
        }
    }
}

impl<C: Cell> Default for Pipeline<C> {
    fn default() -> Self {
        Self::new()
    }
}

impl<C: Cell> Algorithm<C> for Pipeline<C> {
    fn generate(&self, grid: &mut Grid<C>, seed: u64) {
        self.execute(grid, seed);
    }

    fn name(&self) -> &'static str {
        "Pipeline"
    }
}