use std::collections::BTreeMap;
use egui::{Pos2, Vec2};
use re_chunk::EntityPath;
use crate::graph::{EdgeId, Graph, NodeId};
#[derive(PartialEq)]
pub(super) struct NodeTemplate {
pub(super) size: Vec2,
pub(super) fixed_position: Option<Pos2>,
}
#[derive(Clone, PartialEq, Eq)]
pub struct EdgeTemplate {
pub source: NodeId,
pub target: NodeId,
pub target_arrow: bool,
}
#[derive(Default, PartialEq)]
pub(super) struct GraphTemplate {
pub(super) nodes: BTreeMap<NodeId, NodeTemplate>,
pub(super) edges: BTreeMap<EdgeId, Vec<EdgeTemplate>>,
}
#[derive(PartialEq)]
pub struct LayoutRequest {
pub(super) graphs: BTreeMap<EntityPath, GraphTemplate>,
}
impl LayoutRequest {
pub fn from_graphs<'a>(graphs: impl IntoIterator<Item = &'a Graph>) -> Self {
let mut request = Self {
graphs: BTreeMap::new(),
};
for graph in graphs {
let entity = request.graphs.entry(graph.entity().clone()).or_default();
for node in graph.nodes() {
let shape = NodeTemplate {
size: node.size(),
fixed_position: node.position(),
};
let duplicate = entity.nodes.insert(node.id(), shape);
debug_assert!(
duplicate.is_none(),
"duplicated nodes are undefined behavior"
);
}
for edge in graph.edges() {
let id = EdgeId {
source: edge.source,
target: edge.target,
};
let es = entity.edges.entry(id).or_default();
es.push(edge.clone());
}
}
request
}
pub(super) fn all_nodes(&self) -> impl Iterator<Item = (NodeId, &NodeTemplate)> + '_ {
self.graphs
.iter()
.flat_map(|(_, graph)| graph.nodes.iter().map(|(k, v)| (*k, v)))
}
pub(super) fn all_edges(&self) -> impl Iterator<Item = (EdgeId, &[EdgeTemplate])> + '_ {
self.graphs
.iter()
.flat_map(|(_, graph)| graph.edges.iter().map(|(k, v)| (*k, v.as_slice())))
}
}