thedes_gen/map/layer/
pointwise.rs1use 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}