Skip to content

Commit

Permalink
grouping visualization working as expected
Browse files Browse the repository at this point in the history
  • Loading branch information
kvey committed Nov 8, 2024
1 parent b3b2a41 commit ab621f0
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,7 @@ impl ExecutionGraph {
}

pub fn get_state_at_id(&self, id: ExecutionNodeId) -> Option<ExecutionState> {
let state_id_to_state = self.execution_node_id_to_state.clone();
state_id_to_state.get(&id).map(|x| x.clone())
self.execution_node_id_to_state.get(&id).map(|x| x.clone())
}

/// Performs a depth first traversal of the execution graph to resolve the combined
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -469,11 +469,10 @@ impl ExecutionState {
operation_node.name.as_ref()
.and_then(|name| s.operation_name_to_id.get(name).copied())
.unwrap_or_else(|| {
let new_id = Uuid::now_v7();
if let Some(name) = &operation_node.name {
s.operation_name_to_id.insert(name.clone(), op_id);
}
new_id
op_id
});
operation_node.id = op_id;
s.cells_by_id.insert(op_id, operation_node.cell.clone());
Expand Down
7 changes: 1 addition & 6 deletions toolchain/chidori-core/src/sdk/chidori_runtime_instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,11 +203,6 @@ impl ChidoriRuntimeInstance {
UserInteractionMessage::ReloadCells => {
self.reload_cells().await?;
},
UserInteractionMessage::FetchStateAt(id) => {
let state = self.db.get_state_at_id(id).unwrap();
let sender = self.runtime_event_sender.as_mut().unwrap();
sender.send(EventsFromRuntime::StateAtId(id, state)).unwrap();
},
UserInteractionMessage::RevertToState(id) => {
if let Some(id) = id {
self.execution_head_state_id = id;
Expand Down Expand Up @@ -276,6 +271,7 @@ impl ChidoriRuntimeInstance {
Ok(state)
}

#[cfg(test)]
pub fn get_state_at_current_execution_head(&self) -> ExecutionState {
self.db.get_state_at_id(self.execution_head_state_id).unwrap()
}
Expand Down Expand Up @@ -348,7 +344,6 @@ pub enum UserInteractionMessage {
SetPlaybackState(PlaybackState),
RevertToState(Option<ExecutionNodeId>),
ReloadCells,
FetchStateAt(ExecutionNodeId),
MutateCell(CellHolder),
Shutdown,
PushChatMessage(String),
Expand Down
10 changes: 6 additions & 4 deletions toolchain/chidori-debugger/src/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,7 @@ fn save_image_to_png(image: &Image) {
}

fn generate_noodle_path(elements: &[ElementDimensions], noodle_width: f32, nesting_depth: usize) -> (Path, Vec<ControlPoint>) {
let left_offset = nesting_depth as f32 * -30.0 - 30.0;
let left_offset = nesting_depth as f32 * noodle_width * -6.0 - 30.0;
let mut path_builder = PathBuilder::new();
let mut all_points = Vec::new();

Expand Down Expand Up @@ -984,7 +984,7 @@ fn generate_contour_path_for_range(range: &StateRange) -> (Path, Vec<ControlPoin
return (PathBuilder::new().build(), Vec::new());
}

generate_noodle_path(&range.elements, 10.0, range.nesting_depth)
generate_noodle_path(&range.elements, 3.0, range.nesting_depth)
}


Expand Down Expand Up @@ -1057,6 +1057,7 @@ fn render_graph_grouping(
}
}

collector.remove_implicitly_ended_ranges();
collector.calculate_nesting_depths();

let mut existing_ranges: HashSet<_> = range_id_to_entity_id.keys().cloned().collect();
Expand Down Expand Up @@ -1439,7 +1440,7 @@ fn egui_graph_node(
ui.label("Eval Failure");
}
EnclosedState::Open => {
ui.set_min_width(1000.0);
ui.set_min_width(800.0);
ui.label("Executing");
egui_execution_state(
ui,
Expand All @@ -1451,6 +1452,7 @@ fn egui_graph_node(
for (_, value) in state.state.iter() {
let image_paths = crate::util::find_matching_strings(&value.output.clone().unwrap(), r"(?i)\.(png|jpe?g)$");
for (img_path, _) in image_paths {
// TODO: cache this based on node and the path
let texture = if let Some(cached_texture) = node_image_texture_cache.get(&img_path) {
cached_texture.clone()
} else {
Expand Down Expand Up @@ -1555,7 +1557,7 @@ fn generate_tree_layout(
let mut topo = petgraph::visit::Topo::new(&execution_graph);
while let Some(x) = topo.next(&execution_graph) {
if let Some(node) = &execution_graph.node_weight(x) {
let dims = node_dimensions.entry(**node).or_insert((1000.0, 300.0));
let dims = node_dimensions.entry(**node).or_insert((800.0, 300.0));
let mut width = dims.0;
let mut height = dims.1;
let tree_node = crate::tidy_tree::Node::new(x.index(), (width) as f64, (height) as f64, Some(Orientation::Vertical));
Expand Down
64 changes: 57 additions & 7 deletions toolchain/chidori-debugger/src/graph_range_collector.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use std::cmp::Ordering;
use petgraph::prelude::{Dfs, StableGraph};
use chidori_core::execution::execution::execution_graph::ChronologyId;
use petgraph::graph::NodeIndex;
Expand All @@ -14,6 +15,7 @@ pub struct StateRange {
path: Vec<NodeIndex>,
// Maximum depth of nested paths contained within this path
pub(crate) nesting_depth: usize,
pub is_explicit_close: bool,
}

impl StateRange {
Expand Down Expand Up @@ -60,20 +62,23 @@ impl RangeCollector {
if let Some(state) = chidori_state.get_execution_state_at_id(node_weight) {
if matches!(state.evaluating_enclosed_state, EnclosedState::Close(_)) {
if state.resolving_execution_node_state_id == chronology_id {
potential_endpoints.push(node);
potential_endpoints.push((node, true));
}
}
}
}

// If no outgoing edges, consider it an endpoint
if graph.neighbors_directed(node, Outgoing).count() == 0 {
potential_endpoints.push(node);
potential_endpoints.push((node, false));
}
}

// Sort by node index
potential_endpoints.sort_by(|a, b| {
a.0.cmp(&b.0)
});
// Remove duplicates from potential_endpoints
potential_endpoints.sort();
potential_endpoints.dedup();

for end_idx in potential_endpoints {
Expand All @@ -83,23 +88,22 @@ impl RangeCollector {
self.collect_path_recursive(
graph,
start_idx,
end_idx,
end_idx.0,
end_idx.1,
&mut visited,
&mut current_path,
dimensions_map,
&chronology_id,
);
}

// After collecting all paths, calculate nesting depths
// self.calculate_nesting_depths();
}

fn collect_path_recursive(
&mut self,
graph: &StableGraph<ChronologyId, ()>,
current: NodeIndex,
target: NodeIndex,
is_explicit_close: bool,
visited: &mut HashSet<NodeIndex>,
current_path: &mut Vec<NodeIndex>,
dimensions_map: &HashMap<NodeIndex, ElementDimensions>,
Expand All @@ -123,6 +127,7 @@ impl RangeCollector {
let range = StateRange {
start_chronology_id: *chronology_id,
end_chronology_id: *target_chronology_id,
is_explicit_close,
elements,
path: current_path.clone(),
nesting_depth: 0, // Will be calculated later
Expand All @@ -136,6 +141,7 @@ impl RangeCollector {
graph,
neighbor,
target,
is_explicit_close,
visited,
current_path,
dimensions_map,
Expand All @@ -149,14 +155,58 @@ impl RangeCollector {
visited.remove(&current);
}


pub(crate) fn remove_implicitly_ended_ranges(&mut self) {
// Group ranges by start chronology IDs
let mut range_groups: HashMap<ChronologyId, Vec<StateRange>> = HashMap::new();

// First, group all ranges by their start and end IDs
for range in self.ranges.drain(..) {
let key = range.start_chronology_id;
range_groups.entry(key).or_default().push(range);
}

// Process each group
for ranges in range_groups.values() {
// Check if there's an explicitly closed range in the group
let explicit_ranges: Vec<_> = ranges.iter()
.filter(|r| r.is_explicit_close)
.collect();

if !explicit_ranges.is_empty() {
// If there are explicit ranges, only keep the first explicit one
self.ranges.push(explicit_ranges[0].clone());
} else {
// If no explicit ranges, keep all ranges in the group
self.ranges.extend(ranges.iter().cloned());
}
}

// Sort ranges by start_chronology_id for consistent ordering
self.ranges.sort_by_key(|r| r.start_chronology_id);
}

pub(crate) fn calculate_nesting_depths(&mut self) {
// For each path, count how many other paths are fully contained within it
self.ranges.sort_by(|a, b| {
if a.elements.len() > b.elements.len() {
Ordering::Greater
} else if a.elements.len() < b.elements.len() {
Ordering::Less
} else {
Ordering::Equal
}
});
for i in 0..self.ranges.len() {
let mut max_contained_depth = 0;
let parent_path = &self.ranges[i].path;

// compare path with all other paths
for j in 0..self.ranges.len() {

// skip the same path
if i != j {

let child_path = &self.ranges[j].path;

// Check if child_path is completely contained within parent_path
Expand Down

0 comments on commit ab621f0

Please sign in to comment.