Construct value nodes as native record sources

This commit is contained in:
Dennis Kobert
2026-08-06 10:24:44 +00:00
parent 7a1d1f3238
commit 886ff03ef2
4 changed files with 35 additions and 24 deletions

View File

@@ -11,7 +11,7 @@ use core_types::node::Node;
use core_types::registry::{EdgeHandle, edge_type};
use core_types::transform::Footprint;
use core_types::uuid::NodeId;
use core_types::value::value_edge;
use core_types::value::record_value_edge;
use core_types::{CacheHash, Color, ContextModification, MemoHash, Type, TypeDescriptor};
use dyn_any::DynAny;
pub use dyn_any::StaticType;
@@ -290,13 +290,13 @@ macro_rules! tagged_value {
// ===============
// MANUAL VARIANTS
// ===============
Self::None => Ok(value_edge(())),
Self::None => Ok(record_value_edge(())),
Self::TypeDefault(td) => {
// Same direct-construction path as `to_dynany` for the same reason as in `to_dynany`.
let name = td.name.as_ref();
macro_rules! check {
($type_default:ty) => {
if name == std::any::type_name::<$type_default>() { return Ok(value_edge(<$type_default>::default())); }
if name == std::any::type_name::<$type_default>() { return Ok(record_value_edge(<$type_default>::default())); }
};
}
for_each_type_default!(check);
@@ -304,33 +304,33 @@ macro_rules! tagged_value {
}
Self::F64Array(values) => {
let list: List<f64> = values.into_iter().map(core_types::list::Item::new_from_element).collect();
Ok(value_edge(list))
Ok(record_value_edge(list))
}
Self::Color(color) => {
let list: List<Color> = color.into_iter().map(core_types::list::Item::new_from_element).collect();
Ok(value_edge(list))
Ok(record_value_edge(list))
}
Self::Gradient(stops) => Ok(value_edge(List::<GradientStops>::new_from_element(stops))),
Self::Gradient(stops) => Ok(record_value_edge(List::<GradientStops>::new_from_element(stops))),
Self::BrushStrokes(strokes) => {
let list: List<BrushStroke> = strokes.into_iter().map(core_types::list::Item::new_from_element).collect();
Ok(value_edge(list))
Ok(record_value_edge(list))
}
// =======================
// AUTO-GENERATED VARIANTS
// =======================
$( Self::$identifier(x) => Ok(value_edge(x)), )*
$( Self::$identifier(x) => Ok(record_value_edge(x)), )*
// =======================
// NON-SERIALIZED VARIANTS
// =======================
Self::RenderOutput(x) => Ok(value_edge(x)),
Self::RenderOutput(x) => Ok(record_value_edge(x)),
Self::NodeIdPath(path) => {
let list: List<NodeId> = path.into_iter().map(core_types::list::Item::new_from_element).collect();
Ok(value_edge(list))
Ok(record_value_edge(list))
}
Self::DocumentNode(node) => Ok(value_edge(node)),
Self::ContextModification(modification) => Ok(value_edge(modification)),
Self::EditorApi(x) => Ok(value_edge(x)),
Self::ResourceHash(x) => Ok(value_edge(x)),
Self::DocumentNode(node) => Ok(record_value_edge(node)),
Self::ContextModification(modification) => Ok(record_value_edge(modification)),
Self::EditorApi(x) => Ok(record_value_edge(x)),
Self::ResourceHash(x) => Ok(record_value_edge(x)),
}
}

View File

@@ -752,10 +752,10 @@ impl TypingContext {
}
let inputs = match node.construction_args {
// If the node has a value input we can infer the return type from it
// A value node is a native record source, so it types as a record
// of its value.
ConstructionArgs::Value(ref v) => {
// TODO: This should return a reference to the value
let types = NodeIOTypes::new(concrete!(Context), v.ty(), vec![]);
let types = NodeIOTypes::new(concrete!(Context), Type::Record(Box::new(v.ty())), vec![]);
self.inferred.insert(node_id, types.clone());
return Ok(types);
}
@@ -1327,9 +1327,9 @@ mod ref_adapter_test {
],
),
(
ProtoNodeIdentifier::new("graphene_core::memo::LendNode"),
ProtoNodeIdentifier::new("core_types::record::RecordExtractLendNode"),
vec![RegistryEntry {
io: NodeIOTypes::new(concrete!(Context), ref_type::<String>(), vec![edge_type::<String>()]),
io: NodeIOTypes::new(concrete!(Context), ref_type::<String>(), vec![record_edge_type::<String>()]),
constructor: unused,
}],
),
@@ -1366,7 +1366,7 @@ mod ref_adapter_test {
assert_eq!(network.nodes.len(), 3);
let (adapter_id, adapter) = &network.nodes[1];
assert_eq!(adapter.identifier.as_str(), "graphene_core::memo::LendNode");
assert_eq!(adapter.identifier.as_str(), "core_types::record::RecordExtractLendNode");
assert_eq!(adapter.unwrap_construction_nodes(), vec![NodeId(0)]);
assert_eq!(network.nodes[2].1.unwrap_construction_nodes(), vec![*adapter_id]);
assert_eq!(typing.type_of(*adapter_id).unwrap().return_value, ref_type::<String>());
@@ -1392,7 +1392,7 @@ mod ref_adapter_test {
let adapters: Vec<NodeId> = network
.nodes
.iter()
.filter(|(_, node)| node.identifier.as_str() == "graphene_core::memo::LendNode")
.filter(|(_, node)| node.identifier.as_str() == "core_types::record::RecordExtractLendNode")
.map(|(id, _)| *id)
.collect();
let [adapter_id] = adapters.as_slice() else {