proto_lab/
network_simulator.rs1use std::{
2 cell::RefCell,
3 ops::DerefMut,
4 sync::{Arc, Mutex},
5};
6
7use crate::EtherSimulator;
8
9pub struct NetworkSimulator {
10 ethers: RefCell<Option<Vec<EtherSimulator>>>,
11 ms_per_tick: u64,
12 simulation_thread_handle: Option<std::thread::JoinHandle<Vec<EtherSimulator>>>,
13 thread_killer: Arc<Mutex<bool>>,
14}
15
16impl NetworkSimulator {
19 pub fn new(ms_per_tick: u64) -> Self {
20 NetworkSimulator {
21 ethers: RefCell::new(Some(Vec::new())),
22 ms_per_tick,
23 simulation_thread_handle: None,
24 thread_killer: Arc::new(Mutex::new(false)),
25 }
26 }
27
28 pub fn create_ether(&self, name: &str) {
29 match self.ethers.borrow_mut().deref_mut() {
30 Some(ref mut ethers) => {
31 let new_ether = EtherSimulator::new(name);
32 ethers.push(new_ether);
33 }
34 None => {
35 panic!("Simulation thread is already started. Can not change configuration")
36 }
37 };
38 }
39
40 pub fn get_ether(&self, name: &str) -> Option<EtherSimulator> {
41 match self.ethers.borrow_mut().deref_mut() {
42 None => panic!("Simulation thread is started. Can not get ether"),
43 Some(ref ethers) => {
44 for ether in ethers.iter() {
45 if ether.get_name() == name {
46 return Some(ether.clone());
47 }
48 }
49 None
50 }
51 }
52 }
53
54 pub fn start_tick(&self) {
55 match self.ethers.borrow_mut().deref_mut() {
56 None => panic!(
57 "Simulation thread is started. Can not do start_tick and thread at the same time"
58 ),
59 Some(ref ethers) => {
60 for ether in ethers.iter() {
61 ether.start_tick();
62 }
63 }
64 }
65 }
66
67 pub fn end_tick(&self) {
68 match self.ethers.borrow_mut().deref_mut() {
69 None => panic!(
70 "Simulation thread is started. Can not do start_tick and thread at the same time"
71 ),
72 Some(ref ethers) => {
73 for ether in ethers.iter() {
74 ether.end_tick();
75 }
76 }
77 }
78 }
79
80 pub fn simulate(&self) {
81 match self.ethers.borrow_mut().deref_mut() {
82 None => panic!(
83 "Simulation thread is started. Can not do start_tick and thread at the same time"
84 ),
85 Some(ref mut ethers) => {
86 for ether in ethers.iter_mut() {
87 ether.simulate();
88 }
89 }
90 }
91 }
92
93 pub fn start_simulation_thread(&mut self) {
94 match self.simulation_thread_handle {
95 Some(_) => panic!("Simulation thread is already started"),
96 None => {
97 let mut ethers = self.ethers.take().unwrap();
98
99 let ms_per_tick = self.ms_per_tick;
100 let thread_killer_clone = Arc::clone(&self.thread_killer);
101
102 *self
103 .thread_killer
104 .lock()
105 .expect("Fail to get lock on thread killer") = false;
106
107 self.simulation_thread_handle = Some(std::thread::spawn(move || {
108 loop {
109 if *thread_killer_clone
110 .lock()
111 .expect("Faild to get lock on clonned thread killer")
112 {
113 break;
114 }
115 std::thread::sleep(std::time::Duration::from_millis(ms_per_tick));
116 for ether in ethers.iter_mut() {
117 ether.start_tick();
118 }
119 for ether in ethers.iter_mut() {
120 ether.simulate();
121 }
122 for ether in ethers.iter_mut() {
123 ether.end_tick();
124 }
125 }
126 ethers
127 }));
128 }
129 }
130 }
131
132 pub fn stop_simulation_thread(&mut self) {
133 self.simulation_thread_handle = match self.simulation_thread_handle.take() {
134 None => panic!("Simulation thread is not started"),
135 Some(simulation_thread_handle) => {
136 *self
137 .thread_killer
138 .lock()
139 .expect("Fail to get lock on thread killer") = true;
140 self.ethers.replace(Some(
141 simulation_thread_handle
142 .join()
143 .expect(" Fail to join simulation thread to get ethers back"),
144 ));
145 None
146 }
147 };
148 }
149}