Get node_from, node_to ids from state instead of props when a new link appears.

This is more reliable than assuming the link carries the id of its nodes, as there have been cases where a link was created without those
properties set.
Instead, we can just pull them from the state via the port ids of the link.
This commit is contained in:
Tom A. Wagner
2021-06-04 10:30:31 +02:00
parent a9aec985b0
commit 118c1ca28c
3 changed files with 44 additions and 24 deletions

View File

@@ -6,7 +6,7 @@ use gtk::{
prelude::*,
subclass::prelude::*,
};
use log::{info, warn};
use log::{error, info, warn};
use pipewire::{channel::Sender, spa::Direction};
use crate::{
@@ -127,7 +127,7 @@ impl Application {
name,
direction,
} => app.add_port(id, name, node_id, direction),
PipewireMessage::LinkAdded { id, link } => app.add_link(id, link),
PipewireMessage::LinkAdded { id, port_from, port_to } => app.add_link(id, port_from, port_to),
PipewireMessage::ObjectRemoved { id } => app.remove_global(id),
};
Continue(true)
@@ -196,23 +196,53 @@ impl Application {
}
/// Add a new link to the view.
pub fn add_link(&self, id: u32, link: PipewireLink) {
pub fn add_link(&self, id: u32, port_from: u32, port_to: u32) {
info!("Adding link to graph: id {}", id);
let imp = imp::Application::from_instance(self);
let mut state = imp.state.borrow_mut();
// FIXME: Links should be colored depending on the data they carry (video, audio, midi) like ports are.
imp.state.borrow_mut().insert(
let node_from = *match state.get(port_from) {
Some(Item::Port { node_id }) => node_id,
_ => {
error!(
"Tried to add link (id:{}), but its output port (id:{}) is not known",
id, port_from
);
return;
}
};
let node_to = *match state.get(port_to) {
Some(Item::Port { node_id }) => node_id,
_ => {
error!(
"Tried to add link (id:{}), but its input port (id:{}) is not known",
id, port_to
);
return;
}
};
state.insert(
id,
Item::Link {
output_port: link.port_from,
input_port: link.port_to,
output_port: port_from,
input_port: port_to,
},
);
// Update graph to contain the new link.
imp.graphview.add_link(id, link);
imp.graphview.add_link(
id,
PipewireLink {
node_from,
port_from,
node_to,
port_to,
},
);
}
// Toggle a link between the two specified ports on the remote pipewire server.

View File

@@ -37,7 +37,11 @@ enum PipewireMessage {
direction: Direction,
},
/// A new link has appeared.
LinkAdded { id: u32, link: PipewireLink },
LinkAdded {
id: u32,
port_from: u32,
port_to: u32,
},
/// An object was removed
ObjectRemoved { id: u32 },
}

View File

@@ -147,21 +147,11 @@ fn handle_link(link: &GlobalObject<ForeignDict>, sender: &glib::Sender<PipewireM
.props
.as_ref()
.expect("Link object is missing properties");
let node_from: u32 = props
.get("link.output.node")
.expect("Link has no link.input.node property")
.parse()
.expect("Could not parse link.input.node property");
let port_from: u32 = props
.get("link.output.port")
.expect("Link has no link.output.port property")
.parse()
.expect("Could not parse link.output.port property");
let node_to: u32 = props
.get("link.input.node")
.expect("Link has no link.input.node property")
.parse()
.expect("Could not parse link.input.node property");
let port_to: u32 = props
.get("link.input.port")
.expect("Link has no link.input.port property")
@@ -171,12 +161,8 @@ fn handle_link(link: &GlobalObject<ForeignDict>, sender: &glib::Sender<PipewireM
sender
.send(PipewireMessage::LinkAdded {
id: link.id,
link: crate::PipewireLink {
node_from,
port_from,
node_to,
port_to,
},
})
.expect("Failed to send message");
}