mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-10-01 17:28:11 +08:00
Remove serialization from Table<T> and make TaggedValue only store tooling/widget node inputs (#4129)
* Add TaggedValue::TypeDefault to avoid baking placeholder Tables into saved documents * Add TaggedValue::TypeDefault to avoid baking placeholder Tables into saved documents * Migrate empty Vector/Raster/Graphic/Artboard placeholder values to TypeDefault on load Documents written before the TypeDefault mechanism existed have empty Table<Vector>/<Raster>/<Graphic>/<Artboard> values baked into every unwired exposed input. Walk each migrated node's inputs and rewrite any such placeholder NodeInput::Value into the equivalent NodeInput::type_default, so re-saved documents shed the placeholder payloads. Marked with a TODO for eventual removal once enough documents have been re-saved. * Re-save demo artwork * Remove Graphic and Artboard placeholder containers from TaggedValue * Remove Raster placeholder TaggedValue variant * Simplify document migration * Remove Vector placeholder TaggedValue variant * Remove NodeIdTable from the TaggedValue * Remove StringTable from the TaggedValue * Remove F64Table in place of F64Array in TaggedValue * Replace TaggedValue::Color(Table<Color>) with ::Color(Option<Color>) * Replace TaggedValue::GradientTable(Table<GradientStops>) with ::Gradient(GradientStops) * Replace TaggedValue::BrushStrokeTable(Table<BrushStroke>) with ::BrushStrokes(Vec<BrushStroke>) * Make TaggedValue::DocumentNode runtime-only with TypeDefault placeholder * Make TaggedValue::ContextFeatures runtime-only * Remove Serialize/Deserialize from Table<T> * Add a widget for TaggedValue::BrushStrokes to visualize strokes and samples * Define a reusable list of TaggedValue::TypeDefault types for its generated methods * Re-save demo artwork
This commit is contained in:
@@ -6,6 +6,7 @@ use crate::messages::portfolio::document::utility_types::document_metadata::Laye
|
||||
use crate::messages::portfolio::document::utility_types::network_interface::{InputConnector, NodeTemplate, OutputConnector};
|
||||
use crate::messages::prelude::DocumentMessageHandler;
|
||||
use glam::{DVec2, IVec2};
|
||||
use graph_craft::descriptor;
|
||||
use graph_craft::document::DocumentNode;
|
||||
use graph_craft::document::{DocumentNodeImplementation, NodeInput, value::TaggedValue};
|
||||
use graphene_std::ProtoNodeIdentifier;
|
||||
@@ -2089,42 +2090,30 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
|
||||
.set_input(&InputConnector::node(*node_id, 3), NodeInput::value(TaggedValue::Bool(false), false), network_path);
|
||||
}
|
||||
|
||||
// Migrate Path nodes that stored geometry directly in input 0 (as a Table<Vector>) to instead use a VectorModification in input 1
|
||||
// SVG-import legacy Path nodes baked their geometry at non-exposed input 0; move it to input 1 (the modern slot for VectorModification).
|
||||
// For exposed input 0, any baked value is unused at runtime, so just reset it.
|
||||
if reference == DefinitionIdentifier::Network("Path".into()) {
|
||||
let input_0 = node.inputs.first()?;
|
||||
if let NodeInput::Value { tagged_value, exposed } = input_0
|
||||
&& !exposed
|
||||
&& let TaggedValue::Vector(vector_table) = &**tagged_value
|
||||
&& !vector_table.is_empty()
|
||||
&& let TaggedValue::VectorModification(modification) = &**tagged_value
|
||||
{
|
||||
let vector = vector_table.element(0)?;
|
||||
let modification = Box::new(graphene_std::vector::VectorModification::create_from_vector(vector));
|
||||
let modification = modification.clone();
|
||||
let was_exposed = *exposed;
|
||||
|
||||
// Reset input 0 to the default exposed state
|
||||
document
|
||||
.network_interface
|
||||
.set_input(&InputConnector::node(*node_id, 0), NodeInput::value(TaggedValue::Vector(Default::default()), true), network_path);
|
||||
document.network_interface.set_input(
|
||||
&InputConnector::node(*node_id, 0),
|
||||
NodeInput::type_default(descriptor!(graphene_std::table::Table<graphene_std::vector::Vector>), true),
|
||||
network_path,
|
||||
);
|
||||
|
||||
// Store the converted VectorModification in input 1
|
||||
document
|
||||
.network_interface
|
||||
.set_input(&InputConnector::node(*node_id, 1), NodeInput::value(TaggedValue::VectorModification(modification), false), network_path);
|
||||
if !was_exposed {
|
||||
document
|
||||
.network_interface
|
||||
.set_input(&InputConnector::node(*node_id, 1), NodeInput::value(TaggedValue::VectorModification(modification), false), network_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Migrate Image nodes that stored a Table<Raster<CPU>> in input 1 to instead use bare Image<Color> via TaggedValue::ImageData
|
||||
if reference == DefinitionIdentifier::ProtoNode(graphene_std::raster_nodes::std_nodes::image::IDENTIFIER)
|
||||
&& let Some(NodeInput::Value { tagged_value, .. }) = node.inputs.get(1)
|
||||
&& let TaggedValue::Raster(raster_table) = &**tagged_value
|
||||
&& let Some(element) = raster_table.element(0)
|
||||
{
|
||||
let image = element.data().clone();
|
||||
|
||||
document
|
||||
.network_interface
|
||||
.set_input(&InputConnector::node(*node_id, 1), NodeInput::value(TaggedValue::ImageData(image), false), network_path);
|
||||
}
|
||||
|
||||
// ==================================
|
||||
// PUT ALL MIGRATIONS ABOVE THIS LINE
|
||||
// ==================================
|
||||
|
||||
Reference in New Issue
Block a user