Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions node-graph/gcore/src/context_modification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ async fn context_modification<T>(
Context -> Vec<NodeId>,
Context -> Vec<f64>,
Context -> Vec<f32>,
Context -> Vec<String>,
Context -> Table<Vector>,
Context -> Table<Graphic>,
Context -> Table<Raster<CPU>>,
Expand Down
1 change: 1 addition & 0 deletions node-graph/gcore/src/graphic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -451,6 +451,7 @@ fn index<T: AtIndex + Clone + Default>(
Vec<u32>,
Vec<u64>,
Vec<DVec2>,
Vec<String>,
Table<Artboard>,
Table<Graphic>,
Table<Vector>,
Expand Down
11 changes: 11 additions & 0 deletions node-graph/gcore/src/logic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,17 @@ fn string_length(_: impl Ctx, string: String) -> f64 {
string.chars().count() as f64
}

#[node_macro::node(category("Text"))]
fn string_split(_: impl Ctx, string: String, #[default("\\n")] delimeter: String, #[default(true)] delimeter_escaping: bool) -> Vec<String> {
let delimeter = if delimeter_escaping {
delimeter.replace("\\n", "\n").replace("\\r", "\r").replace("\\t", "\t").replace("\\0", "\0").replace("\\\\", "\\")
} else {
delimeter
};

string.split(&delimeter).map(str::to_string).collect()
}

/// Evaluates either the "If True" or "If False" input branch based on whether the input condition is true or false.
#[node_macro::node(category("Math: Logic"))]
async fn switch<T, C: Send + 'n + Clone>(
Expand Down
32 changes: 30 additions & 2 deletions node-graph/gcore/src/vector/vector_nodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1954,11 +1954,39 @@ fn point_inside(_: impl Ctx, source: Table<Vector>, point: DVec2) -> bool {
source.into_iter().any(|row| row.element.check_point_inside_shape(row.transform, point))
}

trait Count {
fn count(&self) -> usize;
}
impl<T> Count for Table<T> {
fn count(&self) -> usize {
self.len()
}
}
impl<T> Count for Vec<T> {
fn count(&self) -> usize {
self.len()
}
}

// TODO: Return u32, u64, or usize instead of f64 after #1621 is resolved and has allowed us to implement automatic type conversion in the node graph for nodes with generic type inputs.
// TODO: (Currently automatic type conversion only works for concrete types, via the Graphene preprocessor and not the full Graphene type system.)
#[node_macro::node(category("General"), path(graphene_core::vector))]
async fn count_elements<I>(_: impl Ctx, #[implementations(Table<Graphic>, Table<Vector>, Table<Raster<CPU>>, Table<Raster<GPU>>, Table<Color>, Table<GradientStops>)] source: Table<I>) -> f64 {
source.len() as f64
async fn count_elements<I: Count>(
_: impl Ctx,
#[implementations(
Table<Graphic>,
Table<Vector>,
Table<Raster<CPU>>,
Table<Raster<GPU>>,
Table<Color>,
Table<GradientStops>,
Vec<String>,
Vec<f64>,
Vec<DVec2>,
)]
source: I,
) -> f64 {
source.count() as f64
}

#[node_macro::node(category("Vector: Measure"), path(graphene_core::vector))]
Expand Down
2 changes: 2 additions & 0 deletions node-graph/interpreted-executor/src/node_registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => graphene_std::vector::misc::PointSpacingType]),
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => Option<f64>]),
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => Vec<DVec2>]),
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => Vec<String>]),
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => [f64; 4]]),
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => Vec<NodeId>]),
async_node!(graphene_core::memo::MonitorNode<_, _, _>, input: Context, fn_params: [Context => Graphic]),
Expand Down Expand Up @@ -165,6 +166,7 @@ fn node_registry() -> HashMap<ProtoNodeIdentifier, HashMap<NodeIOTypes, NodeCons
async_node!(graphene_core::memo::MemoNode<_, _>, input: Context, fn_params: [Context => Vec<NodeId>]),
async_node!(graphene_core::memo::MemoNode<_, _>, input: Context, fn_params: [Context => Vec<f64>]),
async_node!(graphene_core::memo::MemoNode<_, _>, input: Context, fn_params: [Context => Vec<f32>]),
async_node!(graphene_core::memo::MemoNode<_, _>, input: Context, fn_params: [Context => Vec<String>]),
#[cfg(feature = "gpu")]
async_node!(graphene_core::memo::MemoNode<_, _>, input: Context, fn_params: [Context => Arc<WasmSurfaceHandle>]),
async_node!(graphene_core::memo::MemoNode<_, _>, input: Context, fn_params: [Context => WindowHandle]),
Expand Down
10 changes: 9 additions & 1 deletion node-graph/node-macro/src/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,15 @@ pub(crate) fn generate_node_code(crate_ident: &CrateIdent, parsed: &ParsedNodeFn
.iter()
.map(|field| match &field.ty {
ParsedFieldType::Regular(RegularParsedField { value_source, .. }) => match value_source {
ParsedValueSource::Default(data) => quote!(RegistryValueSource::Default(stringify!(#data))),
ParsedValueSource::Default(data) => {
// Check if the data is a string literal by parsing the token stream
let data_str = data.to_string();
if data_str.starts_with('"') && data_str.ends_with('"') && data_str.len() >= 2 {
quote!(RegistryValueSource::Default(#data))
} else {
quote!(RegistryValueSource::Default(stringify!(#data)))
}
}
ParsedValueSource::Scope(data) => quote!(RegistryValueSource::Scope(#data)),
_ => quote!(RegistryValueSource::None),
},
Expand Down
Loading