Restore serialize-based introspection through the typed edges

This commit is contained in:
Dennis Kobert
2026-07-30 10:15:51 +00:00
parent bb736002cf
commit b70b28bbe3
8 changed files with 66 additions and 16 deletions

View File

@@ -14,7 +14,7 @@ use graphene_std::memo::IORecord;
use graphene_std::raster_types::{CPU, GPU, Raster};
use graphene_std::vector::Vector;
use graphene_std::vector::style::{FillChoice, FillChoiceUI, GradientSpreadMethod, GradientType};
use graphene_std::{Artboard, Color, Context, Graphic};
use graphene_std::{Artboard, Color, CtxSnapshot, Graphic};
use std::any::Any;
use std::sync::Arc;
@@ -167,7 +167,7 @@ macro_rules! generate_layout_downcast {
($introspected_data:expr, $data:expr, [ $($ty:ty),* $(,)? ]) => {
if false { None }
$(
else if let Some(io) = $introspected_data.downcast_ref::<IORecord<Context, $ty>>() {
else if let Some(io) = $introspected_data.downcast_ref::<IORecord<CtxSnapshot, $ty>>() {
Some(io.output.layout_with_breadcrumb($data))
}
)*
@@ -178,7 +178,7 @@ macro_rules! generate_layout_downcast {
fn generate_layout(introspected_data: &Arc<dyn std::any::Any + Send + Sync + 'static>, data: &mut LayoutData) -> Option<Vec<LayoutGroup>> {
// `List<NodeId>` is interpreted as a path (e.g. the value produced by `path_of_subgraph`), shown as a
// `List` where each item's NodeId resolves against the prefix made up of the items above it.
if let Some(io) = introspected_data.downcast_ref::<IORecord<Context, List<NodeId>>>() {
if let Some(io) = introspected_data.downcast_ref::<IORecord<CtxSnapshot, List<NodeId>>>() {
return Some(table_node_id_path_layout_with_breadcrumb(&io.output, data));
}
generate_layout_downcast!(introspected_data, data, [

View File

@@ -15,7 +15,7 @@ use graphene_std::raster::{CPU, Raster};
use graphene_std::renderer::{RenderMetadata, graphic_list_bounding_box};
use graphene_std::transform::Footprint;
use graphene_std::vector::{Vector, graphic_types};
use graphene_std::{ATTR_TRANSFORM, Context, Graphic, NodeInputDecleration};
use graphene_std::{ATTR_TRANSFORM, CtxSnapshot, Graphic, NodeInputDecleration};
use interpreted_executor::dynamic_executor::ResolvedDocumentNodeTypesDelta;
use std::any::Any;
use std::sync::Arc;
@@ -892,7 +892,7 @@ fn introspected_output<T: Clone + Send + Sync + 'static>(data: &Arc<dyn Any + Se
if let Some(io) = data.downcast_ref::<IORecord<Footprint, T>>() {
return Some(io.output.clone());
}
if let Some(io) = data.downcast_ref::<IORecord<Context, T>>() {
if let Some(io) = data.downcast_ref::<IORecord<CtxSnapshot, T>>() {
return Some(io.output.clone());
}
None
@@ -911,7 +911,7 @@ mod test {
use crate::test_utils::test_prelude::{self, NodeGraphLayer};
use graph_craft::ProtoNodeIdentifier;
use graph_craft::document::NodeNetwork;
use graphene_std::Context;
use graphene_std::CtxSnapshot;
use graphene_std::NodeInputDecleration;
use graphene_std::memo::IORecord;
use test_prelude::LayerNodeIdentifier;
@@ -979,7 +979,7 @@ mod test {
Some(x.output.clone())
} else if let Some(x) = dynamic.downcast_ref::<IORecord<Footprint, Input::Result>>() {
Some(x.output.clone())
} else if let Some(x) = dynamic.downcast_ref::<IORecord<Context, Input::Result>>() {
} else if let Some(x) = dynamic.downcast_ref::<IORecord<CtxSnapshot, Input::Result>>() {
Some(x.output.clone())
} else {
warn!("cannot downcast type for introspection");

View File

@@ -19,7 +19,7 @@ use graphene_std::renderer::{Render, RenderParams, RenderSvgSegmentList, SvgRend
use graphene_std::transform::RenderQuality;
use graphene_std::vector::Vector;
use graphene_std::vector::style::RenderMode;
use graphene_std::{Artboard, Context, Graphic};
use graphene_std::{Artboard, CtxSnapshot, Graphic};
use interpreted_executor::dynamic_executor::{DynamicExecutor, IntrospectError, ResolvedDocumentNodeTypesDelta};
use interpreted_executor::util::wrap_network_in_scope;
use spin::Mutex;
@@ -413,7 +413,7 @@ impl NodeRuntime {
};
// Graphic list: thumbnail (text-aware bounds, since the `BoundingBox` trait can't lay out `Graphic::Text` content)
if let Some(io) = introspected_data.downcast_ref::<IORecord<Context, List<Graphic>>>() {
if let Some(io) = introspected_data.downcast_ref::<IORecord<CtxSnapshot, List<Graphic>>>() {
if update_thumbnails {
let bounds = graphene_std::renderer::graphic_list_bounding_box(&io.output, DAffine2::IDENTITY);
Self::render_thumbnail(&mut self.thumbnail_renders, parent_network_node_id, &io.output, bounds, responses)
@@ -421,19 +421,19 @@ impl NodeRuntime {
}
// Artboard thumbnail bounds come from the clipping rectangles, not the content union, since the renderer
// clips content to those rectangles so anything outside isn't visible
else if let Some(io) = introspected_data.downcast_ref::<IORecord<Context, List<Artboard>>>() {
else if let Some(io) = introspected_data.downcast_ref::<IORecord<CtxSnapshot, List<Artboard>>>() {
if update_thumbnails {
let bounds = artboard_clip_bounds(&io.output);
Self::render_thumbnail(&mut self.thumbnail_renders, parent_network_node_id, &io.output, bounds, responses)
}
}
// Vector list: vector modifications
else if let Some(io) = introspected_data.downcast_ref::<IORecord<Context, List<Vector>>>() {
else if let Some(io) = introspected_data.downcast_ref::<IORecord<CtxSnapshot, List<Vector>>>() {
// Insert the vector modify
self.vector_modify.insert(parent_network_node_id, io.output.element(0).cloned().unwrap_or_default());
}
// String list: thumbnail (bounds need text layout, which the `BoundingBox` trait can't do for a bare `String`)
else if let Some(io) = introspected_data.downcast_ref::<IORecord<Context, List<String>>>() {
else if let Some(io) = introspected_data.downcast_ref::<IORecord<CtxSnapshot, List<String>>>() {
if update_thumbnails {
let bounds = graphene_std::renderer::text_list_bounding_box(&io.output, DAffine2::IDENTITY);
Self::render_thumbnail(&mut self.thumbnail_renders, parent_network_node_id, &io.output, bounds, responses)