Skip to content
Draft
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
30 changes: 30 additions & 0 deletions api/cpp/include/slint_models.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,36 @@ long int model_length(const std::shared_ptr<M> &model)
}
}

template<typename M, typename P>
bool model_any(const std::shared_ptr<M> &model, P predicate)
{
long int count = model_length(model);

for (long int i = 0; i < count; ++i) {
auto data = access_array_index(model, i);
if (predicate(data)) {
return true;
}
}

return false;
}

template<typename M, typename P>
bool model_all(const std::shared_ptr<M> &model, P predicate)
{
long int count = model_length(model);

for (long int i = 0; i < count; ++i) {
auto data = access_array_index(model, i);
if (!predicate(data)) {
return false;
}
}

return true;
}

} // namespace private_api

/// \rst
Expand Down
3 changes: 2 additions & 1 deletion api/node/rust/interpreter/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,8 @@ pub fn to_value(env: &Env, unknown: JsUnknown, typ: &Type) -> Result<Value> {
| Type::Easing
| Type::PathData
| Type::LayoutCache
| Type::ElementReference => Err(napi::Error::from_reason("reason")),
| Type::ElementReference
| Type::Predicate => Err(napi::Error::from_reason("reason")),
}
}

Expand Down
3 changes: 2 additions & 1 deletion internal/compiler/builtin_macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,8 @@ fn to_debug_string(
| Type::ElementReference
| Type::LayoutCache
| Type::Model
| Type::PathData => {
| Type::PathData
| Type::Predicate => {
diag.push_error("Cannot debug this expression".into(), node);
Expression::Invalid
}
Expand Down
19 changes: 19 additions & 0 deletions internal/compiler/expression_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ pub enum BuiltinFunction {
ColorWithAlpha,
ImageSize,
ArrayLength,
ArrayAny,
ArrayAll,
Rgb,
Hsv,
ColorScheme,
Expand Down Expand Up @@ -239,6 +241,8 @@ declare_builtin_function_types!(
rust_attributes: None,
})),
ArrayLength: (Type::Model) -> Type::Int32,
ArrayAny: (Type::Model, Type::Predicate) -> Type::Bool,
ArrayAll: (Type::Model, Type::Predicate) -> Type::Bool,
Rgb: (Type::Int32, Type::Int32, Type::Int32, Type::Float32) -> Type::Color,
Hsv: (Type::Float32, Type::Float32, Type::Float32, Type::Float32) -> Type::Color,
ColorScheme: () -> Type::Enumeration(
Expand Down Expand Up @@ -359,6 +363,8 @@ impl BuiltinFunction {
BuiltinFunction::StartTimer => false,
BuiltinFunction::StopTimer => false,
BuiltinFunction::RestartTimer => false,
BuiltinFunction::ArrayAny => true,
BuiltinFunction::ArrayAll => true,
}
}

Expand Down Expand Up @@ -435,6 +441,8 @@ impl BuiltinFunction {
BuiltinFunction::StartTimer => false,
BuiltinFunction::StopTimer => false,
BuiltinFunction::RestartTimer => false,
BuiltinFunction::ArrayAny => true,
BuiltinFunction::ArrayAll => true,
}
}
}
Expand Down Expand Up @@ -750,6 +758,11 @@ pub enum Expression {
},

EmptyComponentFactory,

Predicate {
arg_name: SmolStr,
expression: Box<Expression>,
},
}

impl Expression {
Expand Down Expand Up @@ -871,6 +884,7 @@ impl Expression {
Expression::MinMax { ty, .. } => ty.clone(),
Expression::EmptyComponentFactory => Type::ComponentFactory,
Expression::DebugHook { expression, .. } => expression.ty(),
Expression::Predicate { .. } => Type::Predicate,
}
}

Expand Down Expand Up @@ -966,6 +980,7 @@ impl Expression {
}
Expression::EmptyComponentFactory => {}
Expression::DebugHook { expression, .. } => visitor(expression),
Expression::Predicate { expression, .. } => visitor(expression),
}
}

Expand Down Expand Up @@ -1063,6 +1078,7 @@ impl Expression {
}
Expression::EmptyComponentFactory => {}
Expression::DebugHook { expression, .. } => visitor(expression),
Expression::Predicate { expression, .. } => visitor(expression),
}
}

Expand Down Expand Up @@ -1145,6 +1161,7 @@ impl Expression {
Expression::MinMax { lhs, rhs, .. } => lhs.is_constant() && rhs.is_constant(),
Expression::EmptyComponentFactory => true,
Expression::DebugHook { .. } => false,
Expression::Predicate { expression, .. } => expression.is_constant(),
}
}

Expand Down Expand Up @@ -1378,6 +1395,7 @@ impl Expression {
Expression::EnumerationValue(enumeration.clone().default_value())
}
Type::ComponentFactory => Expression::EmptyComponentFactory,
Type::Predicate => Expression::Invalid,
}
}

Expand Down Expand Up @@ -1788,5 +1806,6 @@ pub fn pretty_print(f: &mut dyn std::fmt::Write, expression: &Expression) -> std
pretty_print(f, expression)?;
write!(f, "\"{id}\")")
}
Expression::Predicate { .. } => todo!(),
}
}
12 changes: 12 additions & 0 deletions internal/compiler/generator/cpp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3520,6 +3520,12 @@ fn compile_expression(expr: &llr::Expression, ctx: &EvaluationContext) -> String
None => format!("slint::private_api::translate_from_bundle(slint_translation_bundle_{string_index}, {args})"),
}
},
Expression::Predicate { arg_name, expression } => {
let arg = ident(arg_name);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking we probably want to add some kind of prefix here. For example pred_arg_{} so that you don't get mismatch with existing local variables. (and then we need to figure out that the ReadLocalVariable is actually reading a predicate of this name)

let expr = compile_expression(expression, ctx);

format!("[&](auto {arg}) -> bool {{ return {expr}; }}")
},
}
}

Expand Down Expand Up @@ -4012,6 +4018,12 @@ fn compile_builtin_function_call(
panic!("internal error: invalid args to RetartTimer {arguments:?}")
}
}
BuiltinFunction::ArrayAny => {
format!("slint::private_api::model_any({}, {})", a.next().unwrap(), a.next().unwrap())
},
BuiltinFunction::ArrayAll => {
format!("slint::private_api::model_all({}, {})", a.next().unwrap(), a.next().unwrap())
},
}
}

Expand Down
29 changes: 29 additions & 0 deletions internal/compiler/generator/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2677,6 +2677,13 @@ fn compile_expression(expr: &Expression, ctx: &EvaluationContext) -> TokenStream

}
},
Expression::Predicate { arg_name, expression } => {
let arg_name = ident(arg_name);
let expression = compile_expression(expression, ctx);
quote! {
|#arg_name| {#expression}
}
},
}
}

Expand Down Expand Up @@ -3296,6 +3303,28 @@ fn compile_builtin_function_call(
panic!("internal error: invalid args to RetartTimer {arguments:?}")
}
}
BuiltinFunction::ArrayAny => {
if let [_, Expression::Predicate { .. }] = arguments {
let arr_expression = a.next().unwrap();
let predicate_expression = a.next().unwrap();
quote!(match #arr_expression { x => {
x.iter().any(#predicate_expression)
}})
} else {
panic!("internal error: invalid args to ArrayAny {arguments:?}")
}
}
BuiltinFunction::ArrayAll => {
if let [_, Expression::Predicate { .. }] = arguments {
let arr_expression = a.next().unwrap();
let predicate_expression = a.next().unwrap();
quote!(match #arr_expression { x => {
x.iter().all(#predicate_expression)
}})
} else {
panic!("internal error: invalid args to ArrayAll {arguments:?}")
}
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions internal/compiler/langtype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ pub enum Type {

/// This is a `SharedArray<f32>`
LayoutCache,
Predicate,
}

impl core::cmp::PartialEq for Type {
Expand Down Expand Up @@ -104,6 +105,7 @@ impl core::cmp::PartialEq for Type {
Type::UnitProduct(a) => matches!(other, Type::UnitProduct(b) if a == b),
Type::ElementReference => matches!(other, Type::ElementReference),
Type::LayoutCache => matches!(other, Type::LayoutCache),
Type::Predicate => matches!(other, Type::Predicate),
}
}
}
Expand Down Expand Up @@ -178,6 +180,7 @@ impl Display for Type {
}
Type::ElementReference => write!(f, "element ref"),
Type::LayoutCache => write!(f, "layout cache"),
Type::Predicate => write!(f, "predicate"),
}
}
}
Expand Down Expand Up @@ -314,6 +317,7 @@ impl Type {
Type::UnitProduct(_) => None,
Type::ElementReference => None,
Type::LayoutCache => None,
Type::Predicate => None,
}
}

Expand Down
12 changes: 11 additions & 1 deletion internal/compiler/llr/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,11 @@ pub enum Expression {
/// The `n` value to use for the plural form if it is a plural form
plural: Option<Box<Expression>>,
},

Predicate {
arg_name: SmolStr,
expression: Box<Expression>,
},
}

impl Expression {
Expand All @@ -217,7 +222,8 @@ impl Expression {
| Type::InferredProperty
| Type::InferredCallback
| Type::ElementReference
| Type::LayoutCache => return None,
| Type::LayoutCache
| Type::Predicate => return None,
Type::Float32
| Type::Duration
| Type::Int32
Expand Down Expand Up @@ -320,6 +326,7 @@ impl Expression {
Self::MinMax { ty, .. } => ty.clone(),
Self::EmptyComponentFactory => Type::ComponentFactory,
Self::TranslationReference { .. } => Type::String,
Self::Predicate { .. } => Type::Predicate,
}
}
}
Expand Down Expand Up @@ -409,6 +416,9 @@ macro_rules! visit_impl {
$visitor(plural);
}
}
Expression::Predicate { expression, .. } => {
$visitor(expression);
}
}
};
}
Expand Down
4 changes: 4 additions & 0 deletions internal/compiler/llr/lower_expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,10 @@ pub fn lower_expression(
},
tree_Expression::EmptyComponentFactory => llr_Expression::EmptyComponentFactory,
tree_Expression::DebugHook { expression, .. } => lower_expression(expression, ctx),
tree_Expression::Predicate { arg_name, expression } => llr_Expression::Predicate {
arg_name: arg_name.clone(),
expression: Box::new(lower_expression(expression, ctx)),
},
}
}

Expand Down
3 changes: 3 additions & 0 deletions internal/compiler/llr/optim_passes/inline_expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ fn expression_cost(exp: &Expression, ctx: &EvaluationContext) -> isize {
Expression::MinMax { .. } => 10,
Expression::EmptyComponentFactory => 10,
Expression::TranslationReference { .. } => PROPERTY_ACCESS_COST + 2 * ALLOC_COST,
Expression::Predicate { expression, .. } => expression_cost(expression, ctx),
};

exp.visit(|e| cost = cost.saturating_add(expression_cost(e, ctx)));
Expand Down Expand Up @@ -153,6 +154,8 @@ fn builtin_function_cost(function: &BuiltinFunction) -> isize {
BuiltinFunction::StartTimer => 10,
BuiltinFunction::StopTimer => 10,
BuiltinFunction::RestartTimer => 10,
BuiltinFunction::ArrayAny => isize::MAX,
BuiltinFunction::ArrayAll => isize::MAX,
}
}

Expand Down
1 change: 1 addition & 0 deletions internal/compiler/llr/pretty_print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ impl<'a, T> Display for DisplayExpression<'a, T> {
),
}
}
Expression::Predicate { .. } => todo!(),
}
}
}
Loading
Loading