use super::{Message, ResultMessage}; use std::collections::{HashMap, HashSet}; use std::sync::mpsc::{channel, Receiver, Sender}; use std::thread::JoinHandle; struct InBuffer { receiver: Receiver, row_requests: HashMap>>, results_requests: HashMap, } impl InBuffer { fn new(receiver: Receiver) -> Self { Self { receiver, row_requests: HashMap::new(), results_requests: HashMap::new(), } } fn read(&mut self) -> Option> { loop { match self .receiver .recv() .expect("Channel to Output Daemon broke") { Message::ResultMessage(results) => { if let Some(result_walls) = self.row_requests.get(&results.id) { return Some(Self::calc_results(results.valid_walls(), result_walls)); } else { self.results_requests.insert(results.id, results); } } Message::OutputMessage((id, output)) => { if let Some(results) = self.results_requests.get(&id) { return Some(Self::calc_results(results.valid_walls(), output.as_ref())); } else { self.row_requests.insert(id, output); } } Message::Terminate => { return None; } _ => { println!("Invalid MessageType"); } } } } fn calc_results(res_req: &[Vec], row_req: &[Vec]) -> Vec { let out = Vec::new(); for (rows, perms) in row_req.iter().zip(res_req.iter()) { for p in perms { let new = rows.clone(); new.push(*p); out.push(RowResult::new(new)); } } out } } #[derive(PartialEq, Eq, Hash)] pub struct RowResult { rows: Vec, } impl RowResult { fn new(rows: Vec) -> Self { rows.push(0); Self { rows } } fn output(&self) { println!("{:?}", self.rows); } } pub struct Output { input: InBuffer, permutations: Vec>, permutations_mask: Vec, results: HashSet, } impl Output { pub fn launch_sevice( permutations: &[Vec], permutations_mask: &[u64], ) -> (Sender, JoinHandle<()>) { let (sender, receiver) = channel(); let input = InBuffer::new(receiver); let output = Self { input, permutations: permutations.into(), permutations_mask: permutations_mask.into(), results: HashSet::new(), }; ( sender, std::thread::Builder::new() .name("GPU Manager Deamon".into()) .spawn(move || { output.run(); }) .unwrap(), ) } fn run(mut self) { loop { if let Some(walls) = self.input.read() { for wall in walls { self.results.insert(wall); } } else { for wall in self.results { wall.output() } } } } }