Improve resolved types

This commit is contained in:
Adam
2025-06-22 23:45:21 -07:00
parent ae88f4a3de
commit 88b774f184
3 changed files with 62 additions and 78 deletions

View File

@@ -7,6 +7,7 @@ pub struct Compiler {}
impl Compiler {
pub fn compile(&self, mut network: NodeNetwork) -> impl Iterator<Item = Result<ProtoNetwork, String>> {
let node_ids = network.nodes.keys().copied().collect::<Vec<_>>();
network.generate_node_paths(&[]);
network.populate_dependants();
for id in node_ids {
network.flatten(id);
@@ -19,6 +20,9 @@ impl Compiler {
proto_networks.map(move |mut proto_network| {
proto_network.resolve_inputs()?;
proto_network.generate_stable_node_ids();
// Deduplication of identical protonodes is more efficient, but also means the type information is lost for the corresponding document node
// let mut seen = std::collections::HashSet::new();
// proto_network.nodes.retain(|(protonode_id, _)| seen.insert(*protonode_id));
Ok(proto_network)
})
}

View File

@@ -193,6 +193,11 @@ impl ProtoNode {
self.identifier.name.hash(&mut hasher);
self.construction_args.hash(&mut hasher);
// TODO: This is necessary since a mapping of path to type has to be stored for document node
// If this is removed, the identical node would be removed and the mapping wouldn't be added
// This can be improved by storing a list of paths for each proto node.
self.original_location.path.hash(&mut hasher);
if self.skip_deduplication {
self.original_location.path.hash(&mut hasher);
}
@@ -210,25 +215,6 @@ impl ProtoNode {
Some(NodeId(hasher.finish()))
}
/// Construct a new [`ProtoNode`] with the specified construction args and a `ClonedNode` implementation.
pub fn value(value: ConstructionArgs, path: Vec<NodeId>) -> Self {
let inputs_exposed = match &value {
ConstructionArgs::Nodes(nodes) => nodes.len() + 1,
_ => 2,
};
Self {
identifier: ProtoNodeIdentifier::new("graphene_core::value::ClonedNode"),
construction_args: value,
input: ProtoNodeInput::ManualComposition(concrete!(Context)),
original_location: OriginalLocation {
path: Some(path),
inputs_exposed: vec![false; inputs_exposed],
..Default::default()
},
skip_deduplication: false,
}
}
/// Converts all references to other node IDs into new IDs by running the specified function on them.
/// This can be used when changing the IDs of the nodes, for example in the case of generating stable IDs.
pub fn map_ids(&mut self, f: impl Fn(NodeId) -> NodeId, skip_lambdas: bool) {
@@ -319,29 +305,6 @@ impl ProtoNetwork {
}
}
// TODO: Remove
/// Create a hashmap with the list of nodes this proto network depends on/uses as inputs.
pub fn collect_inwards_edges(&self) -> HashMap<NodeId, Vec<NodeId>> {
let mut edges: HashMap<NodeId, Vec<NodeId>> = HashMap::new();
for (id, node) in &self.nodes {
match &node.input {
ProtoNodeInput::Node(ref_id) | ProtoNodeInput::NodeLambda(ref_id) => {
self.check_ref(ref_id, id);
edges.entry(*id).or_default().push(*ref_id)
}
_ => (),
}
if let ConstructionArgs::Nodes(ref_nodes) = &node.construction_args {
for (ref_id, _) in ref_nodes {
self.check_ref(ref_id, id);
edges.entry(*id).or_default().push(*ref_id)
}
}
}
edges
}
fn collect_inwards_edges_with_mapping(&self) -> (Vec<Vec<usize>>, FxHashMap<NodeId, usize>) {
let id_map: FxHashMap<_, _> = self.nodes.iter().enumerate().map(|(idx, (id, _))| (*id, idx)).collect();
@@ -477,9 +440,22 @@ impl ProtoNetwork {
fn is_topologically_sorted(&self) -> bool {
let mut visited = HashSet::new();
let inwards_edges = self.collect_inwards_edges();
for (id, _) in &self.nodes {
for &dependency in inwards_edges.get(id).unwrap_or(&Vec::new()) {
for (id, node) in &self.nodes {
let mut upstream_nodes = Vec::new();
match &node.input {
ProtoNodeInput::Node(ref_id) | ProtoNodeInput::NodeLambda(ref_id) => {
upstream_nodes.push(*ref_id);
}
_ => (),
}
if let ConstructionArgs::Nodes(ref_nodes) = &node.construction_args {
for (ref_id, _) in ref_nodes {
upstream_nodes.push(*ref_id);
}
}
for dependency in upstream_nodes {
if !visited.contains(&dependency) {
dbg!(id, dependency);
dbg!(&visited);