thedes_gen/map/layer/
pointwise.rs

1use thedes_async_util::progress;
2use thedes_domain::{geometry::CoordPair, map::Map};
3use thiserror::Error;
4use tokio::task;
5
6use crate::random::PickedReproducibleRng;
7
8use super::{Layer, LayerDistribution};
9
10#[derive(Debug, Error)]
11pub enum Error<L, Ld>
12where
13    L: std::error::Error,
14    Ld: std::error::Error,
15{
16    #[error("Failed to manipulate layer")]
17    Layer(#[source] L),
18    #[error("Failed to manipulate layer distribution")]
19    LayerDistribution(#[source] Ld),
20}
21
22#[derive(Debug)]
23pub struct Generator {
24    _priv: (),
25}
26
27impl Generator {
28    pub fn new() -> Self {
29        Self { _priv: () }
30    }
31
32    pub fn progress_goal(&self, map: &Map) -> usize {
33        map.rect().map(usize::from).total_area()
34    }
35
36    pub async fn execute<L, Ld>(
37        self,
38        layer: &L,
39        layer_distr: &Ld,
40        map: &mut Map,
41        rng: &mut PickedReproducibleRng,
42        progress_logger: progress::Logger,
43    ) -> Result<(), Error<L::Error, Ld::Error>>
44    where
45        L: Layer,
46        L::Error: std::error::Error,
47        Ld: LayerDistribution<Data = L::Data>,
48        Ld::Error: std::error::Error,
49    {
50        progress_logger.set_status("generating point block");
51
52        let map_rect = map.rect();
53        for y in map_rect.top_left.y .. map_rect.bottom_right().y {
54            for x in map_rect.top_left.x .. map_rect.bottom_right().x {
55                let point = CoordPair { y, x };
56                let data = layer_distr
57                    .sample(map, point, &mut *rng)
58                    .map_err(Error::LayerDistribution)?;
59                layer.set(map, point, data).map_err(Error::Layer)?;
60                progress_logger.increment();
61                task::yield_now().await;
62            }
63        }
64
65        progress_logger.set_status("done");
66        Ok(())
67    }
68}