mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-29 03:28:12 +08:00
Valid types
This commit is contained in:
@@ -17,7 +17,7 @@ use crate::messages::portfolio::document::overlays::utility_types::{OverlaysType
|
|||||||
use crate::messages::portfolio::document::properties_panel::properties_panel_message_handler::PropertiesPanelMessageContext;
|
use crate::messages::portfolio::document::properties_panel::properties_panel_message_handler::PropertiesPanelMessageContext;
|
||||||
use crate::messages::portfolio::document::utility_types::document_metadata::{DocumentMetadata, LayerNodeIdentifier};
|
use crate::messages::portfolio::document::utility_types::document_metadata::{DocumentMetadata, LayerNodeIdentifier};
|
||||||
use crate::messages::portfolio::document::utility_types::misc::{AlignAggregate, AlignAxis, DocumentMode, FlipAxis, PTZ};
|
use crate::messages::portfolio::document::utility_types::misc::{AlignAggregate, AlignAxis, DocumentMode, FlipAxis, PTZ};
|
||||||
use crate::messages::portfolio::document::utility_types::network_interface::{FlowType, InputConnector, NodeTemplate, OutputConnector};
|
use crate::messages::portfolio::document::utility_types::network_interface::{FlowType, InputConnector, NodeTemplate};
|
||||||
use crate::messages::portfolio::document::utility_types::nodes::RawBuffer;
|
use crate::messages::portfolio::document::utility_types::nodes::RawBuffer;
|
||||||
use crate::messages::portfolio::utility_types::PanelType;
|
use crate::messages::portfolio::utility_types::PanelType;
|
||||||
use crate::messages::portfolio::utility_types::PersistentData;
|
use crate::messages::portfolio::utility_types::PersistentData;
|
||||||
|
|||||||
@@ -10,13 +10,13 @@ use crate::messages::portfolio::document::node_graph::utility_types::{ContextMen
|
|||||||
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
use crate::messages::portfolio::document::utility_types::document_metadata::LayerNodeIdentifier;
|
||||||
use crate::messages::portfolio::document::utility_types::misc::GroupFolderType;
|
use crate::messages::portfolio::document::utility_types::misc::GroupFolderType;
|
||||||
use crate::messages::portfolio::document::utility_types::network_interface::{
|
use crate::messages::portfolio::document::utility_types::network_interface::{
|
||||||
self, FlowType, InputConnector, NodeNetworkInterface, NodeTemplate, NodeTypePersistentMetadata, OutputConnector, Previewing, TypeSource,
|
self, FlowType, InputConnector, NodeNetworkInterface, NodeTemplate, NodeTypePersistentMetadata, OutputConnector, Previewing,
|
||||||
};
|
};
|
||||||
use crate::messages::portfolio::document::utility_types::nodes::{CollapsedLayers, LayerPanelEntry};
|
use crate::messages::portfolio::document::utility_types::nodes::{CollapsedLayers, LayerPanelEntry};
|
||||||
use crate::messages::portfolio::document::utility_types::wires::{GraphWireStyle, WirePath, WirePathUpdate, build_vector_wire};
|
use crate::messages::portfolio::document::utility_types::wires::{GraphWireStyle, WirePath, WirePathUpdate, build_vector_wire};
|
||||||
use crate::messages::prelude::*;
|
use crate::messages::prelude::*;
|
||||||
use crate::messages::tool::common_functionality::auto_panning::AutoPanning;
|
use crate::messages::tool::common_functionality::auto_panning::AutoPanning;
|
||||||
use crate::messages::tool::common_functionality::graph_modification_utils::{self, get_clip_mode};
|
use crate::messages::tool::common_functionality::graph_modification_utils::get_clip_mode;
|
||||||
use crate::messages::tool::common_functionality::utility_functions::make_path_editable_is_allowed;
|
use crate::messages::tool::common_functionality::utility_functions::make_path_editable_is_allowed;
|
||||||
use crate::messages::tool::tool_messages::tool_prelude::{Key, MouseMotion};
|
use crate::messages::tool::tool_messages::tool_prelude::{Key, MouseMotion};
|
||||||
use crate::messages::tool::utility_types::{HintData, HintGroup, HintInfo};
|
use crate::messages::tool::utility_types::{HintData, HintGroup, HintInfo};
|
||||||
@@ -1206,14 +1206,14 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let compatible_type = network_interface.output_type(&output_connector, selection_network_path).add_node_string();
|
||||||
|
|
||||||
// Get the output types from the network interface
|
// Get the output types from the network interface
|
||||||
let Some(network_metadata) = network_interface.network_metadata(selection_network_path) else {
|
let Some(network_metadata) = network_interface.network_metadata(selection_network_path) else {
|
||||||
warn!("No network_metadata");
|
warn!("No network_metadata");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let compatible_type = network_interface.output_type(&output_connector.unwrap(), selection_network_path).add_node_string();
|
|
||||||
|
|
||||||
let appear_right_of_mouse = if ipp.mouse.position.x > ipp.viewport_bounds.size().x - 173. { -173. } else { 0. };
|
let appear_right_of_mouse = if ipp.mouse.position.x > ipp.viewport_bounds.size().x - 173. { -173. } else { 0. };
|
||||||
let appear_above_mouse = if ipp.mouse.position.y > ipp.viewport_bounds.size().y - 34. { -34. } else { 0. };
|
let appear_above_mouse = if ipp.mouse.position.y > ipp.viewport_bounds.size().y - 34. { -34. } else { 0. };
|
||||||
let node_graph_shift = DVec2::new(appear_right_of_mouse, appear_above_mouse) / network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport.matrix2.x_axis.x;
|
let node_graph_shift = DVec2::new(appear_right_of_mouse, appear_above_mouse) / network_metadata.persistent_metadata.navigation_metadata.node_graph_to_viewport.matrix2.x_axis.x;
|
||||||
@@ -1648,6 +1648,7 @@ impl<'a> MessageHandler<NodeGraphMessage, NodeGraphMessageContext<'a>> for NodeG
|
|||||||
has_left_input_wire,
|
has_left_input_wire,
|
||||||
});
|
});
|
||||||
responses.add(NodeGraphMessage::SendSelectedNodes);
|
responses.add(NodeGraphMessage::SendSelectedNodes);
|
||||||
|
responses.add(NodeGraphMessage::SendWires);
|
||||||
self.update_node_graph_hints(responses);
|
self.update_node_graph_hints(responses);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2100,7 +2101,7 @@ impl NodeGraphMessageHandler {
|
|||||||
.popover_layout({
|
.popover_layout({
|
||||||
// Showing only compatible types
|
// Showing only compatible types
|
||||||
let compatible_type = match (selection_includes_layers, has_multiple_selection, selected_layer) {
|
let compatible_type = match (selection_includes_layers, has_multiple_selection, selected_layer) {
|
||||||
(true, false, Some(layer)) => network_interface.output_type(&OutputConnector::node(node_id, 0), &[]).add_node_string(),
|
(true, false, Some(layer)) => network_interface.output_type(&OutputConnector::node(layer.to_node(), 1), &[]).add_node_string(),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -8,9 +8,9 @@ use crate::messages::prelude::*;
|
|||||||
use choice::enum_choice;
|
use choice::enum_choice;
|
||||||
use dyn_any::DynAny;
|
use dyn_any::DynAny;
|
||||||
use glam::{DAffine2, DVec2};
|
use glam::{DAffine2, DVec2};
|
||||||
use graph_craft::Type;
|
|
||||||
use graph_craft::document::value::TaggedValue;
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graph_craft::document::{DocumentNode, DocumentNodeImplementation, NodeId, NodeInput};
|
use graph_craft::document::{DocumentNode, DocumentNodeImplementation, NodeId, NodeInput};
|
||||||
|
use graph_craft::{Type, concrete};
|
||||||
use graphene_std::NodeInputDecleration;
|
use graphene_std::NodeInputDecleration;
|
||||||
use graphene_std::animation::RealTimeMode;
|
use graphene_std::animation::RealTimeMode;
|
||||||
use graphene_std::extract_xy::XY;
|
use graphene_std::extract_xy::XY;
|
||||||
@@ -1996,7 +1996,7 @@ pub struct ParameterWidgetsInfo<'a> {
|
|||||||
impl<'a> ParameterWidgetsInfo<'a> {
|
impl<'a> ParameterWidgetsInfo<'a> {
|
||||||
pub fn new(node_id: NodeId, index: usize, blank_assist: bool, context: &'a mut NodePropertiesContext) -> ParameterWidgetsInfo<'a> {
|
pub fn new(node_id: NodeId, index: usize, blank_assist: bool, context: &'a mut NodePropertiesContext) -> ParameterWidgetsInfo<'a> {
|
||||||
let (name, description) = context.network_interface.displayed_input_name_and_description(&node_id, index, context.selection_network_path);
|
let (name, description) = context.network_interface.displayed_input_name_and_description(&node_id, index, context.selection_network_path);
|
||||||
let input_type = FrontendGraphDataType::from_type(&context.network_interface.input_type(&InputConnector::node(node_id, index), context.selection_network_path));
|
let input_type = FrontendGraphDataType::displayed_type(&context.network_interface.input_type(&InputConnector::node(node_id, index), context.selection_network_path));
|
||||||
let document_node = context.network_interface.document_node(&node_id, context.selection_network_path);
|
let document_node = context.network_interface.document_node(&node_id, context.selection_network_path);
|
||||||
|
|
||||||
ParameterWidgetsInfo {
|
ParameterWidgetsInfo {
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
use crate::messages::portfolio::document::utility_types::network_interface::TypeSource;
|
|
||||||
use glam::IVec2;
|
use glam::IVec2;
|
||||||
use graph_craft::document::NodeId;
|
use graph_craft::document::NodeId;
|
||||||
use graph_craft::document::value::TaggedValue;
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graphene_std::Type;
|
use graphene_std::Type;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
|
use crate::messages::portfolio::document::utility_types::network_interface::resolved_types::TypeSource;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Hash, serde::Serialize, serde::Deserialize, specta::Type)]
|
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Hash, serde::Serialize, serde::Deserialize, specta::Type)]
|
||||||
pub enum FrontendGraphDataType {
|
pub enum FrontendGraphDataType {
|
||||||
#[default]
|
#[default]
|
||||||
@@ -42,7 +43,7 @@ impl FrontendGraphDataType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn displayed_type(type_source: TypeSource) -> Self {
|
pub fn displayed_type(type_source: &TypeSource) -> Self {
|
||||||
match type_source.compiled_nested_type() {
|
match type_source.compiled_nested_type() {
|
||||||
Some(nested_type) => Self::from_type(&nested_type),
|
Some(nested_type) => Self::from_type(&nested_type),
|
||||||
None => Self::General,
|
None => Self::General,
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
mod deserialization;
|
|
||||||
|
|
||||||
use super::document_metadata::{DocumentMetadata, LayerNodeIdentifier, NodeRelations};
|
use super::document_metadata::{DocumentMetadata, LayerNodeIdentifier, NodeRelations};
|
||||||
use super::misc::PTZ;
|
use super::misc::PTZ;
|
||||||
use super::nodes::SelectedNodes;
|
use super::nodes::SelectedNodes;
|
||||||
@@ -13,25 +11,23 @@ use crate::messages::tool::common_functionality::graph_modification_utils;
|
|||||||
use crate::messages::tool::tool_messages::tool_prelude::NumberInputMode;
|
use crate::messages::tool::tool_messages::tool_prelude::NumberInputMode;
|
||||||
use deserialization::deserialize_node_persistent_metadata;
|
use deserialization::deserialize_node_persistent_metadata;
|
||||||
use glam::{DAffine2, DVec2, IVec2};
|
use glam::{DAffine2, DVec2, IVec2};
|
||||||
|
use graph_craft::Type;
|
||||||
use graph_craft::document::value::TaggedValue;
|
use graph_craft::document::value::TaggedValue;
|
||||||
use graph_craft::document::{DocumentNode, DocumentNodeImplementation, InlineRust, NodeId, NodeInput, NodeNetwork, OldDocumentNodeImplementation, OldNodeNetwork};
|
use graph_craft::document::{DocumentNode, DocumentNodeImplementation, NodeId, NodeInput, NodeNetwork, OldDocumentNodeImplementation, OldNodeNetwork};
|
||||||
use graph_craft::{ProtoNodeIdentifier, Type, concrete};
|
|
||||||
use graphene_std::ContextDependencies;
|
use graphene_std::ContextDependencies;
|
||||||
use graphene_std::math::quad::Quad;
|
use graphene_std::math::quad::Quad;
|
||||||
use graphene_std::subpath::Subpath;
|
use graphene_std::subpath::Subpath;
|
||||||
use graphene_std::transform::Footprint;
|
use graphene_std::transform::Footprint;
|
||||||
use graphene_std::vector::click_target::{ClickTarget, ClickTargetType};
|
use graphene_std::vector::click_target::{ClickTarget, ClickTargetType};
|
||||||
use graphene_std::vector::{PointId, Vector, VectorModificationType};
|
use graphene_std::vector::{PointId, Vector, VectorModificationType};
|
||||||
use interpreted_executor::node_registry::NODE_REGISTRY;
|
|
||||||
use kurbo::BezPath;
|
use kurbo::BezPath;
|
||||||
use serde_json::{Value, json};
|
use serde_json::{Value, json};
|
||||||
use std::collections::{HashMap, HashSet, VecDeque};
|
use std::collections::{HashMap, HashSet, VecDeque};
|
||||||
use std::hash::{DefaultHasher, Hash, Hasher};
|
use std::hash::Hash;
|
||||||
|
use std::ops::Deref;
|
||||||
|
|
||||||
mod deserialization;
|
mod deserialization;
|
||||||
mod resolved_types;
|
pub mod resolved_types;
|
||||||
use deserialization::deserialize_node_persistent_metadata;
|
|
||||||
use std::ops::Deref;
|
|
||||||
|
|
||||||
/// All network modifications should be done through this API, so the fields cannot be public. However, all fields within this struct can be public since it it not possible to have a public mutable reference.
|
/// All network modifications should be done through this API, so the fields cannot be public. However, all fields within this struct can be public since it it not possible to have a public mutable reference.
|
||||||
#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, Default, serde::Serialize, serde::Deserialize)]
|
||||||
@@ -670,7 +666,7 @@ impl NodeNetworkInterface {
|
|||||||
let valid_types = match self.valid_input_types(&input_connector, network_path) {
|
let valid_types = match self.valid_input_types(&input_connector, network_path) {
|
||||||
Ok(input_types) => input_types.iter().map(|ty| ty.to_string()).collect(),
|
Ok(input_types) => input_types.iter().map(|ty| ty.to_string()).collect(),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
log::error!("Error getting valid types for input {input_connector}: {e}");
|
log::error!("Error getting valid types for input {input_connector:?}: {e}");
|
||||||
Vec::new()
|
Vec::new()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -719,7 +715,7 @@ impl NodeNetworkInterface {
|
|||||||
} else if let Some(import_type_name) = output_type.compiled_nested_type_name() {
|
} else if let Some(import_type_name) = output_type.compiled_nested_type_name() {
|
||||||
import_type_name
|
import_type_name
|
||||||
} else {
|
} else {
|
||||||
format!("Import index {}", export_index)
|
format!("Import index {}", *import_index)
|
||||||
};
|
};
|
||||||
|
|
||||||
(import_name, description)
|
(import_name, description)
|
||||||
@@ -1061,7 +1057,10 @@ impl NodeNetworkInterface {
|
|||||||
log::error!("Could not get downstream_connectors in primary_output_connected_to_layer");
|
log::error!("Could not get downstream_connectors in primary_output_connected_to_layer");
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
let downstream_nodes = downstream_connectors.iter().filter_map(|connector| connector.node_id()).collect::<Vec<_>>();
|
let downstream_nodes = downstream_connectors
|
||||||
|
.iter()
|
||||||
|
.filter_map(|connector| if connector.input_index() == 0 { connector.node_id() } else { None })
|
||||||
|
.collect::<Vec<_>>();
|
||||||
downstream_nodes.iter().any(|node_id| self.is_layer(node_id, network_path))
|
downstream_nodes.iter().any(|node_id| self.is_layer(node_id, network_path))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1444,30 +1443,6 @@ impl NodeNetworkInterface {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets the type for a random protonode implementation (used if there is no type from the compiled network)
|
|
||||||
fn random_protonode_implementation(protonode: &graph_craft::ProtoNodeIdentifier) -> Option<&graphene_std::NodeIOTypes> {
|
|
||||||
let mut protonode = protonode.clone();
|
|
||||||
// TODO: Remove
|
|
||||||
if let Some((path, _generics)) = protonode.name.split_once('<') {
|
|
||||||
protonode = path.to_string().to_string().into();
|
|
||||||
}
|
|
||||||
let Some(node_io_hashmap) = NODE_REGISTRY.get(&protonode) else {
|
|
||||||
log::error!("Could not get hashmap for proto node: {protonode:?}");
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
|
|
||||||
let node_types = node_io_hashmap.keys().min_by_key(|node_io_types| {
|
|
||||||
let mut hasher = DefaultHasher::new();
|
|
||||||
node_io_types.hash(&mut hasher);
|
|
||||||
hasher.finish()
|
|
||||||
});
|
|
||||||
|
|
||||||
if node_types.is_none() {
|
|
||||||
log::error!("Could not get node_types from hashmap");
|
|
||||||
};
|
|
||||||
node_types
|
|
||||||
}
|
|
||||||
|
|
||||||
// Private mutable getters for use within the network interface
|
// Private mutable getters for use within the network interface
|
||||||
impl NodeNetworkInterface {
|
impl NodeNetworkInterface {
|
||||||
fn network_mut(&mut self, network_path: &[NodeId]) -> Option<&mut NodeNetwork> {
|
fn network_mut(&mut self, network_path: &[NodeId]) -> Option<&mut NodeNetwork> {
|
||||||
|
|||||||
+30
-23
@@ -1,8 +1,14 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
use graph_craft::Type;
|
use graph_craft::{
|
||||||
|
ProtoNodeIdentifier, Type, concrete,
|
||||||
|
document::{DocumentNodeImplementation, InlineRust, NodeInput, value::TaggedValue},
|
||||||
|
};
|
||||||
use graphene_std::uuid::NodeId;
|
use graphene_std::uuid::NodeId;
|
||||||
use interpreted_executor::dynamic_executor::ResolvedDocumentNodeTypesDelta;
|
use interpreted_executor::{
|
||||||
|
dynamic_executor::{NodeTypes, ResolvedDocumentNodeTypesDelta},
|
||||||
|
node_registry::NODE_REGISTRY,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::messages::portfolio::document::utility_types::network_interface::{InputConnector, NodeNetworkInterface, OutputConnector};
|
use crate::messages::portfolio::document::utility_types::network_interface::{InputConnector, NodeNetworkInterface, OutputConnector};
|
||||||
|
|
||||||
@@ -12,13 +18,6 @@ pub struct ResolvedDocumentNodeTypes {
|
|||||||
pub types: HashMap<Vec<NodeId>, NodeTypes>,
|
pub types: HashMap<Vec<NodeId>, NodeTypes>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
|
||||||
pub struct NodeTypes {
|
|
||||||
// TODO: This is currently unused. Only the output is used
|
|
||||||
pub inputs: Vec<Type>,
|
|
||||||
pub output: Type,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ResolvedDocumentNodeTypes {
|
impl ResolvedDocumentNodeTypes {
|
||||||
pub fn update(&mut self, delta: ResolvedDocumentNodeTypesDelta) {
|
pub fn update(&mut self, delta: ResolvedDocumentNodeTypesDelta) {
|
||||||
for (path, node_type) in delta.add {
|
for (path, node_type) in delta.add {
|
||||||
@@ -56,20 +55,20 @@ impl TypeSource {
|
|||||||
|
|
||||||
pub fn compiled_nested_type(&self) -> Option<&Type> {
|
pub fn compiled_nested_type(&self) -> Option<&Type> {
|
||||||
match self {
|
match self {
|
||||||
TypeSource::Compiled(compiled_type) => Some(compiled_type.compiled_nested_type()),
|
TypeSource::Compiled(compiled_type) => Some(compiled_type.nested_type()),
|
||||||
TypeSource::TaggedValue(value_type) => Some(value_type.compiled_nested_type()),
|
TypeSource::TaggedValue(value_type) => Some(value_type.nested_type()),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If Some, the type should be displayed in the imports/exports, if None it should be replaced with "import/export index _"
|
// If Some, the type should be displayed in the imports/exports, if None it should be replaced with "import/export index _"
|
||||||
pub fn compiled_nested_type_name(self) -> Option<String> {
|
pub fn compiled_nested_type_name(&self) -> Option<String> {
|
||||||
self.into_compiled_nested_type().map(|ty| ty.to_string())
|
self.compiled_nested_type().map(|ty| ty.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used when searching for nodes in the add Node popup
|
// Used when searching for nodes in the add Node popup
|
||||||
pub fn add_node_string(self) -> Option<String> {
|
pub fn add_node_string(&self) -> Option<String> {
|
||||||
self.into_compiled_nested_type().map(|ty| format!("type:{}", ty.to_string()))
|
self.compiled_nested_type().map(|ty| format!("type:{}", ty.to_string()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// The type to display in the tooltip
|
// The type to display in the tooltip
|
||||||
@@ -99,8 +98,15 @@ impl NodeNetworkInterface {
|
|||||||
// If we are trying to get the input type of an unknown node, check if it has a reference to its definition and use that input type
|
// If we are trying to get the input type of an unknown node, check if it has a reference to its definition and use that input type
|
||||||
if let InputConnector::Node { node_id, input_index } = input_connector {
|
if let InputConnector::Node { node_id, input_index } = input_connector {
|
||||||
if let Some(definition) = self.get_node_definition(node_id, network_path) {
|
if let Some(definition) = self.get_node_definition(node_id, network_path) {
|
||||||
if let Some(value) = definition.node_template.document_node.inputs.get(*input_index).cloned().and_then(|input| input.as_value()) {
|
if let Some(ty) = definition
|
||||||
return TypeSource::DocumentNodeDefinition(value.ty());
|
.node_template
|
||||||
|
.document_node
|
||||||
|
.inputs
|
||||||
|
.get(*input_index)
|
||||||
|
.cloned()
|
||||||
|
.and_then(|input| input.as_value().map(|value| value.ty()))
|
||||||
|
{
|
||||||
|
return TypeSource::DocumentNodeDefinition(ty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -174,13 +180,14 @@ impl NodeNetworkInterface {
|
|||||||
let valid_types = implementations
|
let valid_types = implementations
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|(node_io, _)| {
|
.filter_map(|(node_io, _)| {
|
||||||
if !valid_output_types.contains(&node_io.return_value) {
|
if !valid_output_types.iter().any(|output_type| output_type.nested_type() == node_io.return_value.nested_type()) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
let valid_inputs = (0..node_io.inputs.len()).filter(|iterator_index| iterator_index != input_index).all(|iterator_index| {
|
let valid_inputs = (0..node_io.inputs.len()).filter(|iterator_index| iterator_index != input_index).all(|iterator_index| {
|
||||||
let input_type = self.input_type(&InputConnector::node(*node_id, iterator_index), network_path);
|
let input_type = self.input_type(&InputConnector::node(*node_id, iterator_index), network_path);
|
||||||
match input_type.into_compiled_nested_type() {
|
match input_type.into_compiled_nested_type() {
|
||||||
Some(input_type) => node_io.inputs.get(iterator_index) == Some(&input_type),
|
Some(input_type) => node_io.inputs.get(iterator_index).map(|input_type| input_type.nested_type()) == Some(&input_type),
|
||||||
None => true,
|
None => true,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -205,7 +212,7 @@ impl NodeNetworkInterface {
|
|||||||
let Some(implementations) = NODE_REGISTRY.get(&ProtoNodeIdentifier::new(render_node)) else {
|
let Some(implementations) = NODE_REGISTRY.get(&ProtoNodeIdentifier::new(render_node)) else {
|
||||||
return Err(format!("Protonode {render_node:?} not found in registry"));
|
return Err(format!("Protonode {render_node:?} not found in registry"));
|
||||||
};
|
};
|
||||||
Ok(implementations.iter().map(|(types, _)| types.inputs[1]).collect())
|
Ok(implementations.iter().map(|(types, _)| types.inputs[1].clone()).collect())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -293,7 +300,7 @@ impl NodeNetworkInterface {
|
|||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
match implementation {
|
match implementation {
|
||||||
DocumentNodeImplementation::Network(node_network) => {
|
DocumentNodeImplementation::Network(_) => {
|
||||||
let Some(outward_wires) = self.outward_wires(&network_path) else {
|
let Some(outward_wires) = self.outward_wires(&network_path) else {
|
||||||
log::error!("Could not get outward wires in random_downstream_protonode_from_connector");
|
log::error!("Could not get outward wires in random_downstream_protonode_from_connector");
|
||||||
return None;
|
return None;
|
||||||
@@ -305,7 +312,7 @@ impl NodeNetworkInterface {
|
|||||||
let Some(first_input) = inputs_from_import.first().cloned() else {
|
let Some(first_input) = inputs_from_import.first().cloned() else {
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
self.random_downstream_type_from_connector(&first_input, &[network_path, &[node_id]].concat())
|
self.random_downstream_type_from_connector(&first_input, &[network_path, &[*node_id]].concat())
|
||||||
}
|
}
|
||||||
DocumentNodeImplementation::ProtoNode(proto_node_identifier) => {
|
DocumentNodeImplementation::ProtoNode(proto_node_identifier) => {
|
||||||
let Some(implementations) = NODE_REGISTRY.get(proto_node_identifier) else {
|
let Some(implementations) = NODE_REGISTRY.get(proto_node_identifier) else {
|
||||||
|
|||||||
@@ -176,6 +176,14 @@
|
|||||||
return `M-2,-2 L${nodeWidth + 2},-2 L${nodeWidth + 2},${nodeHeight + 2} L-2,${nodeHeight + 2}z ${rectangles.join(" ")}`;
|
return `M-2,-2 L${nodeWidth + 2},-2 L${nodeWidth + 2},${nodeHeight + 2} L-2,${nodeHeight + 2}z ${rectangles.join(" ")}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function inputTooltip(value: FrontendGraphInput): string {
|
||||||
|
return dataTypeTooltip(value) + "\n\n" + inputConnectedToText(value) + "\n\n" + validTypesText(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function outputTooltip(value: FrontendGraphOutput): string {
|
||||||
|
return dataTypeTooltip(value) + "\n\n" + outputConnectedToText(value);
|
||||||
|
}
|
||||||
|
|
||||||
function dataTypeTooltip(value: FrontendGraphInput | FrontendGraphOutput): string {
|
function dataTypeTooltip(value: FrontendGraphInput | FrontendGraphOutput): string {
|
||||||
return `Data Type: ${value.resolvedType}`;
|
return `Data Type: ${value.resolvedType}`;
|
||||||
}
|
}
|
||||||
@@ -317,7 +325,7 @@
|
|||||||
style:--offset-left={($nodeGraph.updateImportsExports.importPosition.x - 8) / 24}
|
style:--offset-left={($nodeGraph.updateImportsExports.importPosition.x - 8) / 24}
|
||||||
style:--offset-top={($nodeGraph.updateImportsExports.importPosition.y - 8) / 24 + index}
|
style:--offset-top={($nodeGraph.updateImportsExports.importPosition.y - 8) / 24 + index}
|
||||||
>
|
>
|
||||||
<title>{`${dataTypeTooltip(frontendOutput)}\n\n${outputConnectedToText(frontendOutput)}`}</title>
|
<title>{outputTooltip(frontendOutput)}</title>
|
||||||
{#if frontendOutput.connectedTo.length > 0}
|
{#if frontendOutput.connectedTo.length > 0}
|
||||||
<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)" />
|
<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}
|
{:else}
|
||||||
@@ -389,7 +397,7 @@
|
|||||||
style:--offset-left={($nodeGraph.updateImportsExports.exportPosition.x - 8) / 24}
|
style:--offset-left={($nodeGraph.updateImportsExports.exportPosition.x - 8) / 24}
|
||||||
style:--offset-top={($nodeGraph.updateImportsExports.exportPosition.y - 8) / 24 + index}
|
style:--offset-top={($nodeGraph.updateImportsExports.exportPosition.y - 8) / 24 + index}
|
||||||
>
|
>
|
||||||
<title>{`${dataTypeTooltip(frontendInput)}\n\n${inputConnectedToText(frontendInput)}`}</title>
|
<title>{inputTooltip(frontendInput)}</title>
|
||||||
{#if frontendInput.connectedTo !== "nothing"}
|
{#if frontendInput.connectedTo !== "nothing"}
|
||||||
<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)" />
|
<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}
|
{:else}
|
||||||
@@ -528,7 +536,7 @@
|
|||||||
style:--data-color={`var(--color-data-${node.primaryOutput.dataType.toLowerCase()})`}
|
style:--data-color={`var(--color-data-${node.primaryOutput.dataType.toLowerCase()})`}
|
||||||
style:--data-color-dim={`var(--color-data-${node.primaryOutput.dataType.toLowerCase()}-dim)`}
|
style:--data-color-dim={`var(--color-data-${node.primaryOutput.dataType.toLowerCase()}-dim)`}
|
||||||
>
|
>
|
||||||
<title>{`${dataTypeTooltip(node.primaryOutput)}\n\n${outputConnectedToText(node.primaryOutput)}`}</title>
|
<title>{outputTooltip(node.primaryOutput)}</title>
|
||||||
{#if node.primaryOutput.connectedTo.length > 0}
|
{#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)" />
|
<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 node.primaryOutputConnectedToLayer}
|
{#if node.primaryOutputConnectedToLayer}
|
||||||
@@ -550,7 +558,7 @@
|
|||||||
style:--data-color-dim={`var(--color-data-${(node.primaryInput?.dataType || "General").toLowerCase()}-dim)`}
|
style:--data-color-dim={`var(--color-data-${(node.primaryInput?.dataType || "General").toLowerCase()}-dim)`}
|
||||||
>
|
>
|
||||||
{#if node.primaryInput}
|
{#if node.primaryInput}
|
||||||
<title>{`${dataTypeTooltip(node.primaryInput)}\n\n${validTypesText(node.primaryInput)}\n\n${inputConnectedToText(node.primaryInput)}`}</title>
|
<title>{inputTooltip(node.primaryInput)}</title>
|
||||||
{/if}
|
{/if}
|
||||||
{#if node.primaryInput?.connectedTo !== "nothing"}
|
{#if node.primaryInput?.connectedTo !== "nothing"}
|
||||||
<path d="M0,0H8V8L5.479,6.319a2.666,2.666,0,0,0-2.959,0L0,8Z" fill="var(--data-color)" />
|
<path d="M0,0H8V8L5.479,6.319a2.666,2.666,0,0,0-2.959,0L0,8Z" fill="var(--data-color)" />
|
||||||
@@ -574,7 +582,7 @@
|
|||||||
style:--data-color={`var(--color-data-${stackDataInput.dataType.toLowerCase()})`}
|
style:--data-color={`var(--color-data-${stackDataInput.dataType.toLowerCase()})`}
|
||||||
style:--data-color-dim={`var(--color-data-${stackDataInput.dataType.toLowerCase()}-dim)`}
|
style:--data-color-dim={`var(--color-data-${stackDataInput.dataType.toLowerCase()}-dim)`}
|
||||||
>
|
>
|
||||||
<title>{`${dataTypeTooltip(stackDataInput)}\n\n${validTypesText(stackDataInput)}\n\n${inputConnectedToText(stackDataInput)}`}</title>
|
<title>{inputTooltip(stackDataInput)}</title>
|
||||||
{#if stackDataInput.connectedTo !== undefined}
|
{#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)" />
|
<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}
|
{:else}
|
||||||
@@ -692,7 +700,7 @@
|
|||||||
style:--data-color={`var(--color-data-${node.primaryInput.dataType.toLowerCase()})`}
|
style:--data-color={`var(--color-data-${node.primaryInput.dataType.toLowerCase()})`}
|
||||||
style:--data-color-dim={`var(--color-data-${node.primaryInput.dataType.toLowerCase()}-dim)`}
|
style:--data-color-dim={`var(--color-data-${node.primaryInput.dataType.toLowerCase()}-dim)`}
|
||||||
>
|
>
|
||||||
<title>{`${dataTypeTooltip(node.primaryInput)}\n\n${validTypesText(node.primaryInput)}\n\n${inputConnectedToText(node.primaryInput)}`}</title>
|
<title>{inputTooltip(node.primaryInput)}</title>
|
||||||
{#if node.primaryInput.connectedTo !== undefined}
|
{#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)" />
|
<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}
|
{:else}
|
||||||
@@ -711,7 +719,7 @@
|
|||||||
style:--data-color={`var(--color-data-${secondary.dataType.toLowerCase()})`}
|
style:--data-color={`var(--color-data-${secondary.dataType.toLowerCase()})`}
|
||||||
style:--data-color-dim={`var(--color-data-${secondary.dataType.toLowerCase()}-dim)`}
|
style:--data-color-dim={`var(--color-data-${secondary.dataType.toLowerCase()}-dim)`}
|
||||||
>
|
>
|
||||||
<title>{`${dataTypeTooltip(secondary)}\n\n${validTypesText(secondary)}\n\n${inputConnectedToText(secondary)}`}</title>
|
<title>{inputTooltip(secondary)}</title>
|
||||||
{#if secondary.connectedTo !== undefined}
|
{#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)" />
|
<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}
|
{:else}
|
||||||
@@ -733,7 +741,7 @@
|
|||||||
style:--data-color={`var(--color-data-${node.primaryOutput.dataType.toLowerCase()})`}
|
style:--data-color={`var(--color-data-${node.primaryOutput.dataType.toLowerCase()})`}
|
||||||
style:--data-color-dim={`var(--color-data-${node.primaryOutput.dataType.toLowerCase()}-dim)`}
|
style:--data-color-dim={`var(--color-data-${node.primaryOutput.dataType.toLowerCase()}-dim)`}
|
||||||
>
|
>
|
||||||
<title>{`${dataTypeTooltip(node.primaryOutput)}\n\n${outputConnectedToText(node.primaryOutput)}`}</title>
|
<title>{outputTooltip(node.primaryOutput)}</title>
|
||||||
{#if node.primaryOutput.connectedTo !== undefined}
|
{#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)" />
|
<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}
|
{:else}
|
||||||
@@ -751,7 +759,7 @@
|
|||||||
style:--data-color={`var(--color-data-${secondary.dataType.toLowerCase()})`}
|
style:--data-color={`var(--color-data-${secondary.dataType.toLowerCase()})`}
|
||||||
style:--data-color-dim={`var(--color-data-${secondary.dataType.toLowerCase()}-dim)`}
|
style:--data-color-dim={`var(--color-data-${secondary.dataType.toLowerCase()}-dim)`}
|
||||||
>
|
>
|
||||||
<title>{`${dataTypeTooltip(secondary)}\n\n${outputConnectedToText(secondary)}`}</title>
|
<title>{outputTooltip(secondary)}</title>
|
||||||
{#if secondary.connectedTo !== undefined}
|
{#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)" />
|
<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}
|
{:else}
|
||||||
|
|||||||
@@ -35,12 +35,19 @@ impl Default for DynamicExecutor {
|
|||||||
|
|
||||||
type Path = Box<[NodeId]>;
|
type Path = Box<[NodeId]>;
|
||||||
|
|
||||||
#[derive(PartialEq, Clone, Debug, Default, serde::Serialize, serde::Deserialize)]
|
#[derive(Debug, Clone, Default, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||||
pub struct ResolvedDocumentNodeTypesDelta {
|
pub struct ResolvedDocumentNodeTypesDelta {
|
||||||
pub add: Vec<(Path, NodeTypes)>,
|
pub add: Vec<(Path, NodeTypes)>,
|
||||||
pub remove: Vec<Path>,
|
pub remove: Vec<Path>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
|
||||||
|
pub struct NodeTypes {
|
||||||
|
// This is currently unused. Only the output is used
|
||||||
|
pub inputs: Vec<Type>,
|
||||||
|
pub output: Type,
|
||||||
|
}
|
||||||
|
|
||||||
impl DynamicExecutor {
|
impl DynamicExecutor {
|
||||||
pub async fn new(proto_network: ProtoNetwork) -> Result<Self, GraphErrors> {
|
pub async fn new(proto_network: ProtoNetwork) -> Result<Self, GraphErrors> {
|
||||||
let mut typing_context = TypingContext::new(&node_registry::NODE_REGISTRY);
|
let mut typing_context = TypingContext::new(&node_registry::NODE_REGISTRY);
|
||||||
@@ -100,8 +107,6 @@ impl DynamicExecutor {
|
|||||||
|
|
||||||
pub fn document_node_types<'a>(&'a self, nodes: impl Iterator<Item = Path> + 'a) -> impl Iterator<Item = (Path, NodeTypes)> + 'a {
|
pub fn document_node_types<'a>(&'a self, nodes: impl Iterator<Item = Path> + 'a) -> impl Iterator<Item = (Path, NodeTypes)> + 'a {
|
||||||
nodes.flat_map(|id| self.tree.source_map().get(&id).map(|(_, b)| (id, b.clone())))
|
nodes.flat_map(|id| self.tree.source_map().get(&id).map(|(_, b)| (id, b.clone())))
|
||||||
// TODO: https://github.com/GraphiteEditor/Graphite/issues/1767
|
|
||||||
// TODO: Non exposed inputs are not added to the inputs_source_map, so they are not included in the resolved_document_node_types. The type is still available in the typing_context. This only affects the UI-only "Import" node.
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user