Add leveled vararg sources beside the production read nodes

This commit is contained in:
Dennis Kobert
2026-08-21 14:38:26 +00:00
parent 7e24f810c6
commit 74fddff589
2 changed files with 105 additions and 0 deletions
+73
View File
@@ -1,3 +1,4 @@
use core_types::gpoll::{Extent, GPoll, GraphError, Interrupt};
use core_types::list::List;
use core_types::{Color, ExtractVarArgs};
use core_types::{Ctx, ExtractIndex, ExtractPosition};
@@ -46,6 +47,78 @@ fn read_gradient(ctx: impl Ctx + ExtractVarArgs) -> List<GradientStops> {
var_arg.downcast_ref().cloned().unwrap_or_default()
}
/// The mapped row riding as vararg 0, in the production single-item shape.
fn vararg_list<'a, T: 'static>(ctx: &'a impl ExtractVarArgs) -> Option<&'a List<T>> {
let arg = ctx.vararg(0).ok()?;
(arg as &dyn std::any::Any).downcast_ref::<List<T>>()
}
/// Lanes of a leveled vararg source: one per item, none without a row,
/// matching the legacy empty-list return.
fn vararg_lanes<T: 'static>(ctx: &impl ExtractVarArgs, level: u8) -> GPoll<Extent> {
match level {
0 => GPoll::Final(Extent::Exactly(vararg_list::<T>(ctx).map_or(0, List::len))),
_ => GPoll::Final(Extent::Exactly(1)),
}
}
fn vararg_element<T: Clone + 'static>(ctx: &(impl ExtractVarArgs + ExtractIndex)) -> Result<T, Interrupt> {
vararg_list::<T>(ctx)
.and_then(|list| list.element(ctx.innermost_index() as usize))
.cloned()
.ok_or_else(|| GraphError::new("vararg row addressed past its items").into())
}
/// Rank-model vararg source: the mapped row's items as lanes, elements only.
#[node_macro::node(category("Test"), extent_raw(read_graphic_row_extent))]
pub fn read_graphic_row(ctx: impl Ctx + ExtractVarArgs + ExtractIndex) -> Result<IList<Graphic>, Interrupt> {
vararg_element(ctx)
}
fn read_graphic_row_extent<C: Ctx + ExtractVarArgs>(_: &ReadGraphicRowNode, ctx: &C, level: u8) -> GPoll<Extent> {
vararg_lanes::<Graphic>(ctx, level)
}
/// Rank-model vararg source: the mapped row's items as lanes, elements only.
#[node_macro::node(category("Test"), extent_raw(read_vector_row_extent))]
pub fn read_vector_row(ctx: impl Ctx + ExtractVarArgs + ExtractIndex) -> Result<IList<Vector>, Interrupt> {
vararg_element(ctx)
}
fn read_vector_row_extent<C: Ctx + ExtractVarArgs>(_: &ReadVectorRowNode, ctx: &C, level: u8) -> GPoll<Extent> {
vararg_lanes::<Vector>(ctx, level)
}
/// Rank-model vararg source: the mapped row's items as lanes, elements only.
#[node_macro::node(category("Test"), extent_raw(read_raster_row_extent))]
pub fn read_raster_row(ctx: impl Ctx + ExtractVarArgs + ExtractIndex) -> Result<IList<Raster<CPU>>, Interrupt> {
vararg_element(ctx)
}
fn read_raster_row_extent<C: Ctx + ExtractVarArgs>(_: &ReadRasterRowNode, ctx: &C, level: u8) -> GPoll<Extent> {
vararg_lanes::<Raster<CPU>>(ctx, level)
}
/// Rank-model vararg source: the mapped row's items as lanes, elements only.
#[node_macro::node(category("Test"), extent_raw(read_color_row_extent))]
pub fn read_color_row(ctx: impl Ctx + ExtractVarArgs + ExtractIndex) -> Result<IList<Color>, Interrupt> {
vararg_element(ctx)
}
fn read_color_row_extent<C: Ctx + ExtractVarArgs>(_: &ReadColorRowNode, ctx: &C, level: u8) -> GPoll<Extent> {
vararg_lanes::<Color>(ctx, level)
}
/// Rank-model vararg source: the mapped row's items as lanes, elements only.
#[node_macro::node(category("Test"), extent_raw(read_gradient_row_extent))]
pub fn read_gradient_row(ctx: impl Ctx + ExtractVarArgs + ExtractIndex) -> Result<IList<GradientStops>, Interrupt> {
vararg_element(ctx)
}
fn read_gradient_row_extent<C: Ctx + ExtractVarArgs>(_: &ReadGradientRowNode, ctx: &C, level: u8) -> GPoll<Extent> {
vararg_lanes::<GradientStops>(ctx, level)
}
#[node_macro::node(category("Context"), path(core_types::vector))]
fn read_position(
ctx: impl Ctx + ExtractPosition,