blob: 4916f759a4638ac3264d4f2d384b088c6a0ebfb2 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
use anyhow::Result;
use std::sync::Arc;
use tokio::sync::RwLock;
use resiter::Map;
use crate::util::*;
use crate::backend::sim::*;
use crate::backend::rain::*;
pub struct Landscape {
elements: Vec<Arc<RwLock<LandscapeElement>>>,
}
impl Landscape {
pub fn new(elements: Vec<usize>) -> Self {
let elements = elements
.into_iter()
.map(LandscapeElement::new)
.map(RwLock::new)
.map(Arc::new)
.collect();
Landscape { elements }
}
// here is where the fun is
pub async fn let_it_rain(self, hours: usize) -> Result<RainyLandscape> {
use futures::StreamExt;
self.prepare_element_simulation()
.await?
.into_iter()
.map(|el| el.let_it_rain(hours))
.collect::<futures::stream::FuturesUnordered<_>>()
.collect::<Vec<_>>()
.await
.into_iter()
.map_ok(ElementRainingSimulation::into_landscape_element)
.collect::<Result<Vec<_>>>()
.map(RainyLandscape::new)
}
async fn prepare_element_simulation(&self) -> Result<Vec<ElementRainingSimulation>> {
let mut simulation_elements = self.elements
.iter()
.map(Arc::clone)
.map(ElementRainingSimulation::new)
.collect::<Vec<_>>();
if simulation_elements.len() >= 3 {
log::debug!("Having three or more landscape elements in the simulation, pairing them now");
let mut windows = ThreeElemWindowMut::new(&mut simulation_elements);
while let Some(mut window) = windows.next() {
// we know from the ThreeElemWindowMut impl that 'window' always has three elements
let el = window[0].element().clone();
window[1].set_left_neighbor(Some(el));
let el = window[1].element().clone();
window[0].set_right_neighbor(Some(el));
let el = window[2].element().clone();
window[1].set_right_neighbor(Some(el));
let el = window[1].element().clone();
window[2].set_left_neighbor(Some(el));
}
} else if simulation_elements.len() == 2 {
log::debug!("Having only two landscape elements in the simulation, pairing them now");
let el = simulation_elements[1].element().clone();
simulation_elements[0].set_right_neighbor(Some(el));
let el = simulation_elements[0].element().clone();
simulation_elements[1].set_left_neighbor(Some(el));
}
Ok(simulation_elements)
}
}
#[derive(getset::Setters, getset::Getters)]
pub struct LandscapeElement {
#[getset(get = "pub")]
height: usize,
#[getset(get = "pub")]
rain_elements: Vec<RainElement>,
}
impl LandscapeElement {
fn new(height: usize) -> Self {
LandscapeElement {
height,
rain_elements: Vec::new(),
}
}
pub fn get_current_height(&self) -> f32 {
let rain: f32 = self.rain_elements.iter().map(|e| e.as_f32()).sum();
(self.height as f32) + rain
}
pub fn increase_rain_level(&mut self, el: RainElement) {
self.rain_elements.push(el);
}
}
#[derive(getset::Getters)]
pub struct RainyLandscape {
#[getset(get = "pub")]
elements: Vec<Arc<RwLock<LandscapeElement>>>
}
impl RainyLandscape {
fn new(elements: Vec<Arc<RwLock<LandscapeElement>>>) -> Self {
RainyLandscape { elements }
}
}
|