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}