Refactor mapgen to allow for easy switching between generators transitional_engine
authorunC0Rr
Mon, 13 Feb 2023 12:31:30 +0100
branchtransitional_engine
changeset 15952 da6b67f13c12
parent 15951 5f00829c55ec
child 15953 d46ad15c6dec
Refactor mapgen to allow for easy switching between generators
rust/landgen/src/outline_template_based/mod.rs
rust/landgen/src/outline_template_based/template_based.rs
rust/landgen/src/wavefront_collapse/generator.rs
rust/landgen/src/wavefront_collapse/wavefront_collapse.rs
rust/lib-hwengine-future/src/lib.rs
rust/mapgen/src/lib.rs
rust/mapgen/src/template/mod.rs
rust/mapgen/src/template/outline.rs
rust/mapgen/src/template/wavefront_collapse.rs
--- a/rust/landgen/src/outline_template_based/mod.rs	Mon Feb 13 11:00:12 2023 +0100
+++ b/rust/landgen/src/outline_template_based/mod.rs	Mon Feb 13 12:31:30 2023 +0100
@@ -1,3 +1,3 @@
 mod outline;
 pub mod outline_template;
-pub mod template_based;
\ No newline at end of file
+pub mod template_based;
--- a/rust/landgen/src/outline_template_based/template_based.rs	Mon Feb 13 11:00:12 2023 +0100
+++ b/rust/landgen/src/outline_template_based/template_based.rs	Mon Feb 13 12:31:30 2023 +0100
@@ -1,8 +1,5 @@
-use super::{
-    outline::OutlinePoints, outline_template::OutlineTemplate};
-use crate::{LandGenerationParameters,
-    LandGenerator,
-};
+use super::{outline::OutlinePoints, outline_template::OutlineTemplate};
+use crate::{LandGenerationParameters, LandGenerator};
 use land2d::Land2D;
 
 pub struct TemplatedLandGenerator {
--- a/rust/landgen/src/wavefront_collapse/generator.rs	Mon Feb 13 11:00:12 2023 +0100
+++ b/rust/landgen/src/wavefront_collapse/generator.rs	Mon Feb 13 12:31:30 2023 +0100
@@ -8,13 +8,44 @@
 use std::io::{BufReader, Result};
 use std::path::Path;
 
+#[derive(Clone)]
+pub struct EdgeDescription {
+    pub name: String,
+    pub reversed: Option<bool>,
+    pub symmetrical: Option<bool>,
+}
+
+#[derive(Clone)]
+pub struct EdgesDescription {
+    pub top: EdgeDescription,
+    pub right: EdgeDescription,
+    pub bottom: EdgeDescription,
+    pub left: EdgeDescription,
+}
+
+#[derive(Clone)]
+pub struct TileDescription {
+    pub name: String,
+    pub edges: EdgesDescription,
+    pub can_flip: bool,
+    pub can_mirror: bool,
+    pub can_rotate90: bool,
+    pub can_rotate180: bool,
+    pub can_rotate270: bool,
+}
+
+pub struct TemplateDescription {
+    pub size: Size,
+    pub tiles: Vec<TileDescription>,
+}
+
 pub struct WavefrontCollapseLandGenerator {
-    pub size: Size,
+    pub template: TemplateDescription,
 }
 
 impl WavefrontCollapseLandGenerator {
-    pub fn new(size: &Size) -> Self {
-        Self { size: *size }
+    pub fn new(template: TemplateDescription) -> Self {
+        Self { template }
     }
 
     fn load_image_tiles<T: Copy + PartialEq + Default>(
@@ -140,8 +171,8 @@
             let tile_size = first_tile.size();
 
             Size::new(
-                self.size.width / tile_size.width,
-                self.size.height / tile_size.height,
+                self.template.size.width / tile_size.width,
+                self.template.size.height / tile_size.height,
             )
         } else {
             Size::new(1, 1)
@@ -149,17 +180,7 @@
 
         wfc.generate_map(&wfc_size, |_| {}, random_numbers);
 
-        let grid = wfc.grid();
-
-        for r in 0..grid.height() {
-            for c in 0..grid.width() {
-                print!("{:?} ", grid.get(r, c));
-            }
-
-            println!();
-        }
-
-        let mut result = land2d::Land2D::new(&self.size, parameters.zero);
+        let mut result = land2d::Land2D::new(&self.template.size, parameters.zero);
 
         for row in 0..wfc_size.height {
             for column in 0..wfc_size.width {
@@ -194,7 +215,6 @@
     use std::fs::File;
     use std::io::BufWriter;
     use std::path::Path;
-    use vec2d::Vec2D;
 
     #[test]
     fn test_generation() {
--- a/rust/landgen/src/wavefront_collapse/wavefront_collapse.rs	Mon Feb 13 11:00:12 2023 +0100
+++ b/rust/landgen/src/wavefront_collapse/wavefront_collapse.rs	Mon Feb 13 12:31:30 2023 +0100
@@ -9,35 +9,6 @@
     Numbered(usize),
 }
 
-impl Tile {
-    fn is(&self, i: usize) -> bool {
-        *self == Tile::Numbered(i)
-    }
-
-    fn is_empty(&self) -> bool {
-        match self {
-            Tile::Empty => true,
-            Tile::Outside => true,
-            _ => false,
-        }
-    }
-
-    fn is_empty_or(&self, i: usize) -> bool {
-        match self {
-            Tile::Numbered(n) => *n == i,
-            Tile::Empty => true,
-            _ => false,
-        }
-    }
-
-    fn is_void_or(&self, i: usize) -> bool {
-        match self {
-            Tile::Numbered(n) => *n == i,
-            _ => true,
-        }
-    }
-}
-
 impl Default for Tile {
     fn default() -> Self {
         Tile::Outside
--- a/rust/lib-hwengine-future/src/lib.rs	Mon Feb 13 11:00:12 2023 +0100
+++ b/rust/lib-hwengine-future/src/lib.rs	Mon Feb 13 12:31:30 2023 +0100
@@ -1,6 +1,11 @@
 use integral_geometry::{Point, Size};
 use land2d;
-use landgen::{outline_template_based::template_based::TemplatedLandGenerator, LandGenerationParameters, LandGenerator};
+use landgen::{
+    outline_template_based::{
+        outline_template::OutlineTemplate, template_based::TemplatedLandGenerator,
+    },
+    LandGenerationParameters, LandGenerator,
+};
 use lfprng::LaggedFibonacciPRNG;
 use mapgen::{theme::Theme, MapGenerator};
 use std::fs;
@@ -59,7 +64,7 @@
     let yaml_templates =
         fs::read_to_string(data_path.join(Path::new("map_templates.yaml")).as_path())
             .expect("Error reading map templates file");
-    let mut map_gen = MapGenerator::new();
+    let mut map_gen = MapGenerator::<OutlineTemplate>::new();
     map_gen.import_yaml_templates(&yaml_templates);
 
     let distance_divisor = feature_size.pow(2) / 8 + 10;
@@ -91,7 +96,7 @@
     let data_path = Path::new(&data_path);
 
     let theme_name: &str = unsafe { CStr::from_ptr(theme_name) }.to_str().unwrap();
-    let map_gen = MapGenerator::new();
+    let map_gen = MapGenerator::<()>::new();
 
     let theme = Theme::load(
         data_path
--- a/rust/mapgen/src/lib.rs	Mon Feb 13 11:00:12 2023 +0100
+++ b/rust/mapgen/src/lib.rs	Mon Feb 13 12:31:30 2023 +0100
@@ -1,79 +1,25 @@
+mod template;
 pub mod theme;
 
 use self::theme::Theme;
+use crate::template::outline::TemplateCollectionDesc as OutlineTemplateCollectionDesc;
+use crate::template::wavefront_collapse::TemplateCollectionDesc as WfcTemplateCollectionDesc;
 use integral_geometry::{Point, Rect, Size};
 use land2d::Land2D;
-use landgen::{outline_template_based::outline_template::OutlineTemplate, LandGenerationParameters};
+use landgen::{
+    outline_template_based::{
+        outline_template::OutlineTemplate, template_based::TemplatedLandGenerator,
+    },
+    wavefront_collapse::generator::{
+        TemplateDescription as WfcTemplate, WavefrontCollapseLandGenerator,
+    },
+    LandGenerationParameters, LandGenerator,
+};
+use rand::{seq::SliceRandom, Rng};
 use serde_derive::Deserialize;
 use serde_yaml;
 use std::{borrow::Borrow, collections::hash_map::HashMap, mem::replace};
 use vec2d::Vec2D;
-use rand::{Rng, seq::SliceRandom};
-
-#[derive(Deserialize)]
-struct PointDesc {
-    x: u32,
-    y: u32,
-}
-
-#[derive(Deserialize)]
-struct RectDesc {
-    x: u32,
-    y: u32,
-    w: u32,
-    h: u32,
-}
-
-#[derive(Deserialize)]
-struct TemplateDesc {
-    width: usize,
-    height: usize,
-    can_flip: bool,
-    can_invert: bool,
-    can_mirror: bool,
-    is_negative: bool,
-    put_girders: bool,
-    max_hedgehogs: u8,
-    outline_points: Vec<Vec<RectDesc>>,
-    fill_points: Vec<PointDesc>,
-}
-
-#[derive(Deserialize)]
-struct TemplateCollectionDesc {
-    templates: Vec<TemplateDesc>,
-    template_types: HashMap<String, Vec<usize>>,
-}
-
-impl From<&TemplateDesc> for OutlineTemplate {
-    fn from(desc: &TemplateDesc) -> Self {
-        OutlineTemplate {
-            islands: desc
-                .outline_points
-                .iter()
-                .map(|v| {
-                    v.iter()
-                        .map(|r| {
-                            Rect::from_size(
-                                Point::new(r.x as i32, r.y as i32),
-                                Size::new(r.w as usize, r.h as usize),
-                            )
-                        })
-                        .collect()
-                })
-                .collect(),
-            fill_points: desc
-                .fill_points
-                .iter()
-                .map(|p| Point::new(p.x as i32, p.y as i32))
-                .collect(),
-            size: Size::new(desc.width, desc.height),
-            can_flip: desc.can_flip,
-            can_invert: desc.can_invert,
-            can_mirror: desc.can_mirror,
-            is_negative: desc.is_negative,
-        }
-    }
-}
 
 #[derive(PartialEq, Eq, Hash, Clone, Debug)]
 struct TemplateType(String);
@@ -85,33 +31,18 @@
 }
 
 #[derive(Debug)]
-pub struct MapGenerator {
-    pub(crate) templates: HashMap<TemplateType, Vec<OutlineTemplate>>,
+pub struct MapGenerator<T> {
+    pub(crate) templates: HashMap<TemplateType, Vec<T>>,
 }
 
-impl MapGenerator {
+impl<T> MapGenerator<T> {
     pub fn new() -> Self {
         Self {
             templates: HashMap::new(),
         }
     }
 
-    pub fn import_yaml_templates(&mut self, text: &str) {
-        let mut desc: TemplateCollectionDesc = serde_yaml::from_str(text).unwrap();
-        let templates = replace(&mut desc.templates, vec![]);
-        self.templates = desc
-            .template_types
-            .into_iter()
-            .map(|(size, indices)| {
-                (
-                    TemplateType(size),
-                    indices.iter().map(|i| (&templates[*i]).into()).collect(),
-                )
-            })
-            .collect();
-    }
-
-    pub fn get_template<R: Rng>(&self, template_type: &str, rng: &mut R) -> Option<&OutlineTemplate> {
+    pub fn get_template<R: Rng>(&self, template_type: &str, rng: &mut R) -> Option<&T> {
         self.templates
             .get(template_type)
             .and_then(|t| t.as_slice().choose(rng))
@@ -190,6 +121,48 @@
     }
 }
 
+impl MapGenerator<OutlineTemplate> {
+    pub fn import_yaml_templates(&mut self, text: &str) {
+        let mut desc: OutlineTemplateCollectionDesc = serde_yaml::from_str(text).unwrap();
+        let templates = replace(&mut desc.templates, vec![]);
+        self.templates = desc
+            .template_types
+            .into_iter()
+            .map(|(size, indices)| {
+                (
+                    TemplateType(size),
+                    indices.iter().map(|i| (&templates[*i]).into()).collect(),
+                )
+            })
+            .collect();
+    }
+
+    pub fn build_generator(&self, template: OutlineTemplate) -> impl LandGenerator {
+        TemplatedLandGenerator::new(template)
+    }
+}
+
+impl MapGenerator<WfcTemplate> {
+    pub fn import_yaml_templates(&mut self, text: &str) {
+        let mut desc: WfcTemplateCollectionDesc = serde_yaml::from_str(text).unwrap();
+        let templates = replace(&mut desc.templates, vec![]);
+        self.templates = desc
+            .template_types
+            .into_iter()
+            .map(|(size, indices)| {
+                (
+                    TemplateType(size),
+                    indices.iter().map(|i| (&templates[*i]).into()).collect(),
+                )
+            })
+            .collect();
+    }
+
+    pub fn build_generator(&self, template: WfcTemplate) -> impl LandGenerator {
+        WavefrontCollapseLandGenerator::new(template)
+    }
+}
+
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
 struct Color(u32);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rust/mapgen/src/template/mod.rs	Mon Feb 13 12:31:30 2023 +0100
@@ -0,0 +1,2 @@
+pub mod outline;
+pub mod wavefront_collapse;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rust/mapgen/src/template/outline.rs	Mon Feb 13 12:31:30 2023 +0100
@@ -0,0 +1,73 @@
+use integral_geometry::{Point, Rect, Size};
+use land2d::Land2D;
+use landgen::{
+    outline_template_based::outline_template::OutlineTemplate, LandGenerationParameters,
+};
+use serde_derive::Deserialize;
+use serde_yaml;
+use std::{borrow::Borrow, collections::hash_map::HashMap, mem::replace};
+
+#[derive(Deserialize)]
+pub struct PointDesc {
+    x: u32,
+    y: u32,
+}
+
+#[derive(Deserialize)]
+pub struct RectDesc {
+    x: u32,
+    y: u32,
+    w: u32,
+    h: u32,
+}
+
+#[derive(Deserialize)]
+pub struct TemplateDesc {
+    width: usize,
+    height: usize,
+    can_flip: bool,
+    can_invert: bool,
+    can_mirror: bool,
+    is_negative: bool,
+    put_girders: bool,
+    max_hedgehogs: u8,
+    outline_points: Vec<Vec<RectDesc>>,
+    fill_points: Vec<PointDesc>,
+}
+
+#[derive(Deserialize)]
+pub struct TemplateCollectionDesc {
+    pub templates: Vec<TemplateDesc>,
+    pub template_types: HashMap<String, Vec<usize>>,
+}
+
+impl From<&TemplateDesc> for OutlineTemplate {
+    fn from(desc: &TemplateDesc) -> Self {
+        OutlineTemplate {
+            islands: desc
+                .outline_points
+                .iter()
+                .map(|v| {
+                    v.iter()
+                        .map(|r| {
+                            Rect::from_size(
+                                Point::new(r.x as i32, r.y as i32),
+                                Size::new(r.w as usize, r.h as usize),
+                            )
+                        })
+                        .collect()
+                })
+                .collect(),
+            fill_points: desc
+                .fill_points
+                .iter()
+                .map(|p| Point::new(p.x as i32, p.y as i32))
+                .collect(),
+            size: Size::new(desc.width, desc.height),
+            can_flip: desc.can_flip,
+            can_invert: desc.can_invert,
+            can_mirror: desc.can_mirror,
+            is_negative: desc.is_negative,
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rust/mapgen/src/template/wavefront_collapse.rs	Mon Feb 13 12:31:30 2023 +0100
@@ -0,0 +1,73 @@
+use integral_geometry::{Point, Rect, Size};
+use land2d::Land2D;
+use landgen::{wavefront_collapse::generator::*, LandGenerationParameters};
+use serde_derive::Deserialize;
+use serde_yaml;
+use std::{borrow::Borrow, collections::hash_map::HashMap, mem::replace};
+
+#[derive(Deserialize)]
+#[serde(remote = "EdgeDescription")]
+pub struct EdgeDesc {
+    pub name: String,
+    pub reversed: Option<bool>,
+    pub symmetrical: Option<bool>,
+}
+
+#[derive(Deserialize)]
+#[serde(remote = "EdgesDescription")]
+pub struct EdgesDesc {
+    #[serde(with = "EdgeDesc")]
+    pub top: EdgeDescription,
+    #[serde(with = "EdgeDesc")]
+    pub right: EdgeDescription,
+    #[serde(with = "EdgeDesc")]
+    pub bottom: EdgeDescription,
+    #[serde(with = "EdgeDesc")]
+    pub left: EdgeDescription,
+}
+
+#[derive(Deserialize)]
+#[serde(remote = "TileDescription")]
+pub struct TileDesc {
+    pub name: String,
+    #[serde(with = "EdgesDesc")]
+    pub edges: EdgesDescription,
+    pub can_flip: bool,
+    pub can_mirror: bool,
+    pub can_rotate90: bool,
+    pub can_rotate180: bool,
+    pub can_rotate270: bool,
+}
+
+#[derive(Deserialize)]
+pub struct TileDescriptionHelper(#[serde(with = "TileDesc")] TileDescription);
+
+#[derive(Deserialize)]
+pub struct TemplateDesc {
+    pub width: usize,
+    pub height: usize,
+    pub can_flip: bool,
+    pub is_negative: bool,
+    pub put_girders: bool,
+    pub max_hedgehogs: u8,
+    pub tiles: Vec<TileDescriptionHelper>,
+}
+
+#[derive(Deserialize)]
+pub struct TemplateCollectionDesc {
+    pub templates: Vec<TemplateDesc>,
+    pub template_types: HashMap<String, Vec<usize>>,
+}
+
+impl From<&TemplateDesc> for TemplateDescription {
+    fn from(desc: &TemplateDesc) -> Self {
+        Self {
+            size: Size::new(desc.width, desc.height),
+            tiles: desc
+                .tiles
+                .iter()
+                .map(|TileDescriptionHelper(t)| t.clone())
+                .collect(),
+        }
+    }
+}