This was a regression following the move to the edition 2021.
The CallbackUserData was not capture in the lamda, its member were moved.
So the destructor was called right after it was set.
We must make sure we capture the whole CallbackUserData, so put the callback
inside of it. This also reduce a bit of code duplication at the same time.
Test the callback invokation with statefull lambda
We want to be able to put existing functionality behind a feature flag while keeping
the semver compatibility.
This is only possible if that new feature flag is enabled by default, but this is not
working if the users have done `default-features = false` in their Cargo.toml.
So we add new `compat-x-y-z` feature that is mandatory to have and which is
enforced with a `compile_error!`
Now, users that whishes to not have the default features must enable it explicitly.
Say we want only x11 but not qt and wayland, the user will do
```toml
sixtyfps = { version = "0.2", default-features = false, features = ["x11", "compat-0-2-0"] }
```
Now, imagine that in the version 0.2.3, we put the SVG support behind a feature flag.
we will do this in out Cargo.toml:
```toml
[features]
default = ["compat-0-2-0", "x11", "wayland"]
compat-0-2-0 = ["compat-0-2-3", "svg"]
compat-0-2-3 = []
svg = [...]
...
```
That way, the svg feature will be enabled by default for all the users who used previous version
of SixtyFPS, and people that want to disable "svg" can just change from compat-0-2-0 to
compat-0-2-3 in their Cargo.toml
Move "internal" crates into the `internal` directory. This first batch
includes most of sixtyfps_runtime but leaves the rendering backends
alone for now.
pre-commit applied some cleanups to the moved files:
- Consistent newline at end of file policy
- trimming trailing whitespace
- Formatting Cargo.toml files.
Move it from corelib:🪟:api to corelib::api, where we're going to collect more types in the future
that are meant to be re-exported as public API in the sixtyfps-rs and the interpreter crate.
Implement `sixtyfps::ComponentHandle` for `ComponentInstance`, instead of providing a copy of the API.
This also removes `WeakComponentInstance` and enables the use of `sixtyfps::Weak` for weak handles. This has the advantage that `sixtyfps:Weak`'s `upgrade_in_event_loop` becomes available with the interpreter, and the
weak handle is Send.
This patch is mostly a rename now, but also contains a few small
cleanups.
SharedModel implements the Model trait itself and gracefully falls back
to an empty model is no Model was provided. This allows for some small
simplifications.
Also make sure to use the same comparision for SharedModels everywhere.
This fixes the last remaining clippy errors we had.
The C++ code did not compile because it couldn't deduce the template parameter
properly. Since the lambda became a bit big to be placed in one small string,
I moved it into a real function in the header
Example of error: (sorry for the long lines :-))
```
tmp/.tmpE42a4c.cpp: In member function 'void TestCase::init(const TestCase*, sixtyfps::cbindgen_private::ComponentWeak, uintptr_t, uintptr_t)':
/tmp/.tmpE42a4c.cpp:67:238: error: no match for call to '(TestCase::init(const TestCase*, sixtyfps::cbindgen_private::ComponentWeak, uintptr_t, uintptr_t)::<lambda(const std::shared_ptr<sixtyfps::Model<ModelData> >&, const auto:24&)>) (std::shared_ptr<sixtyfps::private_api::ArrayModel<2, sixtyfps::SharedString> >, int)'
67 | self->root_window_1_hello_world.set([&]<typename D>(const std::shared_ptr<sixtyfps::Model<D>> &model, const auto &index) -> D { model->track_row_data_changes(index); if (const auto v = model->row_data(index)) return *v; return D(); }(std::make_shared<sixtyfps::private_api::ArrayModel<2,sixtyfps::SharedString>>(sixtyfps::SharedString ( sixtyfps::SharedString(u8"hello") ), sixtyfps::SharedString ( sixtyfps::SharedString(u8"world") )), 1));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/tmp/.tmpE42a4c.cpp:67:41: note: candidate: 'template<class D, class auto:24> TestCase::init(const TestCase*, sixtyfps::cbindgen_private::ComponentWeak, uintptr_t, uintptr_t)::<lambda(const std::shared_ptr<sixtyfps::Model<ModelData> >&, const auto:24&)>'
67 | self->root_window_1_hello_world.set([&]<typename D>(const std::shared_ptr<sixtyfps::Model<D>> &model, const auto &index) -> D { model->track_row_data_changes(index); if (const auto v = model->row_data(index)) return *v; return D(); }(std::make_shared<sixtyfps::private_api::ArrayModel<2,sixtyfps::SharedString>>(sixtyfps::SharedString ( sixtyfps::SharedString(u8"hello") ), sixtyfps::SharedString ( sixtyfps::SharedString(u8"world") )), 1));
| ^
/tmp/.tmpE42a4c.cpp:67:41: note: template argument deduction/substitution failed:
/tmp/.tmpE42a4c.cpp:67:238: note: mismatched types 'sixtyfps::Model<ModelData>' and 'sixtyfps::private_api::ArrayModel<2, sixtyfps::SharedString>'
67 | self->root_window_1_hello_world.set([&]<typename D>(const std::shared_ptr<sixtyfps::Model<D>> &model, const auto &index) -> D { model->track_row_data_changes(index); if (const auto v = model->row_data(index)) return *v; return D(); }(std::make_shared<sixtyfps::private_api::ArrayModel<2,sixtyfps::SharedString>>(sixtyfps::SharedString ( sixtyfps::SharedString(u8"hello") ), sixtyfps::SharedString ( sixtyfps::SharedString(u8"world") )), 1));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
Also run set_property within run_scoped, so that later invocations of `run_with_global_context`
succeed.
Currently this happens because set_property() on a model property will check for
value type compatibility, which ends up querying the model to compare values,
which in turn calls into JsModel and then into JS (and needs run_with_global_context).
Arrays declared in .60 are mapped to a SharedVectorModel<Value> in order
to permit for write access. They can also be turned intoValue::Array /
SharedVector<Value> very cheaply, when reading from C++.