Skip to content

Commit

Permalink
Improve older document upgrading compatibility and make node type err…
Browse files Browse the repository at this point in the history
…ors clearer
  • Loading branch information
Keavon committed Jan 16, 2025
1 parent 5aedda0 commit ebee0c7
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 61 deletions.
99 changes: 86 additions & 13 deletions editor/src/messages/portfolio/portfolio_message_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::messages::tool::utility_types::{HintData, HintGroup, ToolType};
use crate::node_graph_executor::{ExportConfig, NodeGraphExecutor};

use graph_craft::document::value::TaggedValue;
use graph_craft::document::{NodeId, NodeInput};
use graph_craft::document::{DocumentNodeImplementation, NodeId, NodeInput};
use graphene_core::text::{Font, TypesettingConfig};
use graphene_std::vector::style::{Fill, FillType, Gradient};
use interpreted_executor::dynamic_executor::IntrospectError;
Expand Down Expand Up @@ -383,8 +383,14 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
document_is_saved,
document_serialized_content,
} => {
// TODO: Eventually remove this document upgrade code
// This big code block contains lots of hacky code for upgrading old documents to the new format

// It can be helpful to temporarily set `upgrade_from_before_editable_subgraphs` to true if it's desired to upgrade a piece of artwork to use fresh copies of all nodes
let upgrade_from_before_editable_subgraphs = document_serialized_content.contains("node_output_index");
// Upgrade layer implementation from https://github.com/GraphiteEditor/Graphite/pull/1946 (see also `fn fix_nodes()` in `main.rs` of Graphene CLI)
let upgrade_from_before_returning_nested_click_targets =
document_serialized_content.contains("graphene_core::ConstructLayerNode") || document_serialized_content.contains("graphene_core::AddArtboardNode");
let upgrade_vector_manipulation_format = document_serialized_content.contains("ManipulatorGroupIds") && !document_name.contains("__DO_NOT_UPGRADE__");
let document_name = document_name.replace("__DO_NOT_UPGRADE__", "");

Expand All @@ -407,9 +413,83 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
}
};

// TODO: Eventually remove this document upgrade code
const REPLACEMENTS: [(&str, &str); 47] = [
("graphene_core::graphic_element::AppendArtboardNode", "graphene_core::AddArtboardNode"),
("graphene_core::graphic_element::ToArtboardNode", "graphene_core::ConstructArtboardNode"),
("graphene_core::graphic_element::ToElementNode", "graphene_core::ToGraphicElementNode"),
("graphene_core::graphic_element::ToGroupNode", "graphene_core::ToGraphicGroupNode"),
("graphene_core::ops::LogicAndNode", "graphene_core::logic::LogicAndNode"),
("graphene_core::ops::LogicNotNode", "graphene_core::logic::LogicNotNode"),
("graphene_core::ops::LogicOrNode", "graphene_core::logic::LogicOrNode"),
("graphene_core::ops::Vector2ValueNode", "graphene_core::ops::ConstructVector2"),
("graphene_core::raster::adjustments::BlackAndWhiteNode", "graphene_core::raster::BlackAndWhiteNode"),
("graphene_core::raster::adjustments::BlendNode", "graphene_core::raster::BlendNode"),
("graphene_core::raster::adjustments::ChannelMixerNode", "graphene_core::raster::ChannelMixerNode"),
("graphene_core::raster::adjustments::ColorOverlayNode", "graphene_core::raster::adjustments::ColorOverlayNode"),
("graphene_core::raster::adjustments::ExposureNode", "graphene_core::raster::ExposureNode"),
("graphene_core::raster::adjustments::ExtractChannelNode", "graphene_core::raster::ExtractChannelNode"),
("graphene_core::raster::adjustments::GradientMapNode", "graphene_core::raster::GradientMapNode"),
("graphene_core::raster::adjustments::HueSaturationNode", "graphene_core::raster::HueSaturationNode"),
("graphene_core::raster::adjustments::IndexNode", "graphene_core::raster::IndexNode"),
("graphene_core::raster::adjustments::InvertNode", "graphene_core::raster::InvertNode"),
("graphene_core::raster::adjustments::InvertNode", "graphene_core::raster::InvertRGBNode"),
("graphene_core::raster::adjustments::LevelsNode", "graphene_core::raster::LevelsNode"),
("graphene_core::raster::adjustments::LuminanceNode", "graphene_core::raster::LuminanceNode"),
("graphene_core::raster::adjustments::MakeOpaqueNode", "graphene_core::raster::ExtractOpaqueNode"),
("graphene_core::raster::adjustments::PosterizeNode", "graphene_core::raster::PosterizeNode"),
("graphene_core::raster::adjustments::ThresholdNode", "graphene_core::raster::ThresholdNode"),
("graphene_core::raster::adjustments::VibranceNode", "graphene_core::raster::VibranceNode"),
("graphene_core::text::TextNode", "graphene_core::text::TextGeneratorNode"),
("graphene_core::transform::ReplaceTransformNode", "graphene_core::transform::SetTransformNode"),
("graphene_core::vector::generator_nodes::EllipseNode", "graphene_core::vector::generator_nodes::EllipseGenerator"),
("graphene_core::vector::generator_nodes::LineNode", "graphene_core::vector::generator_nodes::LineGenerator"),
("graphene_core::vector::generator_nodes::PathNode", "graphene_core::vector::generator_nodes::PathGenerator"),
("graphene_core::vector::generator_nodes::RectangleNode", "graphene_core::vector::generator_nodes::RectangleGenerator"),
(
"graphene_core::vector::generator_nodes::RegularPolygonNode",
"graphene_core::vector::generator_nodes::RegularPolygonGenerator",
),
("graphene_core::vector::generator_nodes::SplineNode", "graphene_core::vector::generator_nodes::SplineGenerator"),
("graphene_core::vector::generator_nodes::StarNode", "graphene_core::vector::generator_nodes::StarGenerator"),
("graphene_core::vector::vector_nodes::AreaNode", "graphene_core::vector::AreaNode"),
("graphene_core::vector::vector_nodes::BoundingBoxNode", "graphene_core::vector::BoundingBoxNode"),
("graphene_core::vector::vector_nodes::CentroidNode", "graphene_core::vector::CentroidNode"),
("graphene_core::vector::vector_nodes::CircularRepeatNode", "graphene_core::vector::CircularRepeatNode"),
("graphene_core::vector::vector_nodes::CopyToPoints", "graphene_core::vector::CopyToPoints"),
("graphene_core::vector::vector_nodes::MorphNode", "graphene_core::vector::MorphNode"),
("graphene_core::vector::vector_nodes::PoissonDiskPoints", "graphene_core::vector::PoissonDiskPoints"),
("graphene_core::vector::vector_nodes::RepeatNode", "graphene_core::vector::RepeatNode"),
("graphene_core::vector::vector_nodes::SolidifyStrokeNode", "graphene_core::vector::SolidifyStrokeNode"),
("graphene_core::vector::vector_nodes::SplinesFromPointsNode", "graphene_core::vector::SplinesFromPointsNode"),
("graphene_core::vector::vector_nodes::StrokeNode", "graphene_core::vector::SetStrokeNode"),
("graphene_std::gpu_nodes::BlendGpuImageNode", "graphene_std::executor::BlendGpuImageNode"),
("graphene_std::raster::SampleImageNode", "graphene_std::raster::SampleNode"),
];
for node_id in &document
.network_interface
.network_metadata(&[])
.unwrap()
.persistent_metadata
.node_metadata
.keys()
.cloned()
.collect::<Vec<NodeId>>()
{
if let Some(DocumentNodeImplementation::ProtoNode(protonode_id)) = document.network_interface.network(&[]).unwrap().nodes.get(node_id).map(|node| node.implementation.clone()) {
for (new, old) in REPLACEMENTS {
let node_path_without_type_args = protonode_id.name.split('<').next();
if node_path_without_type_args == Some(old) {
document
.network_interface
.replace_implementation(node_id, &[], DocumentNodeImplementation::ProtoNode(new.to_string().into()));
document.network_interface.set_manual_compostion(node_id, &[], Some(graph_craft::Type::Generic("T".into())));
}
}
}
}

// Upgrade all old nodes to support editable subgraphs introduced in #1750
if upgrade_from_before_editable_subgraphs {
if upgrade_from_before_editable_subgraphs || upgrade_from_before_returning_nested_click_targets {
// This can be used, if uncommented, to upgrade demo artwork with outdated document node internals from their definitions. Delete when it's no longer needed.
// Used for upgrading old internal networks for demo artwork nodes. Will reset all node internals for any opened file
for node_id in &document
Expand Down Expand Up @@ -437,6 +517,7 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
document
.network_interface
.replace_implementation_metadata(node_id, &[], default_definition_node.persistent_node_metadata);
document.network_interface.set_manual_compostion(node_id, &[], default_definition_node.document_node.manual_composition);
}
}
}
Expand All @@ -460,8 +541,6 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
continue;
};

// Upgrade Fill nodes to the format change in #1778
// TODO: Eventually remove this document upgrade code
let Some(ref reference) = node_metadata.persistent_metadata.reference.clone() else {
continue;
};
Expand All @@ -472,6 +551,7 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
};
let inputs_count = node.inputs.len();

// Upgrade Fill nodes to the format change in #1778
if reference == "Fill" && inputs_count == 8 {
let node_definition = resolve_document_node_type(reference).unwrap();
let document_node = node_definition.default_node_template().document_node;
Expand Down Expand Up @@ -600,15 +680,8 @@ impl MessageHandler<PortfolioMessage, PortfolioMessageData<'_>> for PortfolioMes
.set_input(&InputConnector::node(*node_id, 2), NodeInput::value(TaggedValue::Bool(false), false), &[]);
}

// Upgrade layer implementation from https://github.com/GraphiteEditor/Graphite/pull/1946
if reference == "Merge" || reference == "Artboard" {
let node_definition = crate::messages::portfolio::document::node_graph::document_node_definitions::resolve_document_node_type(reference).unwrap();
let new_merge_node = node_definition.default_node_template();
document.network_interface.replace_implementation(node_id, &[], new_merge_node.document_node.implementation)
}

// Upgrade artboard name being passed as hidden value input to "To Artboard"
if reference == "Artboard" {
if reference == "Artboard" && upgrade_from_before_returning_nested_click_targets {
let label = document.network_interface.frontend_display_name(node_id, &[]);
document
.network_interface
Expand Down
28 changes: 14 additions & 14 deletions frontend/src/components/views/Graph.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@
}
function dataTypeTooltip(value: FrontendGraphInput | FrontendGraphOutput): string {
return value.resolvedType ? `Resolved Data: ${value.resolvedType}` : `Unresolved Data: ${value.dataType}`;
return value.resolvedType ? `Resolved Data:\n${value.resolvedType}` : `Unresolved Data ${value.dataType}`;
}
function outputConnectedToText(output: FrontendGraphOutput): string {
Expand Down Expand Up @@ -432,7 +432,7 @@
style:--offset-top={position.y / 24}
bind:this={outputs[0][index]}
>
<title>{`${dataTypeTooltip(outputMetadata)}\n${outputConnectedToText(outputMetadata)}`}</title>
<title>{`${dataTypeTooltip(outputMetadata)}\n\n${outputConnectedToText(outputMetadata)}`}</title>
{#if outputMetadata.connectedTo !== undefined}
<path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color)" />
{:else}
Expand Down Expand Up @@ -467,7 +467,7 @@
style:--offset-top={position.y / 24}
bind:this={inputs[0][index]}
>
<title>{`${dataTypeTooltip(inputMetadata)}\n${inputConnectedToText(inputMetadata)}`}</title>
<title>{`${dataTypeTooltip(inputMetadata)}\n\n${inputConnectedToText(inputMetadata)}`}</title>
{#if inputMetadata.connectedTo !== undefined}
<path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color)" />
{:else}
Expand Down Expand Up @@ -524,8 +524,8 @@
bind:this={nodeElements[nodeIndex]}
>
{#if node.errors}
<span class="node-error faded" transition:fade={FADE_TRANSITION} data-node-error>{node.errors}</span>
<span class="node-error hover" transition:fade={FADE_TRANSITION} data-node-error>{node.errors}</span>
<span class="node-error faded" transition:fade={FADE_TRANSITION} title="" data-node-error>{node.errors}</span>
<span class="node-error hover" transition:fade={FADE_TRANSITION} title="" data-node-error>{node.errors}</span>
{/if}
<div class="thumbnail">
{#if $nodeGraph.thumbnails.has(node.id)}
Expand All @@ -543,7 +543,7 @@
style:--data-color-dim={`var(--color-data-${node.primaryOutput.dataType.toLowerCase()}-dim)`}
bind:this={outputs[nodeIndex + 1][0]}
>
<title>{`${dataTypeTooltip(node.primaryOutput)}\n${outputConnectedToText(node.primaryOutput)}`}</title>
<title>{`${dataTypeTooltip(node.primaryOutput)}\n\n${outputConnectedToText(node.primaryOutput)}`}</title>
{#if node.primaryOutput.connectedTo.length > 0}
<path d="M0,6.953l2.521,-1.694a2.649,2.649,0,0,1,2.959,0l2.52,1.694v5.047h-8z" fill="var(--data-color)" />
{#if primaryOutputConnectedToLayer(node)}
Expand All @@ -566,7 +566,7 @@
bind:this={inputs[nodeIndex + 1][0]}
>
{#if node.primaryInput}
<title>{`${dataTypeTooltip(node.primaryInput)}\n${inputConnectedToText(node.primaryInput)}`}</title>
<title>{`${dataTypeTooltip(node.primaryInput)}\n\n${inputConnectedToText(node.primaryInput)}`}</title>
{/if}
{#if node.primaryInput?.connectedTo !== undefined}
<path d="M0,0H8V8L5.479,6.319a2.666,2.666,0,0,0-2.959,0L0,8Z" fill="var(--data-color)" />
Expand All @@ -591,7 +591,7 @@
style:--data-color-dim={`var(--color-data-${stackDataInput.dataType.toLowerCase()}-dim)`}
bind:this={inputs[nodeIndex + 1][1]}
>
<title>{`${dataTypeTooltip(stackDataInput)}\n${inputConnectedToText(stackDataInput)}`}</title>
<title>{`${dataTypeTooltip(stackDataInput)}\n\n${inputConnectedToText(stackDataInput)}`}</title>
{#if stackDataInput.connectedTo !== undefined}
<path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color)" />
{:else}
Expand Down Expand Up @@ -664,8 +664,8 @@
bind:this={nodeElements[nodeIndex]}
>
{#if node.errors}
<span class="node-error faded" transition:fade={FADE_TRANSITION} data-node-error>{node.errors}</span>
<span class="node-error hover" transition:fade={FADE_TRANSITION} data-node-error>{node.errors}</span>
<span class="node-error faded" transition:fade={FADE_TRANSITION} title="" data-node-error>{node.errors}</span>
<span class="node-error hover" transition:fade={FADE_TRANSITION} title="" data-node-error>{node.errors}</span>
{/if}
<!-- Primary row -->
<div class="primary" class:in-selected-network={$nodeGraph.inSelectedNetwork} class:no-secondary-section={exposedInputsOutputs.length === 0}>
Expand Down Expand Up @@ -698,7 +698,7 @@
style:--data-color-dim={`var(--color-data-${node.primaryInput.dataType.toLowerCase()}-dim)`}
bind:this={inputs[nodeIndex + 1][0]}
>
<title>{`${dataTypeTooltip(node.primaryInput)}\n${inputConnectedToText(node.primaryInput)}`}</title>
<title>{`${dataTypeTooltip(node.primaryInput)}\n\n${inputConnectedToText(node.primaryInput)}`}</title>
{#if node.primaryInput.connectedTo !== undefined}
<path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color)" />
{:else}
Expand All @@ -718,7 +718,7 @@
style:--data-color-dim={`var(--color-data-${secondary.dataType.toLowerCase()}-dim)`}
bind:this={inputs[nodeIndex + 1][index + (node.primaryInput ? 1 : 0)]}
>
<title>{`${dataTypeTooltip(secondary)}\n${inputConnectedToText(secondary)}`}</title>
<title>{`${dataTypeTooltip(secondary)}\n\n${inputConnectedToText(secondary)}`}</title>
{#if secondary.connectedTo !== undefined}
<path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color)" />
{:else}
Expand All @@ -741,7 +741,7 @@
style:--data-color-dim={`var(--color-data-${node.primaryOutput.dataType.toLowerCase()}-dim)`}
bind:this={outputs[nodeIndex + 1][0]}
>
<title>{`${dataTypeTooltip(node.primaryOutput)}\n${outputConnectedToText(node.primaryOutput)}`}</title>
<title>{`${dataTypeTooltip(node.primaryOutput)}\n\n${outputConnectedToText(node.primaryOutput)}`}</title>
{#if node.primaryOutput.connectedTo !== undefined}
<path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color)" />
{:else}
Expand All @@ -760,7 +760,7 @@
style:--data-color-dim={`var(--color-data-${secondary.dataType.toLowerCase()}-dim)`}
bind:this={outputs[nodeIndex + 1][outputIndex + (node.primaryOutput ? 1 : 0)]}
>
<title>{`${dataTypeTooltip(secondary)}\n${outputConnectedToText(secondary)}`}</title>
<title>{`${dataTypeTooltip(secondary)}\n\n${outputConnectedToText(secondary)}`}</title>
{#if secondary.connectedTo !== undefined}
<path d="M0,6.306A1.474,1.474,0,0,0,2.356,7.724L7.028,5.248c1.3-.687,1.3-1.809,0-2.5L2.356.276A1.474,1.474,0,0,0,0,1.694Z" fill="var(--data-color)" />
{:else}
Expand Down
14 changes: 7 additions & 7 deletions node-graph/gcore/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ impl NodeIOTypes {
impl core::fmt::Debug for NodeIOTypes {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.write_fmt(format_args!(
"node({}) -> {}",
"node({}) {}",
[&self.call_argument].into_iter().chain(&self.inputs).map(|input| input.to_string()).collect::<Vec<_>>().join(", "),
self.return_value
))
Expand Down Expand Up @@ -292,13 +292,13 @@ fn format_type(ty: &str) -> String {
impl core::fmt::Debug for Type {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::Generic(arg0) => write!(f, "Generic({arg0})"),
Self::Generic(arg0) => write!(f, "Generic<{arg0}>"),
#[cfg(feature = "type_id_logging")]
Self::Concrete(arg0) => write!(f, "Concrete({}, {:?})", arg0.name, arg0.id),
Self::Concrete(arg0) => write!(f, "Concrete<{}, {:?}>", arg0.name, arg0.id),
#[cfg(not(feature = "type_id_logging"))]
Self::Concrete(arg0) => write!(f, "Concrete({})", format_type(&arg0.name)),
Self::Fn(arg0, arg1) => write!(f, "({arg0:?} -> {arg1:?})"),
Self::Future(arg0) => write!(f, "Future({arg0:?})"),
Self::Concrete(arg0) => write!(f, "Concrete<{}>", format_type(&arg0.name)),
Self::Fn(arg0, arg1) => write!(f, "{arg0:?} {arg1:?}"),
Self::Future(arg0) => write!(f, "Future<{arg0:?}>"),
}
}
}
Expand All @@ -308,7 +308,7 @@ impl std::fmt::Display for Type {
match self {
Type::Generic(name) => write!(f, "{name}"),
Type::Concrete(ty) => write!(f, "{}", format_type(&ty.name)),
Type::Fn(input, output) => write!(f, "({input} -> {output})"),
Type::Fn(input, output) => write!(f, "{input} {output}"),
Type::Future(ty) => write!(f, "Future<{ty}>"),
}
}
Expand Down
Loading

0 comments on commit ebee0c7

Please sign in to comment.