Improved code

This commit is contained in:
Andre Henriques 2023-05-08 08:52:03 +01:00
parent 6539a59129
commit ecb7ea9f11

View File

@ -1,6 +1,4 @@
use std::{cell::RefCell, env, fs, io::BufRead, collections::HashMap}; use std::{cell::{RefMut, RefCell}, rc::Rc, fs, vec::Vec, env, io::BufRead, collections::HashMap};
use std::vec::Vec;
use std::{cell::RefMut, rc::Rc};
use libspa::ReadableDict; use libspa::ReadableDict;
use pipewire::{types::ObjectType, Context, MainLoop}; use pipewire::{types::ObjectType, Context, MainLoop};
@ -40,6 +38,24 @@ struct LinkDef {
port_out: Rc<PortDef>, port_out: Rc<PortDef>,
} }
#[derive(Debug)]
struct Pair {
node: String,
port: String,
}
impl PortDef {
fn is_pair(&self, pair: &Pair) -> bool {
self.name.eq(&pair.port) && self.node.name.eq(&pair.node)
}
fn to_pair(&self) -> Pair {
Pair {
node: self.node.name.to_string(),
port: self.name.to_string()
}
}
}
struct AppState { struct AppState {
ports: Vec<Rc<Port>>, ports: Vec<Rc<Port>>,
nodes: Vec<Rc<Node>>, nodes: Vec<Rc<Node>>,
@ -105,8 +121,8 @@ impl AppState {
search(&self.nodes, |a| a.id == id) search(&self.nodes, |a| a.id == id)
} }
fn get_port_by_name(&self, name: String) -> Option<Rc<Port>> { fn get_port_by_pair(&self, pair: &Pair) -> Option<Rc<Port>> {
search(&self.ports, |a| a.name.eq(&name)) search(&self.ports, |a| a.name.eq(&pair.port) && a.node.name.eq(&pair.node))
} }
fn try_add_port(&mut self, id: u32, name: String, node_id: u32) -> bool { fn try_add_port(&mut self, id: u32, name: String, node_id: u32) -> bool {
@ -145,7 +161,7 @@ impl AppState {
true true
} }
fn create_links(&mut self, port_name: String, core: Rc<pw::Core>) { fn create_links(&mut self, pair: Pair, core: Rc<pw::Core>) {
#[derive(Debug)] #[derive(Debug)]
struct TempLink { struct TempLink {
port_in: Option<Rc<Port>>, port_in: Option<Rc<Port>>,
@ -154,10 +170,10 @@ impl AppState {
self.link_def self.link_def
.iter() .iter()
.filter(|link| (link.port_in.name.eq(&port_name) || link.port_out.name.eq(&port_name))) .filter(|link| (link.port_in.is_pair(&pair) || link.port_out.is_pair(&pair)))
.map(|a| TempLink { .map(|a| TempLink {
port_in: self.get_port_by_name(a.port_in.name.to_string()), port_in: self.get_port_by_pair(&a.port_in.to_pair()),
port_out: self.get_port_by_name(a.port_out.name.to_string()), port_out: self.get_port_by_pair(&a.port_out.to_pair()),
}).filter(|a| a.port_in.is_some() && a.port_out.is_some()).for_each(|a| { }).filter(|a| a.port_in.is_some() && a.port_out.is_some()).for_each(|a| {
let port_in = a.port_in.unwrap(); let port_in = a.port_in.unwrap();
let port_out = a.port_out.unwrap(); let port_out = a.port_out.unwrap();
@ -226,12 +242,13 @@ fn deal_with_port(
if let (Some(name), Some(node_id)) = (props.get("port.name"), props.get("node.id")) { if let (Some(name), Some(node_id)) = (props.get("port.name"), props.get("node.id")) {
if let Ok(node_id) = node_id.parse::<u32>() { if let Ok(node_id) = node_id.parse::<u32>() {
if state.try_add_port(port.id, name.to_string(), node_id) { if state.try_add_port(port.id, name.to_string(), node_id) {
let node_name = state.get_node(node_id).unwrap().name.to_string();
println!( println!(
"Got port {} for {}", "Got port {} for {}",
name, name,
state.get_node(node_id).unwrap().name node_name
); );
state.create_links(name.to_string(), core) state.create_links(Pair {node: node_name.to_string(), port: name.to_string() }, core)
} }
} else { } else {
println!("Clould not parse {}'s node.id({})", name, node_id) println!("Clould not parse {}'s node.id({})", name, node_id)
@ -284,20 +301,24 @@ fn parse_file(path: std::path::PathBuf, get_names: bool) -> Result<AppState, Box
}, },
}; };
let port_out = match port_def.get_mut(&caps["port_out"]) { let port_out_store = format!("{} {}", &caps["node_out"], &caps["port_out"]);
let port_out = match port_def.get_mut(&port_out_store) {
Some(port) => port.to_owned(), Some(port) => port.to_owned(),
None => { None => {
let port = Rc::new(PortDef { node: node_out.clone(), name: caps["port_out"].to_string() } ); let port = Rc::new(PortDef { node: node_out.clone(), name: caps["port_out"].to_string() } );
port_def.insert(caps["port_out"].to_string(), port.clone()); port_def.insert(port_out_store, port.clone());
port port
}, },
}; };
let port_in = match port_def.get_mut(&caps["port_in"]) { let port_in_store = format!("{} {}", &caps["node_in"], &caps["port_in"]);
let port_in = match port_def.get_mut(&port_in_store) {
Some(port) => port.to_owned(), Some(port) => port.to_owned(),
None => { None => {
let port = Rc::new(PortDef { node: node_in.clone(), name: caps["port_in"].to_string() } ); let port = Rc::new(PortDef { node: node_in.clone(), name: caps["port_in"].to_string() } );
port_def.insert(caps["port_in"].to_string(), port.clone()); port_def.insert(port_in_store, port.clone());
port port
}, },
}; };
@ -305,7 +326,7 @@ fn parse_file(path: std::path::PathBuf, get_names: bool) -> Result<AppState, Box
let link = Rc::new(LinkDef { port_out: port_out.clone(), port_in: port_in.clone() }); let link = Rc::new(LinkDef { port_out: port_out.clone(), port_in: port_in.clone() });
link_def.push(link) link_def.push(link)
} else if !line.starts_with('#') { } else if !line.starts_with('#') && !line.is_empty() {
println!("invalid line: {}", line); println!("invalid line: {}", line);
} }
} }
@ -313,6 +334,9 @@ fn parse_file(path: std::path::PathBuf, get_names: bool) -> Result<AppState, Box
let node_def = node_def.values().cloned().collect::<Vec<Rc<NodeDef>>>(); let node_def = node_def.values().cloned().collect::<Vec<Rc<NodeDef>>>();
let port_def = port_def.values().cloned().collect::<Vec<Rc<PortDef>>>(); let port_def = port_def.values().cloned().collect::<Vec<Rc<PortDef>>>();
println!("node_def {:?}", node_def);
println!("port_def {:?}", port_def);
Ok(AppState::new(node_def, link_def, port_def, get_names)) Ok(AppState::new(node_def, link_def, port_def, get_names))
} }