mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2025-07-08 00:05:00 +00:00
Implement Node Path Insertion at Compile Time (#1947)
* Implement node path insertion at compile time * Fix ci failure * Continue instead of returning from the function
This commit is contained in:
parent
f2493d5308
commit
432385343e
3 changed files with 57 additions and 30 deletions
|
@ -618,6 +618,7 @@ impl NodeNetworkInterface {
|
|||
}
|
||||
NodeInput::Scope(_) => todo!(),
|
||||
NodeInput::Inline(_) => todo!(),
|
||||
NodeInput::Reflection(_) => todo!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4418,7 +4419,7 @@ impl NodeNetworkInterface {
|
|||
if post_node.input_index() == 1 || matches!(post_node, InputConnector::Export(_)) || !post_node.node_id().is_some_and(|post_node_id| self.is_layer(&post_node_id, network_path)) {
|
||||
match post_node_input {
|
||||
// Create a new stack
|
||||
NodeInput::Value { .. } | NodeInput::Scope(_) | NodeInput::Inline(_) => {
|
||||
NodeInput::Value { .. } | NodeInput::Scope(_) | NodeInput::Inline(_) | NodeInput::Reflection(_) => {
|
||||
self.create_wire(&OutputConnector::node(layer.to_node(), 0), &post_node, network_path);
|
||||
|
||||
let final_layer_position = after_move_post_layer_position + IVec2::new(-8, 3);
|
||||
|
@ -4444,7 +4445,7 @@ impl NodeNetworkInterface {
|
|||
} else {
|
||||
match post_node_input {
|
||||
// Move to the bottom of the stack
|
||||
NodeInput::Value { .. } | NodeInput::Scope(_) | NodeInput::Inline(_) => {
|
||||
NodeInput::Value { .. } | NodeInput::Scope(_) | NodeInput::Inline(_) | NodeInput::Reflection(_) => {
|
||||
// TODO: Calculate height of bottom layer by getting height of upstream nodes instead of setting to 3
|
||||
let offset = after_move_post_layer_position - previous_layer_position + IVec2::new(0, 3);
|
||||
self.shift_absolute_node_position(&layer.to_node(), offset, network_path);
|
||||
|
|
|
@ -7,6 +7,7 @@ pub use graphene_core::uuid::generate_uuid;
|
|||
use graphene_core::{Cow, MemoHash, ProtoNodeIdentifier, Type};
|
||||
|
||||
use glam::IVec2;
|
||||
use log::Metadata;
|
||||
use rustc_hash::FxHashMap;
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::collections::HashMap;
|
||||
|
@ -15,7 +16,7 @@ use std::hash::{Hash, Hasher};
|
|||
pub mod value;
|
||||
|
||||
#[repr(transparent)]
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, PartialOrd, Ord, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, PartialOrd, Ord, serde::Serialize, serde::Deserialize, specta::Type, DynAny)]
|
||||
pub struct NodeId(pub u64);
|
||||
|
||||
// TODO: Find and replace all `NodeId(generate_uuid())` with `NodeId::new()`.
|
||||
|
@ -308,6 +309,7 @@ impl DocumentNode {
|
|||
NodeInput::Network { import_type, .. } => (ProtoNodeInput::ManualComposition(import_type), ConstructionArgs::Nodes(vec![])),
|
||||
NodeInput::Inline(inline) => (ProtoNodeInput::None, ConstructionArgs::Inline(inline)),
|
||||
NodeInput::Scope(_) => unreachable!("Scope input was not resolved"),
|
||||
NodeInput::Reflection(_) => unreachable!("Reflection input was not resolved"),
|
||||
}
|
||||
};
|
||||
assert!(!self.inputs.iter().any(|input| matches!(input, NodeInput::Network { .. })), "received non resolved parameter");
|
||||
|
@ -355,6 +357,9 @@ pub enum NodeInput {
|
|||
/// Input that is extracted from the parent scopes the node resides in. The string argument is the key.
|
||||
Scope(Cow<'static, str>),
|
||||
|
||||
/// Input that is extracted from the parent scopes the node resides in. The string argument is the key.
|
||||
Reflection(DocumentNodeMetadata),
|
||||
|
||||
/// A Rust source code string. Allows us to insert literal Rust code. Only used for GPU compilation.
|
||||
/// We can use this whenever we spin up Rustc. Sort of like inline assembly, but because our language is Rust, it acts as inline Rust.
|
||||
Inline(InlineRust),
|
||||
|
@ -373,6 +378,12 @@ impl InlineRust {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Hash, DynAny)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub enum DocumentNodeMetadata {
|
||||
DocumentNodePath,
|
||||
}
|
||||
|
||||
impl NodeInput {
|
||||
pub const fn node(node_id: NodeId, output_index: usize) -> Self {
|
||||
Self::Node { node_id, output_index, lambda: false }
|
||||
|
@ -412,6 +423,7 @@ impl NodeInput {
|
|||
NodeInput::Network { .. } => true,
|
||||
NodeInput::Inline(_) => false,
|
||||
NodeInput::Scope(_) => false,
|
||||
NodeInput::Reflection(_) => false,
|
||||
}
|
||||
}
|
||||
/// Network node inputs in the document network are not displayed, but still exist in the compiled network
|
||||
|
@ -422,6 +434,7 @@ impl NodeInput {
|
|||
NodeInput::Network { .. } => !is_document_network,
|
||||
NodeInput::Inline(_) => false,
|
||||
NodeInput::Scope(_) => false,
|
||||
NodeInput::Reflection(_) => false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -432,6 +445,7 @@ impl NodeInput {
|
|||
NodeInput::Network { import_type, .. } => import_type.clone(),
|
||||
NodeInput::Inline(_) => panic!("ty() called on NodeInput::Inline"),
|
||||
NodeInput::Scope(_) => unreachable!("ty() called on NodeInput::Scope"),
|
||||
NodeInput::Reflection(_) => concrete!(Metadata),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1022,7 +1036,7 @@ impl NodeNetwork {
|
|||
return;
|
||||
};
|
||||
|
||||
// Replace value exports with value nodes, added inside nested network
|
||||
// Replace value and reflection imports with value nodes, added inside nested network
|
||||
Self::replace_value_inputs_with_nodes(
|
||||
&mut inner_network.exports,
|
||||
&mut inner_network.nodes,
|
||||
|
@ -1076,6 +1090,7 @@ impl NodeNetwork {
|
|||
// TODO use correct output index
|
||||
nested_node.inputs[nested_input_index] = NodeInput::node(*import_id, 0);
|
||||
}
|
||||
NodeInput::Reflection(_) => unreachable!("Reflection inputs should have been replaced with value nodes"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1120,35 +1135,43 @@ impl NodeNetwork {
|
|||
for export in inputs {
|
||||
let export: &mut NodeInput = export;
|
||||
let previous_export = std::mem::replace(export, NodeInput::network(concrete!(()), 0));
|
||||
if let NodeInput::Value { tagged_value, exposed } = previous_export {
|
||||
let value_node_id = gen_id();
|
||||
let merged_node_id = map_ids(id, value_node_id);
|
||||
let mut original_location = OriginalLocation {
|
||||
path: Some(path.to_vec()),
|
||||
dependants: vec![vec![id]],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
if let Some(path) = &mut original_location.path {
|
||||
path.push(value_node_id);
|
||||
println!("export {:?}", previous_export);
|
||||
let (tagged_value, exposed) = match previous_export {
|
||||
NodeInput::Value { tagged_value, exposed } => (tagged_value, exposed),
|
||||
NodeInput::Reflection(reflect) => match reflect {
|
||||
DocumentNodeMetadata::DocumentNodePath => (TaggedValue::NodePath(path.to_vec()).into(), false),
|
||||
},
|
||||
previous_export => {
|
||||
*export = previous_export;
|
||||
continue;
|
||||
}
|
||||
collection.insert(
|
||||
merged_node_id,
|
||||
DocumentNode {
|
||||
inputs: vec![NodeInput::Value { tagged_value, exposed }],
|
||||
implementation: DocumentNodeImplementation::ProtoNode("graphene_core::value::ClonedNode".into()),
|
||||
original_location,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
*export = NodeInput::Node {
|
||||
node_id: merged_node_id,
|
||||
output_index: 0,
|
||||
lambda: false,
|
||||
};
|
||||
} else {
|
||||
*export = previous_export;
|
||||
};
|
||||
let value_node_id = gen_id();
|
||||
let merged_node_id = map_ids(id, value_node_id);
|
||||
let mut original_location = OriginalLocation {
|
||||
path: Some(path.to_vec()),
|
||||
dependants: vec![vec![id]],
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
if let Some(path) = &mut original_location.path {
|
||||
path.push(value_node_id);
|
||||
}
|
||||
collection.insert(
|
||||
merged_node_id,
|
||||
DocumentNode {
|
||||
inputs: vec![NodeInput::Value { tagged_value, exposed }],
|
||||
implementation: DocumentNodeImplementation::ProtoNode("graphene_core::value::ClonedNode".into()),
|
||||
original_location,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
*export = NodeInput::Node {
|
||||
node_id: merged_node_id,
|
||||
output_index: 0,
|
||||
lambda: false,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use super::DocumentNode;
|
||||
use crate::document::NodeId;
|
||||
pub use crate::imaginate_input::{ImaginateCache, ImaginateController, ImaginateMaskStartingFill, ImaginateSamplingMethod};
|
||||
use crate::proto::{Any as DAny, FutureAny};
|
||||
use crate::wasm_application_io::WasmEditorApi;
|
||||
|
@ -138,6 +139,8 @@ tagged_value! {
|
|||
F64Array4([f64; 4]),
|
||||
#[serde(alias = "VecF32")] // TODO: Eventually remove this alias (probably starting late 2024)
|
||||
VecF64(Vec<f64>),
|
||||
VecU64(Vec<u64>),
|
||||
NodePath(Vec<NodeId>),
|
||||
VecDVec2(Vec<DVec2>),
|
||||
RedGreenBlue(graphene_core::raster::RedGreenBlue),
|
||||
RedGreenBlueAlpha(graphene_core::raster::RedGreenBlueAlpha),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue