From 621f469a150d4a14c86ba9be87df82aae5dded74 Mon Sep 17 00:00:00 2001 From: Keavon Chambers Date: Sat, 6 Jul 2024 01:02:40 -0700 Subject: [PATCH] Restore backwards compatibility broken with #1750 to prepare next release --- .../document/document_message_handler.rs | 77 +---------- .../graph_operation_message.rs | 2 - .../graph_operation_message_handler.rs | 6 - .../portfolio/portfolio_message_handler.rs | 128 ++++++++++++++---- frontend/wasm/src/editor_api.rs | 2 - node-graph/graph-craft/src/document/value.rs | 1 + 6 files changed, 107 insertions(+), 109 deletions(-) diff --git a/editor/src/messages/portfolio/document/document_message_handler.rs b/editor/src/messages/portfolio/document/document_message_handler.rs index ded6ecd1..edc371ab 100644 --- a/editor/src/messages/portfolio/document/document_message_handler.rs +++ b/editor/src/messages/portfolio/document/document_message_handler.rs @@ -27,7 +27,6 @@ use graphene_core::raster::BlendMode; use graphene_core::raster::ImageFrame; use graphene_core::renderer::ClickTarget; use graphene_core::vector::style::ViewMode; -use graphene_std::vector::style::{Fill, FillType, Gradient}; use glam::{DAffine2, DVec2, IVec2}; @@ -1312,81 +1311,7 @@ impl DocumentMessageHandler { } pub fn deserialize_document(serialized_content: &str) -> Result { - // serde_json::from_str(serialized_content).map_err(|e| EditorError::DocumentDeserialization(e.to_string())) - - match serde_json::from_str::(serialized_content).map_err(|e| EditorError::DocumentDeserialization(e.to_string())) { - Ok(mut document) => { - for (_, node) in &mut document.network.nodes { - // Upgrade Fill nodes to the format change in #1778 - // TODO: Eventually remove this (probably starting late 2024) - if node.name == "Fill" && node.inputs.len() == 8 { - let node_definition = crate::messages::portfolio::document::node_graph::document_node_types::resolve_document_node_type(&node.name).unwrap(); - let default_definition_node = node_definition.default_document_node(); - - node.implementation = default_definition_node.implementation.clone(); - let old_inputs = std::mem::replace(&mut node.inputs, default_definition_node.inputs.clone()); - - node.inputs[0] = old_inputs[0].clone(); - - let Some(fill_type) = old_inputs[1].as_value().cloned() else { continue }; - let TaggedValue::FillType(fill_type) = fill_type else { continue }; - let Some(solid_color) = old_inputs[2].as_value().cloned() else { continue }; - let TaggedValue::OptionalColor(solid_color) = solid_color else { continue }; - let Some(gradient_type) = old_inputs[3].as_value().cloned() else { continue }; - let TaggedValue::GradientType(gradient_type) = gradient_type else { continue }; - let Some(start) = old_inputs[4].as_value().cloned() else { continue }; - let TaggedValue::DVec2(start) = start else { continue }; - let Some(end) = old_inputs[5].as_value().cloned() else { continue }; - let TaggedValue::DVec2(end) = end else { continue }; - let Some(transform) = old_inputs[6].as_value().cloned() else { continue }; - let TaggedValue::DAffine2(transform) = transform else { continue }; - let Some(positions) = old_inputs[7].as_value().cloned() else { continue }; - let TaggedValue::GradientStops(positions) = positions else { continue }; - - let fill = match (fill_type, solid_color) { - (FillType::Solid, None) => Fill::None, - (FillType::Solid, Some(color)) => Fill::Solid(color), - (FillType::Gradient, _) => Fill::Gradient(Gradient { - stops: positions, - gradient_type, - start, - end, - transform, - }), - }; - node.inputs[1] = NodeInput::value(TaggedValue::Fill(fill.clone()), false); - match fill { - Fill::None => { - node.inputs[2] = NodeInput::value(TaggedValue::OptionalColor(None), false); - } - Fill::Solid(color) => { - node.inputs[2] = NodeInput::value(TaggedValue::OptionalColor(Some(color)), false); - } - Fill::Gradient(gradient) => { - node.inputs[3] = NodeInput::value(TaggedValue::Gradient(gradient), false); - } - } - } - } - Ok(document) - } - Err(e) => Err(e), - } - - // TODO: 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 - // match serde_json::from_str::(serialized_content).map_err(|e| EditorError::DocumentDeserialization(e.to_string())) { - // Ok(mut document) => { - // for (_, node) in &mut document.network.nodes { - // let node_definition = crate::messages::portfolio::document::node_graph::document_node_types::resolve_document_node_type(&node.name).unwrap(); - // let default_definition_node = node_definition.default_document_node(); - - // node.implementation = default_definition_node.implementation.clone(); - // } - // Ok(document) - // } - // Err(e) => Err(e), - // } + serde_json::from_str(serialized_content).map_err(|e| EditorError::DocumentDeserialization(e.to_string())) } pub fn with_name(name: String, ipp: &InputPreprocessorMessageHandler, responses: &mut VecDeque) -> Self { diff --git a/editor/src/messages/portfolio/document/graph_operation/graph_operation_message.rs b/editor/src/messages/portfolio/document/graph_operation/graph_operation_message.rs index a6495132..68005a43 100644 --- a/editor/src/messages/portfolio/document/graph_operation/graph_operation_message.rs +++ b/editor/src/messages/portfolio/document/graph_operation/graph_operation_message.rs @@ -32,8 +32,6 @@ pub enum GraphOperationMessage { layer: LayerNodeIdentifier, reconnect: bool, }, - // TODO: Eventually remove this (probably starting late 2024) - DeleteLegacyOutputNode, DisconnectInput { node_id: NodeId, input_index: usize, diff --git a/editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs b/editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs index cc09a208..1007f417 100644 --- a/editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs +++ b/editor/src/messages/portfolio/document/graph_operation/graph_operation_message_handler.rs @@ -141,12 +141,6 @@ impl MessageHandler> for Gr load_network_structure(document_network, document_metadata, collapsed); responses.add(NodeGraphMessage::RunDocumentGraph); } - // TODO: Eventually remove this (probably starting late 2024) - GraphOperationMessage::DeleteLegacyOutputNode => { - if document_network.nodes.iter().any(|(node_id, node)| node.name == "Output" && *node_id == NodeId(0)) { - ModifyInputsContext::delete_nodes(node_graph, document_network, selected_nodes, vec![NodeId(0)], true, responses, Vec::new()); - } - } // Make sure to also update NodeGraphMessage::DisconnectInput when changing this GraphOperationMessage::DisconnectInput { node_id, input_index } => { let Some(existing_input) = document_network diff --git a/editor/src/messages/portfolio/portfolio_message_handler.rs b/editor/src/messages/portfolio/portfolio_message_handler.rs index 1d1bf854..ceade28d 100644 --- a/editor/src/messages/portfolio/portfolio_message_handler.rs +++ b/editor/src/messages/portfolio/portfolio_message_handler.rs @@ -4,14 +4,18 @@ use crate::consts::DEFAULT_DOCUMENT_NAME; use crate::messages::dialog::simple_dialogs; use crate::messages::frontend::utility_types::FrontendDocumentDetails; use crate::messages::layout::utility_types::widget_prelude::*; +use crate::messages::portfolio::document::graph_operation::utility_types::ModifyInputsContext; use crate::messages::portfolio::document::utility_types::clipboards::{Clipboard, CopyBufferEntry, INTERNAL_CLIPBOARD_COUNT}; +use crate::messages::portfolio::document::utility_types::nodes::SelectedNodes; use crate::messages::portfolio::document::DocumentMessageData; use crate::messages::prelude::*; use crate::messages::tool::utility_types::{HintData, HintGroup}; use crate::node_graph_executor::{ExportConfig, NodeGraphExecutor}; -use graph_craft::document::NodeId; +use graph_craft::document::value::TaggedValue; +use graph_craft::document::{NodeId, NodeInput}; use graphene_core::text::Font; +use graphene_std::vector::style::{Fill, FillType, Gradient}; use std::sync::Arc; @@ -375,10 +379,104 @@ impl MessageHandler> for PortfolioMes document_is_saved, document_serialized_content, } => { - // TODO: Eventually remove this (probably starting late 2024) - let do_not_upgrade = document_name.contains("__DO_NOT_UPGRADE__"); + let upgrade_from_before_editable_subgraphs = document_serialized_content.contains("node_output_index"); + 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__", ""); - if document_serialized_content.contains("ManipulatorGroupIds") && !do_not_upgrade { + + let document = DocumentMessageHandler::with_name_and_content(document_name.clone(), document_serialized_content); + let mut document = match document { + Ok(document) => document, + Err(e) => { + if !document_is_auto_saved { + responses.add(DialogMessage::DisplayDialogError { + title: "Failed to open document".to_string(), + description: e.to_string(), + }); + } + + return; + } + }; + + // TODO: Eventually remove this (probably starting late 2024) + // Upgrade all old nodes to support editable subgraphs introduced in #1750 + if upgrade_from_before_editable_subgraphs { + for (_, node) in &mut document.network.nodes { + let node_definition = crate::messages::portfolio::document::node_graph::document_node_types::resolve_document_node_type(&node.name).unwrap(); + let default_definition_node = node_definition.default_document_node(); + + node.implementation = default_definition_node.implementation.clone(); + } + } + if document.network.nodes.iter().any(|(node_id, node)| node.name == "Output" && *node_id == NodeId(0)) { + ModifyInputsContext::delete_nodes( + &mut document.node_graph_handler, + &mut document.network, + &mut SelectedNodes(vec![]), + vec![NodeId(0)], + true, + responses, + Vec::new(), + ); + } + + // TODO: Eventually remove this (probably starting late 2024) + // Upgrade Fill nodes to the format change in #1778 + for (_, node) in &mut document.network.nodes { + if node.name == "Fill" && node.inputs.len() == 8 { + let node_definition = crate::messages::portfolio::document::node_graph::document_node_types::resolve_document_node_type(&node.name).unwrap(); + let default_definition_node = node_definition.default_document_node(); + + node.implementation = default_definition_node.implementation.clone(); + let old_inputs = std::mem::replace(&mut node.inputs, default_definition_node.inputs.clone()); + + node.inputs[0] = old_inputs[0].clone(); + + let Some(fill_type) = old_inputs[1].as_value().cloned() else { continue }; + let TaggedValue::FillType(fill_type) = fill_type else { continue }; + let Some(solid_color) = old_inputs[2].as_value().cloned() else { continue }; + let TaggedValue::OptionalColor(solid_color) = solid_color else { continue }; + let Some(gradient_type) = old_inputs[3].as_value().cloned() else { continue }; + let TaggedValue::GradientType(gradient_type) = gradient_type else { continue }; + let Some(start) = old_inputs[4].as_value().cloned() else { continue }; + let TaggedValue::DVec2(start) = start else { continue }; + let Some(end) = old_inputs[5].as_value().cloned() else { continue }; + let TaggedValue::DVec2(end) = end else { continue }; + let Some(transform) = old_inputs[6].as_value().cloned() else { continue }; + let TaggedValue::DAffine2(transform) = transform else { continue }; + let Some(positions) = old_inputs[7].as_value().cloned() else { continue }; + let TaggedValue::GradientStops(positions) = positions else { continue }; + + let fill = match (fill_type, solid_color) { + (FillType::Solid, None) => Fill::None, + (FillType::Solid, Some(color)) => Fill::Solid(color), + (FillType::Gradient, _) => Fill::Gradient(Gradient { + stops: positions, + gradient_type, + start, + end, + transform, + }), + }; + node.inputs[1] = NodeInput::value(TaggedValue::Fill(fill.clone()), false); + match fill { + Fill::None => { + node.inputs[2] = NodeInput::value(TaggedValue::OptionalColor(None), false); + } + Fill::Solid(color) => { + node.inputs[2] = NodeInput::value(TaggedValue::OptionalColor(Some(color)), false); + } + Fill::Gradient(gradient) => { + node.inputs[3] = NodeInput::value(TaggedValue::Gradient(gradient), false); + } + } + } + } + + // TODO: Eventually remove this (probably starting late 2024) + // Upgrade document to the new vector manipulation format introduced in #1676 + let document_serialized_content = document.serialize_document(); + if upgrade_vector_manipulation_format && document_serialized_content != "" { responses.add(FrontendMessage::TriggerUpgradeDocumentToVectorManipulationFormat { document_id, document_name, @@ -389,25 +487,9 @@ impl MessageHandler> for PortfolioMes return; } - let document = DocumentMessageHandler::with_name_and_content(document_name, document_serialized_content); - match document { - Ok(mut document) => { - document.set_auto_save_state(document_is_auto_saved); - document.set_save_state(document_is_saved); - self.load_document(document, document_id, responses); - } - Err(e) => { - if !document_is_auto_saved { - responses.add(DialogMessage::DisplayDialogError { - title: "Failed to open document".to_string(), - description: e.to_string(), - }); - } - } - } - - // TODO: Eventually remove this (probably starting late 2024) - responses.add(GraphOperationMessage::DeleteLegacyOutputNode); + document.set_auto_save_state(document_is_auto_saved); + document.set_save_state(document_is_saved); + self.load_document(document, document_id, responses); } PortfolioMessage::PasteIntoFolder { clipboard, parent, insert_index } => { let paste = |entry: &CopyBufferEntry, responses: &mut VecDeque<_>| { diff --git a/frontend/wasm/src/editor_api.rs b/frontend/wasm/src/editor_api.rs index 5259fca5..c3a14516 100644 --- a/frontend/wasm/src/editor_api.rs +++ b/frontend/wasm/src/editor_api.rs @@ -660,8 +660,6 @@ impl EditorHandle { let (response_sender, _) = std::sync::mpsc::channel(); let old_runtime = replace_node_runtime(NodeRuntime::new(request_receiver, response_sender)); - let document_serialized_content = document_serialized_content.replace("\"ManipulatorGroupIds\"", "\"PointIds\""); - let mut editor = Editor::new(); let document_id = DocumentId(document_id); editor.handle_message(PortfolioMessage::OpenDocumentFileWithId { diff --git a/node-graph/graph-craft/src/document/value.rs b/node-graph/graph-craft/src/document/value.rs index 77183800..1ec450d2 100644 --- a/node-graph/graph-craft/src/document/value.rs +++ b/node-graph/graph-craft/src/document/value.rs @@ -155,6 +155,7 @@ tagged_value! { GradientStops(graphene_core::vector::style::GradientStops), Quantization(graphene_core::quantization::QuantizationChannels), OptionalColor(Option), + #[serde(alias = "ManipulatorGroupIds")] // TODO: Eventually remove this alias (probably starting late 2024) PointIds(Vec), Font(graphene_core::text::Font), BrushStrokes(Vec),