Skip to content

Commit

Permalink
Make graphs generic over index size (#103)
Browse files Browse the repository at this point in the history
- piped Ix params through code
- all examples work
- no clippy warnings related to the change

---------

Co-authored-by: starlord <[email protected]>
  • Loading branch information
dmyyy and blitzarx1 authored Nov 7, 2023
1 parent c9e3ae5 commit 0e770f5
Show file tree
Hide file tree
Showing 13 changed files with 174 additions and 128 deletions.
7 changes: 5 additions & 2 deletions examples/basic/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use eframe::{run_native, App, CreationContext};
use egui::Context;
use egui_graphs::{Graph, GraphView};
use petgraph::{stable_graph::StableGraph, Directed};
use petgraph::{
stable_graph::{DefaultIx, StableGraph},
Directed,
};

pub struct BasicApp {
g: Graph<(), (), Directed>,
g: Graph<(), (), Directed, DefaultIx>,
}

impl BasicApp {
Expand Down
15 changes: 9 additions & 6 deletions examples/configurable/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use egui_graphs::events::Event;
use egui_graphs::{to_graph, Edge, Graph, GraphView, Node};
use fdg_sim::glam::Vec3;
use fdg_sim::{ForceGraph, ForceGraphHelper, Simulation, SimulationParameters};
use petgraph::stable_graph::{EdgeIndex, NodeIndex, StableGraph};
use petgraph::stable_graph::{DefaultIx, EdgeIndex, NodeIndex, StableGraph};
use petgraph::visit::EdgeRef;
use petgraph::Directed;
use rand::Rng;
Expand All @@ -19,7 +19,7 @@ const SIMULATION_DT: f32 = 0.035;
const EVENTS_LIMIT: usize = 100;

pub struct ConfigurableApp {
g: Graph<(), (), Directed>,
g: Graph<(), (), Directed, DefaultIx>,
sim: Simulation<(), f32>,

settings_graph: SettingsGraph,
Expand Down Expand Up @@ -168,7 +168,7 @@ impl ConfigurableApp {
self.settings_graph = settings_graph;
self.last_events = Default::default();

GraphView::<(), (), Directed>::reset_metadata(ui);
GraphView::<(), (), Directed, DefaultIx>::reset_metadata(ui);
}

fn handle_events(&mut self) {
Expand Down Expand Up @@ -552,14 +552,14 @@ impl App for ConfigurableApp {
}
}

fn generate(settings: &SettingsGraph) -> (Graph<(), (), Directed>, Simulation<(), f32>) {
fn generate(settings: &SettingsGraph) -> (Graph<(), (), Directed, DefaultIx>, Simulation<(), f32>) {
let g = generate_random_graph(settings.count_node, settings.count_edge);
let sim = construct_simulation(&g);

(g, sim)
}

fn construct_simulation(g: &Graph<(), (), Directed>) -> Simulation<(), f32> {
fn construct_simulation(g: &Graph<(), (), Directed, DefaultIx>) -> Simulation<(), f32> {
// create force graph
let mut force_graph = ForceGraph::with_capacity(g.g.node_count(), g.g.edge_count());
g.g.node_indices().for_each(|idx| {
Expand All @@ -579,7 +579,10 @@ fn construct_simulation(g: &Graph<(), (), Directed>) -> Simulation<(), f32> {
Simulation::from_graph(force_graph, params)
}

fn generate_random_graph(node_count: usize, edge_count: usize) -> Graph<(), (), Directed> {
fn generate_random_graph(
node_count: usize,
edge_count: usize,
) -> Graph<(), (), Directed, DefaultIx> {
let mut rng = rand::thread_rng();
let mut graph = StableGraph::new();

Expand Down
11 changes: 6 additions & 5 deletions examples/custom_draw/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
use eframe::{run_native, App, CreationContext};
use egui::{
epaint::TextShape, Context, FontFamily, FontId, Rect, Rounding, Shape, Stroke, Vec2,
};
use egui::{epaint::TextShape, Context, FontFamily, FontId, Rect, Rounding, Shape, Stroke, Vec2};
use egui_graphs::{default_edges_draw, Graph, GraphView, SettingsInteraction};
use petgraph::{stable_graph::StableGraph, Directed};
use petgraph::{
stable_graph::{DefaultIx, StableGraph},
Directed,
};

pub struct BasicApp {
g: Graph<(), (), Directed>,
g: Graph<(), (), Directed, DefaultIx>,
}

impl BasicApp {
Expand Down
9 changes: 6 additions & 3 deletions examples/interactive/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
use eframe::{run_native, App, CreationContext};
use egui::Context;
use egui_graphs::{Graph, GraphView, SettingsInteraction, SettingsStyle};
use petgraph::{stable_graph::StableGraph, Directed};
use petgraph::{
stable_graph::{DefaultIx, StableGraph},
Directed,
};

pub struct BasicInteractiveApp {
g: Graph<(), (), Directed>,
g: Graph<(), (), Directed, DefaultIx>,
}

impl BasicInteractiveApp {
Expand Down Expand Up @@ -32,7 +35,7 @@ impl App for BasicInteractiveApp {
}
}

fn generate_graph() -> Graph<(), (), Directed> {
fn generate_graph() -> Graph<(), (), Directed, DefaultIx> {
let mut g: StableGraph<(), ()> = StableGraph::new();

let a = g.add_node(());
Expand Down
4 changes: 2 additions & 2 deletions examples/undirected/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ use eframe::{run_native, App, CreationContext};
use egui::Context;
use egui_graphs::{Graph, GraphView};
use petgraph::{
stable_graph::{StableGraph, StableUnGraph},
stable_graph::{DefaultIx, StableGraph, StableUnGraph},
Undirected,
};

pub struct BasicUndirectedApp {
g: Graph<(), (), Undirected>,
g: Graph<(), (), Undirected, DefaultIx>,
}

impl BasicUndirectedApp {
Expand Down
21 changes: 14 additions & 7 deletions src/computed.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
use egui::{Rect, Vec2};
use petgraph::graph::IndexType;
use petgraph::{stable_graph::NodeIndex, EdgeType};

use crate::{Graph, Node, SettingsStyle};

/// The struct stores selections, dragged node and computed elements states.
#[derive(Debug, Clone)]
pub struct ComputedState {
pub dragged: Option<NodeIndex>,
pub selected: Vec<NodeIndex>,
pub struct ComputedState<Ix: IndexType> {
pub dragged: Option<NodeIndex<Ix>>,
pub selected: Vec<NodeIndex<Ix>>,

min: Vec2,
max: Vec2,
max_rad: f32,
}

impl Default for ComputedState {
impl<Ix> Default for ComputedState<Ix>
where
Ix: IndexType,
{
fn default() -> Self {
Self {
dragged: None,
Expand All @@ -28,11 +32,14 @@ impl Default for ComputedState {
}
}

impl ComputedState {
impl<Ix> ComputedState<Ix>
where
Ix: IndexType,
{
pub fn compute_for_node<N: Clone, E: Clone, Ty: EdgeType>(
&mut self,
g: &Graph<N, E, Ty>,
idx: NodeIndex,
g: &Graph<N, E, Ty, Ix>,
idx: NodeIndex<Ix>,
) -> ComputedNode {
let n = g.node(idx).unwrap();

Expand Down
18 changes: 12 additions & 6 deletions src/draw/custom.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
use egui::Context;
use petgraph::graph::IndexType;
use petgraph::{stable_graph::NodeIndex, EdgeType};

use crate::{Edge, Graph, Metadata, Node, SettingsStyle};

use super::Layers;

/// Contains all the data about current widget state which is needed for custom drawing functions.
pub struct WidgetState<'a, N: Clone, E: Clone, Ty: EdgeType> {
pub g: &'a Graph<N, E, Ty>,
pub struct WidgetState<'a, N: Clone, E: Clone, Ty: EdgeType, Ix: IndexType> {
pub g: &'a Graph<N, E, Ty, Ix>,
pub style: &'a SettingsStyle,
pub meta: &'a Metadata,
}
Expand All @@ -20,8 +21,8 @@ pub struct WidgetState<'a, N: Clone, E: Clone, Ty: EdgeType> {
/// - node reference, contains all node data;
/// - widget state with references to graph, style and metadata;
/// - when you create a shape, add it to the layers.
pub type FnCustomNodeDraw<N, E, Ty> =
fn(&Context, n: &Node<N>, &WidgetState<N, E, Ty>, &mut Layers);
pub type FnCustomNodeDraw<N, E, Ty, Ix> =
fn(&Context, n: &Node<N>, &WidgetState<N, E, Ty, Ix>, &mut Layers);

/// Allows to fully customize what shape would be drawn for an edge.
/// The function is **called once for every node pair** which has edges connecting them. So make sure you have drawn all the edges which are passed to the function.
Expand All @@ -32,5 +33,10 @@ pub type FnCustomNodeDraw<N, E, Ty> =
/// - vector of edges, all edges between start and end nodes;
/// - widget state with references to graph, style and metadata;
/// - when you create a shape, add it to the layers.
pub type FnCustomEdgeDraw<N, E, Ty> =
fn(&Context, (NodeIndex, NodeIndex), Vec<&Edge<E>>, &WidgetState<N, E, Ty>, &mut Layers);
pub type FnCustomEdgeDraw<N, E, Ty, Ix> = fn(
&Context,
(NodeIndex<Ix>, NodeIndex<Ix>),
Vec<&Edge<E>>,
&WidgetState<N, E, Ty, Ix>,
&mut Layers,
);
21 changes: 11 additions & 10 deletions src/draw/drawer.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::collections::HashMap;

use egui::Painter;
use petgraph::graph::IndexType;
use petgraph::{stable_graph::NodeIndex, EdgeType};

use crate::{settings::SettingsStyle, Edge, Graph, Metadata};
Expand All @@ -12,27 +13,27 @@ use super::{
};

/// Mapping for 2 nodes and all edges between them
type EdgeMap<'a, E> = HashMap<(NodeIndex, NodeIndex), Vec<&'a Edge<E>>>;
type EdgeMap<'a, E, Ix> = HashMap<(NodeIndex<Ix>, NodeIndex<Ix>), Vec<&'a Edge<E>>>;

pub struct Drawer<'a, N: Clone, E: Clone, Ty: EdgeType> {
pub struct Drawer<'a, N: Clone, E: Clone, Ty: EdgeType, Ix: IndexType> {
p: Painter,

g: &'a Graph<N, E, Ty>,
g: &'a Graph<N, E, Ty, Ix>,
style: &'a SettingsStyle,
meta: &'a Metadata,

custom_node_draw: Option<FnCustomNodeDraw<N, E, Ty>>,
custom_edge_draw: Option<FnCustomEdgeDraw<N, E, Ty>>,
custom_node_draw: Option<FnCustomNodeDraw<N, E, Ty, Ix>>,
custom_edge_draw: Option<FnCustomEdgeDraw<N, E, Ty, Ix>>,
}

impl<'a, N: Clone, E: Clone, Ty: EdgeType> Drawer<'a, N, E, Ty> {
impl<'a, N: Clone, E: Clone, Ty: EdgeType, Ix: IndexType> Drawer<'a, N, E, Ty, Ix> {
pub fn new(
p: Painter,
g: &'a Graph<N, E, Ty>,
g: &'a Graph<N, E, Ty, Ix>,
style: &'a SettingsStyle,
meta: &'a Metadata,
custom_node_draw: Option<FnCustomNodeDraw<N, E, Ty>>,
custom_edge_draw: Option<FnCustomEdgeDraw<N, E, Ty>>,
custom_node_draw: Option<FnCustomNodeDraw<N, E, Ty, Ix>>,
custom_edge_draw: Option<FnCustomEdgeDraw<N, E, Ty, Ix>>,
) -> Self {
Drawer {
g,
Expand Down Expand Up @@ -68,7 +69,7 @@ impl<'a, N: Clone, E: Clone, Ty: EdgeType> Drawer<'a, N, E, Ty> {
}

fn fill_layers_edges(&self, l: &mut Layers) {
let mut edge_map: EdgeMap<E> = HashMap::new();
let mut edge_map: EdgeMap<E, Ix> = HashMap::new();

self.g.edges_iter().for_each(|(idx, e)| {
let (source, target) = self.g.edge_endpoints(idx).unwrap();
Expand Down
15 changes: 8 additions & 7 deletions src/draw/edge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@ use egui::{
epaint::{CubicBezierShape, QuadraticBezierShape},
Color32, Context, Pos2, Shape, Stroke, Vec2,
};
use petgraph::graph::IndexType;
use petgraph::{stable_graph::NodeIndex, EdgeType};

use crate::{Edge, Node};

use super::{custom::WidgetState, Layers};

pub fn default_edges_draw<N: Clone, E: Clone, Ty: EdgeType>(
pub fn default_edges_draw<N: Clone, E: Clone, Ty: EdgeType, Ix: IndexType>(
ctx: &Context,
bounds: (NodeIndex, NodeIndex),
bounds: (NodeIndex<Ix>, NodeIndex<Ix>),
edges: Vec<&Edge<E>>,
state: &WidgetState<N, E, Ty>,
state: &WidgetState<N, E, Ty, Ix>,
l: &mut Layers,
) {
let (idx_start, idx_end) = bounds;
Expand All @@ -33,14 +34,14 @@ pub fn default_edges_draw<N: Clone, E: Clone, Ty: EdgeType>(
});
}

fn draw_edge_basic<N: Clone, E: Clone, Ty: EdgeType>(
fn draw_edge_basic<N: Clone, E: Clone, Ty: EdgeType, Ix: IndexType>(
ctx: &Context,
l: &mut Layers,
n_start: &Node<N>,
n_end: &Node<N>,
e: &Edge<E>,
order: usize,
state: &WidgetState<N, E, Ty>,
state: &WidgetState<N, E, Ty, Ix>,
) {
let loc_start = n_start.screen_location(state.meta).to_pos2();
let loc_end = n_end.screen_location(state.meta).to_pos2();
Expand Down Expand Up @@ -119,13 +120,13 @@ fn draw_edge_basic<N: Clone, E: Clone, Ty: EdgeType>(
l.add(shape_tip_curved);
}

fn draw_edge_looped<N: Clone, E: Clone, Ty: EdgeType>(
fn draw_edge_looped<N: Clone, E: Clone, Ty: EdgeType, Ix: IndexType>(
ctx: &Context,
l: &mut Layers,
node: &Node<N>,
e: &Edge<E>,
order: usize,
state: &WidgetState<N, E, Ty>,
state: &WidgetState<N, E, Ty, Ix>,
) {
let rad = node.screen_radius(state.meta, state.style);
let center = node.screen_location(state.meta);
Expand Down
5 changes: 3 additions & 2 deletions src/draw/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@ use egui::{
epaint::{CircleShape, TextShape},
Context, FontFamily, FontId, Pos2, Stroke,
};
use petgraph::graph::IndexType;
use petgraph::EdgeType;

use crate::Node;

use super::{custom::WidgetState, Layers};

pub fn default_node_draw<N: Clone, E: Clone, Ty: EdgeType>(
pub fn default_node_draw<N: Clone, E: Clone, Ty: EdgeType, Ix: IndexType>(
ctx: &Context,
n: &Node<N>,
state: &WidgetState<N, E, Ty>,
state: &WidgetState<N, E, Ty, Ix>,
l: &mut Layers,
) {
let is_interacted = n.selected() || n.dragged();
Expand Down
Loading

0 comments on commit 0e770f5

Please sign in to comment.