Resolve coercion nodes and dynamic values in the layout pass

This commit is contained in:
Dennis Kobert
2026-08-15 08:48:29 +00:00
parent a717403db8
commit bfa48439c8
3 changed files with 27 additions and 5 deletions

View File

@@ -263,11 +263,20 @@ macro_rules! tagged_value {
}
}
/// `None` for values whose element type is only known dynamically ([`Self::TypeDefault`]).
/// `None` for a [`Self::TypeDefault`] whose named type is outside `for_each_type_default!`.
pub fn element_write(&self) -> Option<core_types::record::ElementWrite> {
Some(match self {
Self::None => core_types::record::element_write::<()>(),
Self::TypeDefault(_) => return None,
Self::TypeDefault(td) => {
let name = td.name.as_ref();
macro_rules! check {
($type_default:ty) => {
if name == std::any::type_name::<$type_default>() { return Some(core_types::record::element_write::<$type_default>()); }
};
}
for_each_type_default!(check);
return None;
}
Self::F64Array(_) => core_types::record::element_write::<List<f64>>(),
Self::Color(_) => core_types::record::element_write::<List<Color>>(),
Self::Gradient(_) => core_types::record::element_write::<List<GradientStops>>(),

View File

@@ -179,7 +179,7 @@ mod node_registry_macros {
(
ProtoNodeIdentifier::new(concat!["graphene_core::ops::IntoNode<", stringify!($to), ">"]),
RegistryEntry {
layout_meta: None,
layout_meta: Some(core_types::record::LayoutMeta::retype(core_types::record::element_write::<$to>())),
io: NodeIOTypes::new(
concrete!(Context),
core_types::registry::record_type::<$to>(),
@@ -247,7 +247,7 @@ mod node_registry_macros {
(
ProtoNodeIdentifier::new(concat!["graphene_core::ops::ConvertNode<", stringify!($to), ">"]),
RegistryEntry {
layout_meta: None,
layout_meta: Some(core_types::record::LayoutMeta::retype(core_types::record::element_write::<$to>())),
io: NodeIOTypes::new(
concrete!(Context),
core_types::registry::record_type::<$to>(),
@@ -293,7 +293,7 @@ mod node_registry_macros {
(
ProtoNodeIdentifier::new(concat!["graphene_core::ops::ConvertNode<", stringify!($to), ">"]),
RegistryEntry {
layout_meta: None,
layout_meta: Some(core_types::record::LayoutMeta::retype(core_types::record::element_write::<$to>())),
io: NodeIOTypes::new(
concrete!(Context),
core_types::registry::record_type::<$to>(),

View File

@@ -287,6 +287,19 @@ pub enum ElementSpec {
}
impl LayoutMeta {
/// The meta of an elementwise carrier flip that retypes input 0's element,
/// preserving its depth and attributes: what an `Into`/`Convert` coercion derives.
pub fn retype(element: ElementWrite) -> Self {
Self {
sources: vec![0],
reads: Vec::new(),
element: ElementSpec::Concrete(element),
writes: Vec::new(),
removes: Vec::new(),
level_delta: 0,
}
}
/// Folds the node's output layout from its inputs', reproducing what the
/// node's constructor derives at wiring. `inputs` is indexed by proto-input
/// position; [`sources`](LayoutMeta::sources) selects the base layouts, which