Table
Several wires become one table, each under a key.
arrays
strings
tables
out
- Type name
signal:Table- Plane
signal- Tags
transform- Language
rust- Tier
native- Bundle
signal- Source
node-bundles/signal/Table.rs- Availability
- available
Slots
| Slot | Direction | Type | |
|---|---|---|---|
arrays | input | ARRAY | accepts several cables |
strings | input | STRING | accepts several cables |
tables | input | TABLE | accepts several cables |
out | output | TABLE |
Parameters
table
| Name | Type | Default | Range | Doc |
|---|---|---|---|---|
keys | string | "" | The key for each wire, comma-separated, over the arrays and then the strings. A wire with no key here takes the name of the node it comes from. |
common
| Name | Type | Default | Range | Doc |
|---|---|---|---|---|
autotrigger | bool | false | Run 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_frequency | float | 0 | 0 … 100 | Rate cap for this node, read through `frequency_mode`. 0 means uncapped — the node runs as often as the scheduler and its inputs allow. |
frequency_mode | string | updates_per_second | updates_per_second | seconds_per_update | How 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/Table.rs.
//! Table — several wires become one table. Arrays and strings take a key each; a table wire
//! merges its own entries in, and a later wire wins a key a earlier one already holds.
use goofi_core::indexmap::IndexMap;
use goofi_core::{Data, Meta, SlotType};
use goofi_signal_sdk::{Inputs, Manifest, Node, NodeCtx, NodeResult, OutputDecl, Outputs, ParamDecl, Params, ParamSpec, SlotDecl, Tag};
#[derive(Default)]
struct Table;
impl Node for Table {
fn process(
&mut self,
inp: &Inputs<'_>,
out: &mut Outputs<'_>,
_c: &mut NodeCtx,
p: &Params<'_>,
) -> NodeResult {
let named: Vec<&str> = p
.str("table", "keys")
.unwrap_or("")
.split(',')
.map(str::trim)
.filter(|k| !k.is_empty())
.collect();
let mut map: IndexMap<String, Data> = IndexMap::new();
let leaves = inp.get_multi("arrays").iter().chain(inp.get_multi("strings"));
for (at, (source, d)) in leaves.enumerate() {
let key = named.get(at).map_or(source.as_str(), |k| *k);
map.insert(key.to_string(), d.clone());
}
for (source, d) in inp.get_multi("tables") {
let inner = d.as_table().map_err(|e| format!("`{source}`: {e}"))?;
for (k, v) in inner {
map.insert(k.clone(), v.clone());
}
}
if map.is_empty() {
return Err("a table needs at least one wire".to_string().into());
}
out.set("out", Data::table(map, Meta::new()));
Ok(())
}
}
static PARAMS: &[ParamDecl] = &[ParamDecl {
group: "table",
name: "keys",
spec: ParamSpec::Str { default: "", options: &[], refresh: false },
expression: None,
doc: Some(
"The key for each wire, comma-separated, over the arrays and then the strings. A wire \
with no key here takes the name of the node it comes from.",
),
}];
static INPUTS: &[SlotDecl] = &[
SlotDecl { name: "arrays", kind: SlotType::Array, trigger_process: true, multi: true, required: false },
SlotDecl { name: "strings", kind: SlotType::String, trigger_process: true, multi: true, required: false },
SlotDecl { name: "tables", kind: SlotType::Table, trigger_process: true, multi: true, required: false },
];
static OUTPUTS: &[OutputDecl] = &[OutputDecl { name: "out", kind: SlotType::Table }];
static MANIFEST: Manifest = Manifest {
tags: &[Tag::Transform],
doc: "Several wires become one table, each under a key.",
inputs: INPUTS,
outputs: OUTPUTS,
params: PARAMS,
producer: false,
};
goofi_signal_sdk::export!(Table, MANIFEST);This reference describes goofi 3.1.0(537cd394), generated from a running instance on 2026-09-06.