diff --git a/internal/core/model.rs b/internal/core/model.rs index 6d2adeb5f73..83a7022e5ab 100644 --- a/internal/core/model.rs +++ b/internal/core/model.rs @@ -896,27 +896,30 @@ impl Repeater { model: &ModelRc, count: usize, ) -> bool { + let mut indices_to_init = Vec::new(); let mut inner = self.0.inner.borrow_mut(); inner.components.resize_with(count, || (RepeatedComponentState::Dirty, None)); let offset = inner.offset; let mut any_items_created = false; for (i, c) in inner.components.iter_mut().enumerate() { if c.0 == RepeatedComponentState::Dirty { - let created = if c.1.is_none() { + if c.1.is_none() { any_items_created = true; c.1 = Some(init()); - true - } else { - false + indices_to_init.push(i); }; c.1.as_ref().unwrap().update(i + offset, model.row_data(i + offset).unwrap()); - if created { - c.1.as_ref().unwrap().init(); - } c.0 = RepeatedComponentState::Clean; } } self.data().is_dirty.set(false); + + drop(inner); + let inner = self.0.inner.borrow(); + for item in indices_to_init.into_iter().filter_map(|index| inner.components.get(index)) { + item.1.as_ref().unwrap().init(); + } + any_items_created } diff --git a/tests/cases/models/init_recursion.slint b/tests/cases/models/init_recursion.slint new file mode 100644 index 00000000000..7e387e1ad61 --- /dev/null +++ b/tests/cases/models/init_recursion.slint @@ -0,0 +1,36 @@ +// Copyright © SixtyFPS GmbH +// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial + +TestCase := Rectangle { + property test-height: layout.preferred-height; + property test: self.test-height != 0; + + layout := VerticalLayout { + if true: TextInput { + // Trigger a call into the layout + init => { debug(self.y); } + } + } +} + +/* +```cpp +auto handle = TestCase::create(); +const TestCase &instance = *handle; + +assert(instance.get_test_height() != 0.); +``` + + +```rust +let instance = TestCase::new().unwrap(); + +assert!(instance.get_test_height() != 0.); +``` + +```js +var instance = new slint.TestCase(); + +assert(instance.test_height != 0.); +``` +*/