Skip to content

Commit 1cf8f7f

Browse files
committed
Old value node migrations
1 parent 940c714 commit 1cf8f7f

File tree

9 files changed

+256
-126
lines changed

9 files changed

+256
-126
lines changed

editor/src/messages/portfolio/document/node_graph/document_node_definitions.rs

Lines changed: 156 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
104104
},
105105
DocumentNodeDefinition {
106106
identifier: "Value",
107-
category: "General",
107+
category: "Value",
108108
node_template: NodeTemplate {
109109
document_node: DocumentNode {
110110
implementation: DocumentNodeImplementation::ProtoNode(ops::identity::IDENTIFIER),
@@ -113,12 +113,164 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
113113
..Default::default()
114114
},
115115
persistent_node_metadata: DocumentNodePersistentMetadata {
116-
input_metadata: vec![("", "Value").into()],
116+
input_metadata: vec![("Value", "").into()],
117+
output_names: vec!["Out".to_string()],
118+
..Default::default()
119+
},
120+
},
121+
description: Cow::Borrowed("Construct any value using the dropdown menu."),
122+
properties: Some("value_properties"),
123+
},
124+
DocumentNodeDefinition {
125+
identifier: "Number Value",
126+
category: "Value",
127+
node_template: NodeTemplate {
128+
document_node: DocumentNode {
129+
implementation: DocumentNodeImplementation::ProtoNode(ops::identity::IDENTIFIER),
130+
manual_composition: Some(generic!(T)),
131+
inputs: vec![NodeInput::value(TaggedValue::F64(0.), false)],
132+
..Default::default()
133+
},
134+
persistent_node_metadata: DocumentNodePersistentMetadata {
135+
input_metadata: vec![("Value", "").into()],
136+
output_names: vec!["Out".to_string()],
137+
..Default::default()
138+
},
139+
},
140+
description: Cow::Borrowed("Constructs a number which can be set to any real number"),
141+
properties: Some("value_properties"),
142+
},
143+
DocumentNodeDefinition {
144+
identifier: "Percentage Value",
145+
category: "Value",
146+
node_template: NodeTemplate {
147+
document_node: DocumentNode {
148+
implementation: DocumentNodeImplementation::ProtoNode(ops::identity::IDENTIFIER),
149+
manual_composition: Some(generic!(T)),
150+
inputs: vec![NodeInput::value(TaggedValue::Percentage(0.), false)],
151+
..Default::default()
152+
},
153+
persistent_node_metadata: DocumentNodePersistentMetadata {
154+
input_metadata: vec![("Value", "").into()],
155+
output_names: vec!["Out".to_string()],
156+
..Default::default()
157+
},
158+
},
159+
description: Cow::Borrowed("Constructs a decimal value between 0 and 1."),
160+
properties: Some("value_properties"),
161+
},
162+
DocumentNodeDefinition {
163+
identifier: "Number Value",
164+
category: "Value",
165+
node_template: NodeTemplate {
166+
document_node: DocumentNode {
167+
implementation: DocumentNodeImplementation::ProtoNode(ops::identity::IDENTIFIER),
168+
manual_composition: Some(generic!(T)),
169+
inputs: vec![NodeInput::value(TaggedValue::U32(0), false)],
170+
..Default::default()
171+
},
172+
persistent_node_metadata: DocumentNodePersistentMetadata {
173+
input_metadata: vec![("Value", "").into()],
174+
output_names: vec!["Out".to_string()],
175+
..Default::default()
176+
},
177+
},
178+
description: Cow::Borrowed("Constructs a positive integer value."),
179+
properties: Some("value_properties"),
180+
},
181+
DocumentNodeDefinition {
182+
identifier: "Bool Value",
183+
category: "Value",
184+
node_template: NodeTemplate {
185+
document_node: DocumentNode {
186+
implementation: DocumentNodeImplementation::ProtoNode(ops::identity::IDENTIFIER),
187+
manual_composition: Some(generic!(T)),
188+
inputs: vec![NodeInput::value(TaggedValue::Bool(true), false)],
189+
..Default::default()
190+
},
191+
persistent_node_metadata: DocumentNodePersistentMetadata {
192+
input_metadata: vec![("Value", "").into()],
193+
output_names: vec!["Out".to_string()],
194+
..Default::default()
195+
},
196+
},
197+
description: Cow::Borrowed("Constructs a value which can be true or false"),
198+
properties: Some("value_properties"),
199+
},
200+
DocumentNodeDefinition {
201+
identifier: "String Value",
202+
category: "Value",
203+
node_template: NodeTemplate {
204+
document_node: DocumentNode {
205+
implementation: DocumentNodeImplementation::ProtoNode(ops::identity::IDENTIFIER),
206+
manual_composition: Some(generic!(T)),
207+
inputs: vec![NodeInput::value(TaggedValue::Percentage(0.), false)],
208+
..Default::default()
209+
},
210+
persistent_node_metadata: DocumentNodePersistentMetadata {
211+
input_metadata: vec![("Value", "").into()],
212+
output_names: vec!["Out".to_string()],
213+
..Default::default()
214+
},
215+
},
216+
description: Cow::Borrowed("Constructs a string value which can be set to any plain text."),
217+
properties: Some("value_properties"),
218+
},
219+
DocumentNodeDefinition {
220+
identifier: "Coordinate Value",
221+
category: "Value",
222+
node_template: NodeTemplate {
223+
document_node: DocumentNode {
224+
implementation: DocumentNodeImplementation::ProtoNode(ops::identity::IDENTIFIER),
225+
manual_composition: Some(generic!(T)),
226+
inputs: vec![NodeInput::value(TaggedValue::DVec2(DVec2::new(0., 0.)), false)],
227+
..Default::default()
228+
},
229+
persistent_node_metadata: DocumentNodePersistentMetadata {
230+
input_metadata: vec![("Value", "").into()],
231+
output_names: vec!["Out".to_string()],
232+
..Default::default()
233+
},
234+
},
235+
description: Cow::Borrowed("Constructs a string value which can be set to any plain text."),
236+
properties: Some("value_properties"),
237+
},
238+
DocumentNodeDefinition {
239+
identifier: "Color Value",
240+
category: "Value",
241+
node_template: NodeTemplate {
242+
document_node: DocumentNode {
243+
implementation: DocumentNodeImplementation::ProtoNode(ops::identity::IDENTIFIER),
244+
manual_composition: Some(generic!(T)),
245+
inputs: vec![NodeInput::value(TaggedValue::OptionalColor(None), false)],
246+
..Default::default()
247+
},
248+
persistent_node_metadata: DocumentNodePersistentMetadata {
249+
input_metadata: vec![("Value", "").into()],
250+
output_names: vec!["Out".to_string()],
251+
..Default::default()
252+
},
253+
},
254+
description: Cow::Borrowed("Constructs a color value which may to set to any color, or no color"),
255+
properties: Some("value_properties"),
256+
},
257+
DocumentNodeDefinition {
258+
identifier: "Gradient Value",
259+
category: "Value",
260+
node_template: NodeTemplate {
261+
document_node: DocumentNode {
262+
implementation: DocumentNodeImplementation::ProtoNode(ops::identity::IDENTIFIER),
263+
manual_composition: Some(generic!(T)),
264+
inputs: vec![NodeInput::value(TaggedValue::OptionalColor(None), false)],
265+
..Default::default()
266+
},
267+
persistent_node_metadata: DocumentNodePersistentMetadata {
268+
input_metadata: vec![("Value", "").into()],
117269
output_names: vec!["Out".to_string()],
118270
..Default::default()
119271
},
120272
},
121-
description: Cow::Borrowed("Returns the value stored in its input"),
273+
description: Cow::Borrowed(" Constructs a gradient value which may be set to any sequence of color stops to represent the transition between colors."),
122274
properties: Some("value_properties"),
123275
},
124276
// TODO: Auto-generate this from its proto node macro
@@ -934,7 +1086,7 @@ fn static_nodes() -> Vec<DocumentNodeDefinition> {
9341086
},
9351087
},
9361088
description: Cow::Borrowed(
937-
"Decomposes the X and Y components of a 2D coordinate.\n\nThe inverse of this node is \"Coordinate Value\", which can have either or both its X and Y exposed as graph inputs.",
1089+
"Decomposes the X and Y components of a 2D coordinate.\n\nThe inverse of this node is \"Coordinate from Numbers\", which can have either or both its X and Y exposed as graph inputs.",
9381090
),
9391091
properties: None,
9401092
},

editor/src/messages/portfolio/document/node_graph/node_properties.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,6 @@ pub(crate) fn property_from_type(
257257
Type::Fn(_, out) => return property_from_type(node_id, index, out, number_options, unit, display_decimal_places, step, exposable, context),
258258
Type::Future(out) => return property_from_type(node_id, index, out, number_options, unit, display_decimal_places, step, exposable, context),
259259
};
260-
261260
extra_widgets.push(widgets);
262261

263262
Ok(extra_widgets)
@@ -769,6 +768,17 @@ pub fn number_widget(parameter_widgets_info: ParameterWidgetsInfo, number_props:
769768
.on_commit(commit_value)
770769
.widget_holder(),
771770
]),
771+
Some(&TaggedValue::Percentage(x)) => widgets.extend_from_slice(&[
772+
Separator::new(SeparatorType::Unrelated).widget_holder(),
773+
number_props
774+
.percentage()
775+
.min(0.)
776+
.max(100.)
777+
.value(Some(x))
778+
.on_update(update_value(move |x: &NumberInput| TaggedValue::Percentage(x.value.unwrap()), node_id, index))
779+
.on_commit(commit_value)
780+
.widget_holder(),
781+
]),
772782
Some(&TaggedValue::U32(x)) => widgets.extend_from_slice(&[
773783
Separator::new(SeparatorType::Unrelated).widget_holder(),
774784
number_props

editor/src/messages/portfolio/document/utility_types/network_interface.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4069,20 +4069,32 @@ impl NodeNetworkInterface {
40694069
self.unload_stack_dependents(network_path);
40704070
}
40714071

4072+
pub fn set_implementation(&mut self, node_id: &NodeId, network_path: &[NodeId], implementation: DocumentNodeImplementation) {
4073+
let Some(network) = self.network_mut(network_path) else {
4074+
log::error!("Could not get nested network in replace_implementation");
4075+
return;
4076+
};
4077+
let Some(node) = network.nodes.get_mut(node_id) else {
4078+
log::error!("Could not get node in replace_implementation");
4079+
return;
4080+
};
4081+
node.implementation = implementation;
4082+
}
4083+
40724084
/// Replaces the implementation and corresponding metadata.
40734085
pub fn replace_implementation(&mut self, node_id: &NodeId, network_path: &[NodeId], new_template: &mut NodeTemplate) {
40744086
let Some(network) = self.network_mut(network_path) else {
4075-
log::error!("Could not get nested network in set_implementation");
4087+
log::error!("Could not get nested network in replace_implementation");
40764088
return;
40774089
};
40784090
let Some(node) = network.nodes.get_mut(node_id) else {
4079-
log::error!("Could not get node in set_implementation");
4091+
log::error!("Could not get node in replace_implementation");
40804092
return;
40814093
};
40824094
let new_implementation = std::mem::take(&mut new_template.document_node.implementation);
40834095
let _ = std::mem::replace(&mut node.implementation, new_implementation);
40844096
let Some(metadata) = self.node_metadata_mut(node_id, network_path) else {
4085-
log::error!("Could not get metadata in set_implementation");
4097+
log::error!("Could not get metadata in replace_implementation");
40864098
return;
40874099
};
40884100
let new_metadata = std::mem::take(&mut new_template.persistent_node_metadata.network_metadata);
@@ -4092,17 +4104,17 @@ impl NodeNetworkInterface {
40924104
/// Replaces the inputs and corresponding metadata.
40934105
pub fn replace_inputs(&mut self, node_id: &NodeId, network_path: &[NodeId], new_template: &mut NodeTemplate) -> Option<Vec<NodeInput>> {
40944106
let Some(network) = self.network_mut(network_path) else {
4095-
log::error!("Could not get nested network in set_implementation");
4107+
log::error!("Could not get nested network in replace_inputs");
40964108
return None;
40974109
};
40984110
let Some(node) = network.nodes.get_mut(node_id) else {
4099-
log::error!("Could not get node in set_implementation");
4111+
log::error!("Could not get node in replace_inputs");
41004112
return None;
41014113
};
41024114
let new_inputs = std::mem::take(&mut new_template.document_node.inputs);
41034115
let old_inputs = std::mem::replace(&mut node.inputs, new_inputs);
41044116
let Some(metadata) = self.node_metadata_mut(node_id, network_path) else {
4105-
log::error!("Could not get metadata in set_implementation");
4117+
log::error!("Could not get metadata in replace_inputs");
41064118
return None;
41074119
};
41084120
let new_metadata = std::mem::take(&mut new_template.persistent_node_metadata.input_metadata);
@@ -4159,13 +4171,13 @@ impl NodeNetworkInterface {
41594171
}
41604172

41614173
/// Keep metadata in sync with the new implementation if this is used by anything other than the upgrade scripts
4162-
pub fn set_manual_compostion(&mut self, node_id: &NodeId, network_path: &[NodeId], manual_composition: Option<Type>) {
4174+
pub fn set_manual_composition(&mut self, node_id: &NodeId, network_path: &[NodeId], manual_composition: Option<Type>) {
41634175
let Some(network) = self.network_mut(network_path) else {
4164-
log::error!("Could not get nested network in set_implementation");
4176+
log::error!("Could not get nested network in set_manual_composition");
41654177
return;
41664178
};
41674179
let Some(node) = network.nodes.get_mut(node_id) else {
4168-
log::error!("Could not get node in set_implementation");
4180+
log::error!("Could not get node in set_manual_composition");
41694181
return;
41704182
};
41714183
node.manual_composition = manual_composition;

editor/src/messages/portfolio/document_migration.rs

Lines changed: 41 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -173,42 +173,10 @@ const NODE_REPLACEMENTS: &[NodeReplacement<'static>] = &[
173173
node: graphene_std::math_nodes::logical_not::IDENTIFIER,
174174
aliases: &["graphene_core::ops::LogicalNotNode", "graphene_core::ops::LogicOrNode", "graphene_core::logic::LogicOrNode"],
175175
},
176-
NodeReplacement {
177-
node: graphene_std::math_nodes::bool_value::IDENTIFIER,
178-
aliases: &["graphene_core::ops::BoolValueNode"],
179-
},
180-
NodeReplacement {
181-
node: graphene_std::math_nodes::number_value::IDENTIFIER,
182-
aliases: &["graphene_core::ops::NumberValueNode"],
183-
},
184-
NodeReplacement {
185-
node: graphene_std::math_nodes::percentage_value::IDENTIFIER,
186-
aliases: &["graphene_core::ops::PercentageValueNode"],
187-
},
188-
NodeReplacement {
189-
node: graphene_std::math_nodes::coordinate_value::IDENTIFIER,
190-
aliases: &[
191-
"graphene_core::ops::CoordinateValueNode",
192-
"graphene_core::ops::ConstructVector2",
193-
"graphene_core::ops::Vector2ValueNode",
194-
],
195-
},
196-
NodeReplacement {
197-
node: graphene_std::math_nodes::color_value::IDENTIFIER,
198-
aliases: &["graphene_core::ops::ColorValueNode"],
199-
},
200-
NodeReplacement {
201-
node: graphene_std::math_nodes::gradient_value::IDENTIFIER,
202-
aliases: &["graphene_core::ops::GradientValueNode"],
203-
},
204176
NodeReplacement {
205177
node: graphene_std::math_nodes::sample_gradient::IDENTIFIER,
206178
aliases: &["graphene_core::ops::SampleGradientNode"],
207179
},
208-
NodeReplacement {
209-
node: graphene_std::math_nodes::string_value::IDENTIFIER,
210-
aliases: &["graphene_core::ops::StringValueNode"],
211-
},
212180
NodeReplacement {
213181
node: graphene_std::math_nodes::dot_product::IDENTIFIER,
214182
aliases: &["graphene_core::ops::DotProductNode"],
@@ -499,7 +467,7 @@ pub fn document_migration_upgrades(document: &mut DocumentMessageHandler, reset_
499467
let mut default_template = NodeTemplate::default();
500468
default_template.document_node.implementation = DocumentNodeImplementation::ProtoNode(new.clone());
501469
document.network_interface.replace_implementation(node_id, &network_path, &mut default_template);
502-
document.network_interface.set_manual_compostion(node_id, &network_path, Some(graph_craft::Type::Generic("T".into())));
470+
document.network_interface.set_manual_composition(node_id, &network_path, Some(graph_craft::Type::Generic("T".into())));
503471
}
504472
}
505473
}
@@ -528,7 +496,45 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
528496
if node.manual_composition == Some(graph_craft::concrete!(())) || node.manual_composition == Some(graph_craft::concrete!(graphene_std::transform::Footprint)) {
529497
document
530498
.network_interface
531-
.set_manual_compostion(node_id, network_path, graph_craft::concrete!(graphene_std::Context).into());
499+
.set_manual_composition(node_id, network_path, graph_craft::concrete!(graphene_std::Context).into());
500+
}
501+
502+
// Update old value nodes after https://github.com/GraphiteEditor/Graphite/pull/2822
503+
if let DocumentNodeImplementation::ProtoNode(ProtoNodeIdentifier { name }) = &node.implementation {
504+
let value_node_names = [
505+
"graphene_math_nodes::BoolValueNode",
506+
"graphene_math_nodes::ColorValueNode",
507+
"graphene_math_nodes::PercentageValueNode",
508+
"graphene_math_nodes::NumberValueNode",
509+
"graphene_math_nodes::StringValueNode",
510+
"graphene_math_nodes::GradientValueNode",
511+
];
512+
if value_node_names.iter().any(|&s| s == name) {
513+
let mut template = resolve_document_node_type("Value")?.default_node_template();
514+
document.network_interface.replace_implementation(node_id, &network_path, &mut template);
515+
let mut old_inputs = document.network_interface.replace_inputs(node_id, &network_path, &mut template)?;
516+
document.network_interface.set_reference(node_id, network_path, Some("Value".to_string()));
517+
if name == "graphene_math_nodes::PercentageValueNode" {
518+
if let NodeInput::Value { tagged_value, .. } = &old_inputs[1] {
519+
if let TaggedValue::F64(value) = &**tagged_value {
520+
old_inputs[1] = NodeInput::value(TaggedValue::Percentage(*value), false);
521+
}
522+
}
523+
}
524+
// Only migrate value inputs, if its a wire the value is unknown.
525+
if let NodeInput::Value { tagged_value, .. } = old_inputs[1].clone() {
526+
document
527+
.network_interface
528+
.set_input(&InputConnector::node(*node_id, 0), NodeInput::value(tagged_value.into_inner(), false), network_path);
529+
}
530+
} else if name == "graphene_math_nodes::CoordinateValueNode" {
531+
document.network_interface.set_implementation(
532+
node_id,
533+
&network_path,
534+
DocumentNodeImplementation::ProtoNode(graphene_std::math_nodes::coordinate_from_numbers::IDENTIFIER),
535+
);
536+
document.network_interface.set_reference(node_id, network_path, Some("Coordinate From Numbers".to_string()))
537+
}
532538
}
533539

534540
// Only nodes that have not been modified and still refer to a definition can be updated
@@ -987,7 +993,7 @@ fn migrate_node(node_id: &NodeId, node: &DocumentNode, network_path: &[NodeId],
987993

988994
// Ensure layers are positioned as stacks if they are upstream siblings of another layer
989995
document.network_interface.load_structure();
990-
let all_layers = LayerNodeIdentifier::ROOT_PARENT.descendants(document.network_interface.document_metadata()).collect::<Vec<_>>();
996+
let all_layers: Vec<LayerNodeIdentifier> = LayerNodeIdentifier::ROOT_PARENT.descendants(document.network_interface.document_metadata()).collect::<Vec<_>>();
991997
for layer in all_layers {
992998
let (downstream_node, input_index) = document
993999
.network_interface

0 commit comments

Comments
 (0)