Add experimental array.find-index predicate - #12790
Conversation
31f0559 to
b9e5867
Compare
b9e5867 to
10559b4
Compare
| (0..model.row_count()) | ||
| .find(|index| { | ||
| model.model_tracker().track_row_data_changes(*index); | ||
| predicate(model.row_data(*index).unwrap_or_default()) |
There was a problem hiding this comment.
How about something like
| predicate(model.row_data(*index).unwrap_or_default()) | |
| model.row_data(*index).is_some_and(predicate) |
Then we don't need T:Default
There was a problem hiding this comment.
Done — applied the suggestion and dropped the T: Default bound.
| model.model_tracker().track_row_count_changes(); | ||
| (0..model.row_count()) | ||
| .find(|index| { | ||
| model.model_tracker().track_row_data_changes(*index); |
There was a problem hiding this comment.
I think this might be expensive to track all row like that.
we might need a better system to track_any_change or something like that.
anyway, the any and all have the same problem.
There was a problem hiding this comment.
Agreed — since any/all have the same per-row tracking cost, I'd rather tackle a track_any_change-style mechanism for all three in a follow-up than special-case find-index here.
There was a problem hiding this comment.
Follow-up implementing track_any_change: #12806
| /// Evaluates `predicate` against each row of `model`, binding `arg_name` to the row value. | ||
| /// Stops as soon as `on_result` returns `Some`; shared by `ArrayAny`/`ArrayAll`/`ArrayFindIndex`, | ||
| /// which differ only in what they do with each row's boolean result. | ||
| fn eval_array_row_predicate<R>( |
There was a problem hiding this comment.
We should be able to re-use i_slint_core::model::model_find_index
There was a problem hiding this comment.
Done — the interpreter now reuses model_any/model_all/model_find_index from core for the iteration and dependency tracking; what's left in eval.rs is only the per-row "bind the closure arg, evaluate, restore the shadowed local" part that's inherently interpreter-specific.
Sibling to the array.any/array.all predicates (slint-ui#11989): returns the index of the first element for which the closure holds, or -1 if none match. Mirrors any/all end-to-end — parser/lookup, resolving, Rust and C++ codegen, api/cpp/include/private/slint_models.h, the interpreter, and core::model::model_find_index — reusing the existing Expression::Closure/ Type::Closure plumbing. Same experimental gate as any/all (tracked by slint-ui#12777); only usable inline, not stored or passed around, for the same reasons any/all are restricted that way. The interpreter reuses core's model_any/model_all/model_find_index for the row iteration and dependency tracking, rather than open-coding the loop a second time; a small eval_array_row_predicate helper does the per-row work shared by any/all/find-index (bind arg_name, evaluate the closure expression, restore the shadowed local var). Added as groundwork for a real fix to slint-ui#11970 (ComboBox/RadioGroup current-value writes), which needs a value-to-index reverse lookup that plain any/all can't express. changelog: Added an experimental `array.find-index((name) => condition)` predicate, returning the index of the first matching element or -1.
10559b4 to
89ef1de
Compare
Summary
Sibling to the
array.any/array.allpredicates (#11989):array.find-index((name) => condition)returns the index of the first element for which the closure holds, or-1if none match.Mirrors
any/allend-to-end — parser/lookup, resolving, Rust and C++ codegen,api/cpp/include/private/slint_models.h, the interpreter, andcore::model::model_find_index— reusing the existingExpression::Closure/Type::Closureplumbing. Same experimental gate asany/all(tracked by #12777); only usable inline, not stored or passed around, for the same reasonsany/allare restricted that way.The interpreter's per-row "evaluate the closure against this row" loop is shared with
any/allvia a smalleval_array_row_predicatehelper rather than copy-pasted into a third arm —any/all/find-indexdiffer only in what they do with each row's boolean result.This is part 1 of a 3-PR stack:
array.find-index, the experimental predicate.array.index-of, a stable value-based sibling that desugars tofind-index.current-valuewrites toindex-of, closing ComboBox and RadioGroup: writes tocurrent-valueare silently overridden #11970.Test plan
cargo test -p i-slint-compiler --features display-diagnostics --test syntax_testsSLINT_TEST_FILTER=array_predicates cargo test --manifest-path tests/Cargo.toml -p test-driver-{interpreter,rust,cpp,nodejs}