New node: String Split (#3304)
* Add two nodes for substring * fix: number convention * Remove unnecessay allocations and add support for \n in patterns * Make split node return Vec<String> and remove count_elements node * Add Cache implementations for Vec<String> * Code review --------- Co-authored-by: daniil.loban <daniil.loban@gmail.com> Co-authored-by: Dennis Kobert <dennis@kobert.dev> Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
parent
c4bbb7e880
commit
0d8c521fbe
|
|
@ -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>>,
|
||||
|
|
|
|||
|
|
@ -451,6 +451,7 @@ fn index<T: AtIndex + Clone + Default>(
|
|||
Vec<u32>,
|
||||
Vec<u64>,
|
||||
Vec<DVec2>,
|
||||
Vec<String>,
|
||||
Table<Artboard>,
|
||||
Table<Graphic>,
|
||||
Table<Vector>,
|
||||
|
|
|
|||
|
|
@ -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>(
|
||||
|
|
|
|||
|
|
@ -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))]
|
||||
|
|
|
|||
|
|
@ -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]),
|
||||
|
|
@ -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]),
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue