Add port to virtual device

This commit is contained in:
hodasemi 2022-01-31 12:13:58 +01:00
parent ad11a23c9e
commit 08c90d34d3
5 changed files with 126 additions and 8 deletions

View file

@ -155,7 +155,7 @@ impl Device {
None => Vec::new(),
};
let outputs = Self::flatten(
let outputs = flatten(
self.supported_events
.iter()
.map(|(event_type, kinds)| {
@ -219,8 +219,8 @@ impl Device {
}
}
fn flatten<T>(vv: Vec<Vec<T>>) -> Vec<T> {
vv.into_iter().flatten().collect()
pub fn events(&self) -> &HashMap<EventType, Vec<EventCode>> {
&self.supported_events
}
}

View file

@ -679,3 +679,7 @@ pub fn code_to_string(code: &EventCode) -> String {
_ => panic!(),
}
}
pub fn flatten<T>(vv: Vec<Vec<T>>) -> Vec<T> {
vv.into_iter().flatten().collect()
}

View file

@ -56,7 +56,7 @@ pub fn draw_graph_editor(
}
node_finder_area.show(ctx, |ui| {
// don't allow a nodes to be duplicated
let devs: Vec<&Device> = devices
let missing_devices: Vec<&Device> = devices
.iter()
.filter(|device| {
let mut allow = true;
@ -72,7 +72,29 @@ pub fn draw_graph_editor(
})
.collect();
if let Some(node_device) = node_finder.show(&devs, virtual_device.is_none(), ui) {
if let Some(mut node_device) =
node_finder.show(&missing_devices, virtual_device.is_none(), ui)
{
if let SelectedDevice::Virtual(virt) = &mut node_device {
let existing_devices: Vec<&Device> = devices
.iter()
.filter(|device| {
let mut exists = false;
for (_node_id, node) in state.graph.nodes.iter() {
if node.op_name == device.name() {
exists = true;
break;
}
}
exists
})
.collect();
virt.build_ports(&existing_devices);
}
let new_node = state.graph.add_node(node_device.to_descriptor());
state
.node_positions

View file

@ -58,6 +58,7 @@ impl NodeFinder {
// The archetype that will be returned.
let mut submitted_device = None;
frame.show(ui, |ui| {
ui.set_width(250.0);
ui.vertical(|ui| {
Frame::default().margin(vec2(10.0, 10.0)).show(ui, |ui| {
if allow_virt_dev {

View file

@ -1,8 +1,20 @@
use crate::{graph_types::NodeDescriptor, id_types::NodeId};
use std::collections::{HashMap, HashSet};
use evdev_rs::enums::{EventCode, EventType};
use crate::{
device::Device,
event_code_iters::{code_to_string, flatten},
graph_types::{Descriptor, NodeDescriptor},
id_types::NodeId,
};
pub struct VirtualDevice {
name: String,
node_id: Option<NodeId>,
inputs: HashMap<EventType, Vec<EventCode>>,
outputs: HashMap<EventType, Vec<EventCode>>,
}
impl VirtualDevice {
@ -10,6 +22,9 @@ impl VirtualDevice {
Self {
name: name.to_string(),
node_id: None,
inputs: HashMap::new(),
outputs: HashMap::new(),
}
}
@ -17,6 +32,62 @@ impl VirtualDevice {
self.node_id = Some(node_id);
}
pub fn build_ports(&mut self, devices: &[&Device]) {
let mut inputs: HashMap<EventType, HashSet<EventCode>> = HashMap::new();
let mut outputs: HashMap<EventType, HashSet<EventCode>> = HashMap::new();
for device in devices {
for (event_type, new_codes) in device.events() {
match event_type {
EventType::EV_KEY | EventType::EV_REL | EventType::EV_ABS => {
match inputs.get_mut(event_type) {
Some(codes) => {
for code in new_codes {
codes.insert(*code);
}
}
None => {
let mut codes = HashSet::new();
for code in new_codes {
codes.insert(*code);
}
inputs.insert(*event_type, codes);
}
}
}
EventType::EV_FF => match outputs.get_mut(event_type) {
Some(codes) => {
for code in new_codes {
codes.insert(*code);
}
}
None => {
let mut codes = HashSet::new();
for code in new_codes {
codes.insert(*code);
}
outputs.insert(*event_type, codes);
}
},
_ => (),
}
}
}
for (event_type, codes) in inputs {
self.inputs.insert(event_type, codes.into_iter().collect());
}
for (event_type, codes) in outputs {
self.outputs.insert(event_type, codes.into_iter().collect());
}
}
pub fn node_id(&self) -> NodeId {
self.node_id.unwrap()
}
@ -24,8 +95,28 @@ impl VirtualDevice {
pub fn to_descriptor(&self) -> NodeDescriptor {
NodeDescriptor {
op_name: self.name.clone(),
inputs: Vec::new(),
outputs: Vec::new(),
inputs: flatten(
self.inputs
.iter()
.map(|(_event_type, codes)| {
codes
.iter()
.map(|code| (code_to_string(code), Descriptor::Button))
.collect::<Vec<(String, Descriptor)>>()
})
.collect::<Vec<Vec<(String, Descriptor)>>>(),
),
outputs: flatten(
self.outputs
.iter()
.map(|(_event_type, codes)| {
codes
.iter()
.map(|code| (code_to_string(code), Descriptor::Button))
.collect::<Vec<(String, Descriptor)>>()
})
.collect::<Vec<Vec<(String, Descriptor)>>>(),
),
}
}
}