Constant

A number, given a shape: the way a scalar becomes an array of the size a node downstream wants.

Constant rs
out
Type name
signal:Constant
Plane
signal
Tags
generator
Language
rust
Tier
native
Bundle
signal
Source
node-bundles/signal/Constant.rs
Availability
available

Slots

SlotDirectionType
outoutputARRAY

Parameters

constant

NameTypeDefaultRangeDoc
valuefloat0-1000000000 … 1000000000The number every entry carries; in reference mode it follows another node's output.
shapestring1The shape to fill, as lengths separated by commas: `1` is one number, `4,64` a grid.

common

NameTypeDefaultRangeDoc
autotriggerbooltrueRun on the node's own schedule, instead of waiting for an input frame. Turn this on for sources; leave it off for transforms driven by their input.
max_frequencyfloat00 … 100Rate cap for this node, read through `frequency_mode`. 0 means uncapped — the node runs as often as the scheduler and its inputs allow.
frequency_modestringupdates_per_secondupdates_per_second | seconds_per_updateHow to read `max_frequency`: as a rate in Hz (updates per second), or as a period in seconds between updates — convenient for very slow nodes.

Source

The current source of this node, as it stands in the goofi repository at node-bundles/signal/Constant.rs.

node-bundles/signal/Constant.rs
//! Constant — a number, given a shape. With `value` in reference mode it is how a scalar from
//! anywhere in the patch becomes an array of the shape a node downstream wants.

use goofi_core::{Data, Meta, SlotType};
use goofi_signal_sdk::{Inputs, Manifest, Node, NodeCtx, NodeResult, OutputDecl, Outputs, ParamDecl, Params, ParamSpec, Tag};

#[derive(Default)]
struct Constant;

impl Node for Constant {
    fn process(
        &mut self,
        _inp: &Inputs<'_>,
        out: &mut Outputs<'_>,
        _c: &mut NodeCtx,
        p: &Params<'_>,
    ) -> NodeResult {
        let value = p.f64("constant", "value").unwrap_or(0.0);
        if !value.is_finite() {
            return Err(format!("`value` is not a number: {value}").into());
        }
        let text = p.str("constant", "shape").unwrap_or("1");
        let mut shape = Vec::new();
        for part in text.split(',').map(str::trim).filter(|s| !s.is_empty()) {
            let n: usize = part.parse().map_err(|_| format!("`shape` takes whole numbers, not `{part}`"))?;
            if n == 0 {
                return Err("`shape` takes lengths of one or more".to_string().into());
            }
            shape.push(n);
        }
        if shape.is_empty() {
            shape.push(1);
        }
        let count: usize = shape.iter().product();
        if count > 1 << 24 {
            return Err(format!("`shape` asks for {count} entries, which is more than 16 million").into());
        }
        let buf: Vec<u8> = (value as f32).to_le_bytes().repeat(count);
        out.set("out", Data::array_f32(shape, buf, Meta::new()).map_err(|e| e.to_string())?);
        Ok(())
    }
}

static PARAMS: &[ParamDecl] = &[
    ParamDecl {
        group: "constant",
        name: "value",
        spec: ParamSpec::Float { default: 0.0, min: -1.0e9, max: 1.0e9 },
        expression: None,
        doc: Some("The number every entry carries; in reference mode it follows another node's output."),
    },
    ParamDecl {
        group: "constant",
        name: "shape",
        spec: ParamSpec::Str { default: "1", options: &[], refresh: false },
        expression: None,
        doc: Some("The shape to fill, as lengths separated by commas: `1` is one number, `4,64` a grid."),
    },
];
static OUTPUTS: &[OutputDecl] = &[OutputDecl { name: "out", kind: SlotType::Array }];

static MANIFEST: Manifest = Manifest {
    tags: &[Tag::Generator],
    doc: "A number, given a shape: the way a scalar becomes an array of the size a node downstream wants.",
    inputs: &[],
    outputs: OUTPUTS,
    params: PARAMS,
    producer: true,
};

goofi_signal_sdk::export!(Constant, MANIFEST);

← All nodes

This reference describes goofi 3.1.0(537cd394), generated from a running instance on 2026-09-06.