gol_core/board/
board.rs

1use crate::{
2    BoardCallbackManager, BoardNeighborManager, BoardSpaceManager, BoardStateManager,
3    BoardStrategyManager, IndexedDataOwned,
4};
5
6use rayon::prelude::*;
7pub trait Board<T, CI, I>: Send + Sync
8where
9    T: 'static + Send + Sync + Clone,
10    CI: 'static + Send + Sync + Clone,
11    I: Iterator<Item = CI>,
12{
13    fn space_manager(&self) -> &dyn BoardSpaceManager<CI, I, rayon::vec::IntoIter<CI>>;
14    fn neighbor_manager(&self) -> &dyn BoardNeighborManager<CI, I>;
15
16    fn state_manager(
17        &self,
18    ) -> &dyn BoardStateManager<T, CI, rayon::vec::IntoIter<IndexedDataOwned<CI, T>>>;
19
20    fn state_manager_mut(
21        &mut self,
22    ) -> &mut dyn BoardStateManager<T, CI, rayon::vec::IntoIter<IndexedDataOwned<CI, T>>>;
23
24    fn strategy_manager(
25        &self,
26    ) -> &dyn BoardStrategyManager<CI, T, std::vec::IntoIter<IndexedDataOwned<CI, T>>>;
27
28    fn callback_manager(
29        &mut self,
30    ) -> &mut BoardCallbackManager<T, CI, rayon::vec::IntoIter<IndexedDataOwned<CI, T>>>;
31
32    fn advance(&mut self, max_iter: Option<usize>) {
33        let mut cur_iter = 0usize;
34        let state_manager = self.state_manager();
35        let cur_states = self
36            .space_manager()
37            .indices_par_iter()
38            .map(|idx| (idx.clone(), state_manager.get_cell_state(&idx)))
39            .collect();
40
41        self.callback_manager().setup_all();
42        self.callback_manager().call(cur_states);
43
44        loop {
45            let next_states = self.advance_one_generation();
46
47            self.callback_manager().call(next_states);
48
49            cur_iter += 1;
50            match max_iter {
51                Some(val) => {
52                    if cur_iter >= val - 1 {
53                        break;
54                    }
55                }
56                None => continue,
57            }
58        }
59        self.callback_manager().cleanup_all();
60    }
61
62    fn advance_one_generation(&mut self) -> Vec<IndexedDataOwned<CI, T>> {
63        let states = self.state_manager();
64        let strat = self.strategy_manager();
65        let neighbor_manager = self.neighbor_manager();
66
67        let next_states: Vec<IndexedDataOwned<CI, T>> = self
68            .space_manager()
69            .indices_par_iter()
70            .map(|idx| {
71                let cur_state = states.get_cell_state(&idx.clone());
72                let neighbors: Vec<IndexedDataOwned<CI, T>> = neighbor_manager
73                    .get_neighbors_idx(&idx)
74                    .map(|neighbor_idx| (idx.clone(), states.get_cell_state(&neighbor_idx)))
75                    .collect();
76                (
77                    idx.clone(),
78                    strat.get_strategy_at_index(idx.clone()).next_state(
79                        idx,
80                        cur_state,
81                        neighbors.into_iter(),
82                    ),
83                )
84            })
85            .collect();
86
87        self.state_manager_mut()
88            .update_cell_states_from_par_iter(next_states.clone().into_par_iter());
89        next_states
90    }
91}