Drop `BuilderData` trait.

This commit is contained in:
Nolan Darilek 2022-03-13 21:14:59 -05:00
parent ffaad6cf48
commit 2202540a43
17 changed files with 61 additions and 78 deletions

View File

@ -2,7 +2,7 @@ use mapgen::{
filter::{
AreaStartingPosition, CellularAutomata, CullUnreachable, NoiseGenerator, XStart, YStart,
},
BuilderData, MapBuilder, MapFilter,
MapBuilder, MapFilter,
};
#[derive(Clone, Default)]
@ -10,11 +10,9 @@ struct MyData {
value: usize,
}
impl BuilderData for MyData {}
struct IncrementData;
impl<D: BuilderData> MapFilter<D> for IncrementData {
impl<D: Clone + Default> MapFilter<D> for IncrementData {
fn modify_map(&self, rng: &mut rand::prelude::StdRng, map: &mapgen::Map<D>) -> mapgen::Map<D> {
let map = map.clone();
map.data.value += 1;
@ -28,7 +26,7 @@ fn main() {
.with(CellularAutomata::new())
.with(AreaStartingPosition::new(XStart::CENTER, YStart::CENTER))
.with(CullUnreachable::new())
.with(Box::new(IncrementData))
.with(Box::new(IncrementData::<MyData>))
.build();
println!("{:}", &map);

View File

@ -25,7 +25,7 @@
//! ---
//!
use super::map::{BuilderData, Map};
use super::map::Map;
use std::f32::MAX;
use std::{collections::VecDeque, marker::PhantomData};
@ -41,13 +41,13 @@ pub struct DijkstraMap<D> {
phantom: PhantomData<D>,
}
impl<D: BuilderData> DijkstraMap<D> {
impl<D: Clone + Default> DijkstraMap<D> {
//! Construct a new Dijkstra map, ready to run.
pub fn new(map: &Map<D>) -> DijkstraMap<D> {
let len = map.width * map.height;
let tiles = vec![MAX; len];
let mut d = DijkstraMap {
tiles: tiles,
tiles,
size_x: map.width,
size_y: map.height,
max_depth: len as f32,

View File

@ -25,21 +25,21 @@ use std::marker::PhantomData;
use crate::geometry::{Point, Rect};
use crate::random::Rng;
use crate::Map;
use crate::{BuilderData, MapFilter};
use crate::MapFilter;
use rand::prelude::*;
pub struct BspInterior<D: BuilderData> {
pub struct BspInterior<D> {
min_room_size: usize,
phantom: PhantomData<D>,
}
impl<D: BuilderData> MapFilter<D> for BspInterior<D> {
impl<D: Clone + Default> MapFilter<D> for BspInterior<D> {
fn modify_map(&self, rng: &mut StdRng, map: &Map<D>) -> Map<D> {
self.build(rng, map)
}
}
impl<D: BuilderData> BspInterior<D> {
impl<D: Clone + Default> BspInterior<D> {
pub fn new() -> Box<BspInterior<D>> {
Box::new(BspInterior {
min_room_size: 8,

View File

@ -22,23 +22,22 @@ use std::marker::PhantomData;
use crate::geometry::Rect;
use crate::random::Rng;
use crate::BuilderData;
use crate::Map;
use crate::MapFilter;
use rand::prelude::*;
pub struct BspRooms<D: BuilderData> {
pub struct BspRooms<D> {
max_split: usize,
phantom: PhantomData<D>,
}
impl<D: BuilderData> MapFilter<D> for BspRooms<D> {
impl<D: Clone + Default> MapFilter<D> for BspRooms<D> {
fn modify_map(&self, rng: &mut StdRng, map: &Map<D>) -> Map<D> {
self.build_rooms(map, rng)
}
}
impl<D: BuilderData> BspRooms<D> {
impl<D: Clone + Default> BspRooms<D> {
pub fn new() -> Box<BspRooms<D>> {
Box::new(BspRooms {
max_split: 240,
@ -152,10 +151,8 @@ impl<D: BuilderData> BspRooms<D> {
if y < 1 {
can_build = false;
}
if can_build {
if map.at(x as usize, y as usize).is_walkable() {
can_build = false;
}
if can_build && map.at(x as usize, y as usize).is_walkable() {
can_build = false;
}
}
}

View File

@ -23,24 +23,23 @@
use std::marker::PhantomData;
use crate::BuilderData;
use crate::MapFilter;
use crate::{Map, Tile};
use rand::prelude::*;
/// Map filter
pub struct CellularAutomata<D: BuilderData> {
pub struct CellularAutomata<D> {
num_iteraction: u32,
phantom: PhantomData<D>,
}
impl<D: BuilderData> MapFilter<D> for CellularAutomata<D> {
impl<D: Clone + Default> MapFilter<D> for CellularAutomata<D> {
fn modify_map(&self, _rng: &mut StdRng, map: &Map<D>) -> Map<D> {
self.build(map)
}
}
impl<D: BuilderData> CellularAutomata<D> {
impl<D: Clone + Default> CellularAutomata<D> {
/// Create generator which will create map with the given dimension.
pub fn new() -> Box<CellularAutomata<D>> {
Box::new(CellularAutomata {
@ -60,7 +59,7 @@ impl<D: BuilderData> CellularAutomata<D> {
}
}
fn apply_iteration<D: BuilderData>(map: &Map<D>) -> Map<D> {
fn apply_iteration<D: Clone + Default>(map: &Map<D>) -> Map<D> {
let mut new_map = map.clone();
for y in 1..map.height - 1 {

View File

@ -8,21 +8,21 @@ use std::marker::PhantomData;
use crate::dijkstra::DijkstraMap;
use crate::MapFilter;
use crate::{BuilderData, Map, Tile};
use crate::{Map, Tile};
use rand::prelude::StdRng;
/// Remove unreachable areas from the map.
pub struct CullUnreachable<D: BuilderData> {
pub struct CullUnreachable<D> {
phantom: PhantomData<D>,
}
impl<D: BuilderData> MapFilter<D> for CullUnreachable<D> {
impl<D: Clone + Default> MapFilter<D> for CullUnreachable<D> {
fn modify_map(&self, _: &mut StdRng, map: &Map<D>) -> Map<D> {
self.build(map)
}
}
impl<D: BuilderData> CullUnreachable<D> {
impl<D: Clone + Default> CullUnreachable<D> {
#[allow(dead_code)]
pub fn new() -> Box<CullUnreachable<D>> {
Box::new(CullUnreachable {

View File

@ -6,7 +6,6 @@
use crate::dijkstra::DijkstraMap;
use crate::geometry::Point;
use crate::BuilderData;
use crate::Map;
use crate::MapFilter;
use rand::prelude::StdRng;
@ -14,17 +13,17 @@ use std::f32;
use std::marker::PhantomData;
/// Add exist position to the map based on the distance from the start point.
pub struct DistantExit<D: BuilderData> {
pub struct DistantExit<D> {
phantom: PhantomData<D>,
}
impl<D: BuilderData> MapFilter<D> for DistantExit<D> {
impl<D: Clone + Default> MapFilter<D> for DistantExit<D> {
fn modify_map(&self, _: &mut StdRng, map: &Map<D>) -> Map<D> {
self.build(map)
}
}
impl<D: BuilderData> DistantExit<D> {
impl<D: Clone + Default> DistantExit<D> {
#[allow(dead_code)]
pub fn new() -> Box<DistantExit<D>> {
Box::new(DistantExit {

View File

@ -20,7 +20,6 @@ use crate::{
geometry::Point,
map::{Map, Symmetry, Tile},
random::Rng,
BuilderData,
};
use rand::prelude::*;
@ -30,7 +29,7 @@ pub enum DrunkSpawnMode {
Random,
}
pub struct DrunkardsWalk<D: BuilderData> {
pub struct DrunkardsWalk<D> {
spawn_mode: DrunkSpawnMode,
drunken_lifetime: i32,
floor_percent: f32,
@ -39,13 +38,13 @@ pub struct DrunkardsWalk<D: BuilderData> {
phantom: PhantomData<D>,
}
impl<D: BuilderData> MapFilter<D> for DrunkardsWalk<D> {
impl<D: Clone + Default> MapFilter<D> for DrunkardsWalk<D> {
fn modify_map(&self, rng: &mut StdRng, map: &Map<D>) -> Map<D> {
self.build(rng, map)
}
}
impl<D: BuilderData> DrunkardsWalk<D> {
impl<D: Clone + Default> DrunkardsWalk<D> {
pub fn new(
spawn_mode: DrunkSpawnMode,
drunken_lifetime: i32,

View File

@ -17,22 +17,22 @@ use std::marker::PhantomData;
use crate::MapFilter;
use crate::{
map::{BuilderData, Map, Tile},
map::{Map, Tile},
random::Rng,
};
use rand::prelude::*;
pub struct MazeBuilder<D: BuilderData> {
pub struct MazeBuilder<D> {
phantom: PhantomData<D>,
}
impl<D: BuilderData> MapFilter<D> for MazeBuilder<D> {
impl<D: Clone + Default> MapFilter<D> for MazeBuilder<D> {
fn modify_map(&self, rng: &mut StdRng, map: &Map<D>) -> Map<D> {
self.build(rng, map)
}
}
impl<D: BuilderData> MazeBuilder<D> {
impl<D: Clone + Default> MazeBuilder<D> {
pub fn new() -> Box<MazeBuilder<D>> {
Box::new(MazeBuilder {
phantom: PhantomData,
@ -93,7 +93,7 @@ impl Cell {
}
}
struct Grid<'a, D: BuilderData> {
struct Grid<'a, D> {
width: i32,
height: i32,
cells: Vec<Cell>,
@ -103,7 +103,7 @@ struct Grid<'a, D: BuilderData> {
phantom: PhantomData<D>,
}
impl<'a, D: BuilderData> Grid<'a, D> {
impl<'a, D: Clone + Default> Grid<'a, D> {
fn new(width: i32, height: i32, rng: &mut StdRng) -> Grid<D> {
let mut grid = Grid {
width,

View File

@ -19,22 +19,22 @@
use std::marker::PhantomData;
use crate::MapFilter;
use crate::{BuilderData, Map, Tile};
use crate::{Map, Tile};
use rand::prelude::*;
/// Map noise generator
pub struct NoiseGenerator<D: BuilderData> {
pub struct NoiseGenerator<D> {
prob: f32,
phantom: PhantomData<D>,
}
impl<D: BuilderData> MapFilter<D> for NoiseGenerator<D> {
impl<D: Clone + Default> MapFilter<D> for NoiseGenerator<D> {
fn modify_map(&self, rng: &mut StdRng, map: &Map<D>) -> Map<D> {
self.build(map, rng)
}
}
impl<D: BuilderData> NoiseGenerator<D> {
impl<D: Clone + Default> NoiseGenerator<D> {
/// Create noise with custom probability
pub fn new(prob: f32) -> Box<NoiseGenerator<D>> {
Box::new(NoiseGenerator {

View File

@ -1,23 +1,22 @@
//! Connect nearest rooms on the map with corridors
//!
use crate::BuilderData;
use crate::Map;
use crate::MapFilter;
use rand::prelude::StdRng;
use std::collections::HashSet;
use std::marker::PhantomData;
pub struct NearestCorridors<D: BuilderData> {
pub struct NearestCorridors<D> {
phantom: PhantomData<D>,
}
impl<D: BuilderData> MapFilter<D> for NearestCorridors<D> {
impl<D: Clone + Default> MapFilter<D> for NearestCorridors<D> {
fn modify_map(&self, _: &mut StdRng, map: &Map<D>) -> Map<D> {
self.corridors(map)
}
}
impl<D: BuilderData> NearestCorridors<D> {
impl<D: Clone + Default> NearestCorridors<D> {
pub fn new() -> Box<NearestCorridors<D>> {
Box::new(NearestCorridors {
phantom: PhantomData,

View File

@ -22,25 +22,24 @@ use std::marker::PhantomData;
use crate::geometry::Rect;
use crate::random::Rng;
use crate::BuilderData;
use crate::Map;
use crate::MapFilter;
use rand::prelude::*;
pub struct SimpleRooms<D: BuilderData> {
pub struct SimpleRooms<D> {
max_rooms: usize,
min_room_size: usize,
max_room_size: usize,
phantom: PhantomData<D>,
}
impl<D: BuilderData> MapFilter<D> for SimpleRooms<D> {
impl<D: Clone + Default> MapFilter<D> for SimpleRooms<D> {
fn modify_map(&self, rng: &mut StdRng, map: &Map<D>) -> Map<D> {
self.build_rooms(map, rng)
}
}
impl<D: BuilderData> SimpleRooms<D> {
impl<D: Clone + Default> SimpleRooms<D> {
pub fn new() -> Box<SimpleRooms<D>> {
Box::new(SimpleRooms {
max_rooms: 30,

View File

@ -23,7 +23,6 @@
use std::marker::PhantomData;
use crate::geometry::Point;
use crate::BuilderData;
use crate::Map;
use crate::MapFilter;
use rand::prelude::StdRng;
@ -43,19 +42,19 @@ pub enum YStart {
}
/// Add starting position to the map
pub struct AreaStartingPosition<D: BuilderData> {
pub struct AreaStartingPosition<D> {
x: XStart,
y: YStart,
phantom: PhantomData<D>,
}
impl<D: BuilderData> MapFilter<D> for AreaStartingPosition<D> {
impl<D: Clone + Default> MapFilter<D> for AreaStartingPosition<D> {
fn modify_map(&self, _: &mut StdRng, map: &Map<D>) -> Map<D> {
self.build(map)
}
}
impl<D: BuilderData> AreaStartingPosition<D> {
impl<D: Clone + Default> AreaStartingPosition<D> {
/// Create new modifier with given region
pub fn new(x: XStart, y: YStart) -> Box<AreaStartingPosition<D>> {
Box::new(AreaStartingPosition {

View File

@ -18,23 +18,23 @@ use std::marker::PhantomData;
use crate::MapFilter;
use crate::{
geometry::Point,
map::{BuilderData, Map, Tile},
map::{Map, Tile},
random::Rng,
};
use rand::prelude::*;
pub struct VoronoiHive<D: BuilderData> {
pub struct VoronoiHive<D> {
n_seeds: usize,
phantom: PhantomData<D>,
}
impl<D: BuilderData> MapFilter<D> for VoronoiHive<D> {
impl<D: Clone + Default> MapFilter<D> for VoronoiHive<D> {
fn modify_map(&self, rng: &mut StdRng, map: &Map<D>) -> Map<D> {
self.build(rng, map)
}
}
impl<D: BuilderData> VoronoiHive<D> {
impl<D: Clone + Default> VoronoiHive<D> {
pub fn new() -> Box<VoronoiHive<D>> {
Box::new(VoronoiHive {
n_seeds: 64,

View File

@ -34,7 +34,7 @@ pub mod map;
pub mod metric;
pub use filter::*;
pub use map::{BuilderData, Map, NoData, Symmetry, Tile};
pub use map::{Map, NoData, Symmetry, Tile};
pub(crate) mod dijkstra;
pub(crate) mod random;
@ -44,18 +44,18 @@ use std::time::{SystemTime, UNIX_EPOCH};
/// Trait which should be implemented by map modifier.
/// Modifier takes initiall map and apply changes to it.
pub trait MapFilter<D: BuilderData> {
pub trait MapFilter<D: Clone + Default> {
fn modify_map(&self, rng: &mut StdRng, map: &Map<D>) -> Map<D>;
}
/// Used to chain MapBuilder and MapModifiers to create the final map.
pub struct MapBuilder<D> {
pub struct MapBuilder<D: Clone + Default> {
width: usize,
height: usize,
modifiers: Vec<Box<dyn MapFilter<D>>>,
}
impl<D: BuilderData> MapBuilder<D> {
impl<D: Clone + Default> MapBuilder<D> {
/// Create Map Builder with initial map generator
pub fn new(width: usize, height: usize) -> MapBuilder<D> {
MapBuilder {

View File

@ -24,18 +24,13 @@ pub enum Symmetry {
Both,
}
/// Arbitrary data associated with each map
pub trait BuilderData: Clone + Default {}
/// No build data
#[derive(Clone, Debug, Default)]
pub struct NoData;
impl BuilderData for NoData {}
/// Map data
#[derive(Default, Clone)]
pub struct Map<D> {
pub struct Map<D: Clone + Default> {
pub tiles: Vec<Tile>,
pub width: usize,
pub height: usize,
@ -72,7 +67,7 @@ impl Tile {
}
}
impl<D: BuilderData> Map<D> {
impl<D: Clone + Default> Map<D> {
/// Generates an empty map, consisting entirely of solid walls
pub fn new(width: usize, height: usize) -> Map<D> {
let map_tile_count = width * height;
@ -274,7 +269,7 @@ impl<D: BuilderData> Map<D> {
}
}
impl<D: BuilderData> fmt::Display for Map<D> {
impl<D: Clone + Default> fmt::Display for Map<D> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for y in 0..self.height {
let bytes: Vec<u8> = (0..self.width)

View File

@ -6,12 +6,11 @@
use super::dijkstra::DijkstraMap;
use super::map::Map;
use super::BuilderData;
/// This metric calculates the percentage of walkable cells (Floor).
/// If this number is very low (like < 10%) then it means that the map
/// is probably to degenerated and shouldn't be used
pub fn density<D>(map: &Map<D>) -> f32 {
pub fn density<D: Clone + Default>(map: &Map<D>) -> f32 {
let floor_count = map.tiles.iter().filter(|&t| t.is_walkable()).count();
floor_count as f32 / map.tiles.len() as f32
}
@ -19,7 +18,7 @@ pub fn density<D>(map: &Map<D>) -> f32 {
/// Calculate the length of the shortes path from the starting point
/// to the exit.
/// If this path is very short, then the map is probably degenerated.
pub fn path_length<D: BuilderData>(map: &Map<D>) -> f32 {
pub fn path_length<D: Clone + Default>(map: &Map<D>) -> f32 {
if map.starting_point.is_none() {
return 0.0;
}