Repository: GraphiteEditor/Graphite
File: node-graph/gcore/src/vector/vector_nodes.rs (Rust)

Code before:
}
#[node_macro::node(category("Vector: Modifier"), path(graphene_core::vector))]
fn extract_vector(ctx: impl Ctx + ExtractVarArgs) -> Table<Vector> {
	let Ok(var_arg) = ctx.vararg(0) else { return Default::default() };
	let var_arg = var_arg as &dyn std::any::Any;
	var_arg.downcast_ref().cloned().unwrap_or_default()
}

#[node_macro::node(category("Vector: Modifier"), path(graphene_core::vector))]
async fn map(ctx: impl Ctx + CloneVarArgs + ExtractAll, content: Table<Vector>, map_fn: impl Node<Context<'static>, Output = Table<Vector>>) -> Table<Vector> {
	let mut rows = Vec::new();
	for (i, row) in content.into_iter().enumerate() {
		let owned_ctx = OwnedContextImpl::from(ctx.clone());
		let owned_ctx = owned_ctx.with_vararg(Box::new(Table::new_from_row(row))).with_index(i);
		let table = map_fn.eval(owned_ctx.into_context()).await;
		for inner_row in table {
			rows.push(inner_row);
		}
	}
	rows.into_iter().collect()
}

#[node_macro::node(category("Vector"), path(graphene_core::vector))]
async fn flatten_path<I: 'n + Send>(_: impl Ctx, #[implementations(Table<Graphic>, Table<Vector>)] content: Table<I>) -> Table<Vector>
where
	Graphic: From<Table<I>>,
{
	// NOTE(AdamGerhant):
	// A node-based solution to support passing through vector data could be a network node with a cache node
	// connected to a Flatten Path connected to an if else node, another connection from the cache directly to
	// the if else node, and another connection from the cache to a matches type node connected to the if else node.

	fn flatten_table(output: &mut TableRowMut<Vector>, graphic_table: &Table<Graphic>) {
		for (current_index, current_element) in graphic_table.iter().enumerate() {
			match current_element.element {
				Graphic::Vector(vector) => {
					// Loop through every row of the `Table<Vector>` and concatenate each element's subpath into the output `Vector` element.
					for (vector_index, row) in vector.iter().enumerate() {
						let other = row.element;
						let transform = *current_element.transform * *row.transform;
						let node_id = current_element.source_node_id.map(|node_id| node_id.0).unwrap_or_default();

						let mut hasher = DefaultHasher::new();
						(current_index, vector_index, node_id).hash(&mut hasher);
						let collision_hash_seed = hasher.finish();

						output.element.concat(other, transform, collision_hash_seed);

						// Use the last encountered style as the output style
						output.element.style = row.element.style.clone();
					}

Review comment (refactor):
```suggestion

#[node_macro::node(category("Vector: Modifier"), path(graphene_core::vector))]
fn instance_vector(ctx: impl Ctx + ExtractVarArgs) -> Table<Vector> {
	let Ok(var_arg) = ctx.vararg(0) else { return Default::default() };
	let var_arg = var_arg as &dyn std::any::Any;

	var_arg.downcast_ref().cloned().unwrap_or_default()
}

#[node_macro::node(category("Vector: Modifier"), path(graphene_core::vector))]
async fn instance_map(ctx: impl Ctx + CloneVarArgs + ExtractAll, content: Table<Vector>, mapped: impl Node<Context<'static>, Output = Table<Vector>>) -> Table<Vector> {
	let mut rows = Vec::new();

	for (i, row) in content.into_iter().enumerate() {
		let owned_ctx = OwnedContextImpl::from(ctx.clone());
		let owned_ctx = owned_ctx.with_vararg(Box::new(Table::new_from_row(row))).with_index(i);
		let table = mapped.eval(owned_ctx.into_context()).await;

		for inner_row in table {
			rows.push(inner_row);
		}
	}

	rows.into_iter().collect()
}
```

Code after:
}

#[node_macro::node(category("Vector: Modifier"), path(graphene_core::vector))]
fn instance_vector(ctx: impl Ctx + ExtractVarArgs) -> Table<Vector> {
	let Ok(var_arg) = ctx.vararg(0) else { return Default::default() };
	let var_arg = var_arg as &dyn std::any::Any;

	var_arg.downcast_ref().cloned().unwrap_or_default()
}

#[node_macro::node(category("Vector: Modifier"), path(graphene_core::vector))]
async fn instance_map(ctx: impl Ctx + CloneVarArgs + ExtractAll, content: Table<Vector>, mapped: impl Node<Context<'static>, Output = Table<Vector>>) -> Table<Vector> {
	let mut rows = Vec::new();

	for (i, row) in content.into_iter().enumerate() {
		let owned_ctx = OwnedContextImpl::from(ctx.clone());
		let owned_ctx = owned_ctx.with_vararg(Box::new(Table::new_from_row(row))).with_index(i);
		let table = mapped.eval(owned_ctx.into_context()).await;

		for inner_row in table {
			rows.push(inner_row);
		}
	}

	rows.into_iter().collect()
}

#[node_macro::node(category("Vector"), path(graphene_core::vector))]
async fn flatten_path<I: 'n + Send>(_: impl Ctx, #[implementations(Table<Graphic>, Table<Vector>)] content: Table<I>) -> Table<Vector>
where
	Graphic: From<Table<I>>,
{
	// NOTE(AdamGerhant):
	// A node-based solution to support passing through vector data could be a network node with a cache node
	// connected to a Flatten Path connected to an if else node, another connection from the cache directly to
	// the if else node, and another connection from the cache to a matches type node connected to the if else node.

	fn flatten_table(output: &mut TableRowMut<Vector>, graphic_table: &Table<Graphic>) {
		for (current_index, current_element) in graphic_table.iter().enumerate() {
			match current_element.element {
				Graphic::Vector(vector) => {
					// Loop through every row of the `Table<Vector>` and concatenate each element's subpath into the output `Vector` element.
					for (vector_index, row) in vector.iter().enumerate() {
						let other = row.element;
						let transform = *current_element.transform * *row.transform;
						let node_id = current_element.source_node_id.map(|node_id| node_id.0).unwrap_or_default();

						let mut hasher = DefaultHasher::new();
						(current_index, vector_index, node_id).hash(&mut hasher);
						let collision_hash_seed = hasher.finish();