mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-03 02:13:21 +00:00
C++ live-reload: support getting the model back
This commit is contained in:
parent
43b436a89f
commit
01850e0b82
4 changed files with 67 additions and 18 deletions
|
@ -82,13 +82,9 @@ inline interpreter::Value into_slint_value(const long int &val)
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename ModelData>
|
template<typename ModelData>
|
||||||
inline std::shared_ptr<slint::Model<ModelData>>
|
std::shared_ptr<slint::Model<ModelData>>
|
||||||
from_slint_value(const slint::interpreter::Value &,
|
from_slint_value(const slint::interpreter::Value &,
|
||||||
const std::shared_ptr<slint::Model<ModelData>> *)
|
const std::shared_ptr<slint::Model<ModelData>> *);
|
||||||
{
|
|
||||||
std::cout << "NOT IMPLEMENTED " << __PRETTY_FUNCTION__ << std::endl;
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename ModelData>
|
template<typename ModelData>
|
||||||
slint::interpreter::Value into_slint_value(const std::shared_ptr<slint::Model<ModelData>> &val);
|
slint::interpreter::Value into_slint_value(const std::shared_ptr<slint::Model<ModelData>> &val);
|
||||||
|
@ -297,11 +293,28 @@ protected:
|
||||||
return interpreter::Value(cbindgen_private::slint_interpreter_value_new_model(
|
return interpreter::Value(cbindgen_private::slint_interpreter_value_new_model(
|
||||||
reinterpret_cast<uint8_t *>(wrapper.get()), vtable()));
|
reinterpret_cast<uint8_t *>(wrapper.get()), vtable()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
// get the model wrapper from a value (or nullptr if the value don't contain a model)
|
||||||
|
static const LiveReloadModelWrapperBase *get(const slint::interpreter::Value &value)
|
||||||
|
{
|
||||||
|
if (auto model =
|
||||||
|
cbindgen_private::slint_interpreter_value_to_model(value.inner, vtable())) {
|
||||||
|
return reinterpret_cast<const LiveReloadModelWrapperBase *>(model);
|
||||||
|
} else {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename ModelData>
|
template<typename ModelData>
|
||||||
class LiveReloadModelWrapper : public LiveReloadModelWrapperBase
|
class LiveReloadModelWrapper : public LiveReloadModelWrapperBase
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
LiveReloadModelWrapper(std::shared_ptr<slint::Model<ModelData>> model) : model(std::move(model))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<slint::Model<ModelData>> model = nullptr;
|
std::shared_ptr<slint::Model<ModelData>> model = nullptr;
|
||||||
|
|
||||||
int row_count() const override { return model->row_count(); }
|
int row_count() const override { return model->row_count(); }
|
||||||
|
@ -319,11 +332,6 @@ class LiveReloadModelWrapper : public LiveReloadModelWrapperBase
|
||||||
model->set_row_data(i, from_slint_value<ModelData>(value));
|
model->set_row_data(i, from_slint_value<ModelData>(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
LiveReloadModelWrapper(std::shared_ptr<slint::Model<ModelData>> model) : model(std::move(model))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static slint::interpreter::Value wrap(std::shared_ptr<slint::Model<ModelData>> model)
|
static slint::interpreter::Value wrap(std::shared_ptr<slint::Model<ModelData>> model)
|
||||||
{
|
{
|
||||||
auto self = std::make_shared<LiveReloadModelWrapper<ModelData>>(model);
|
auto self = std::make_shared<LiveReloadModelWrapper<ModelData>>(model);
|
||||||
|
@ -342,6 +350,19 @@ slint::interpreter::Value into_slint_value(const std::shared_ptr<slint::Model<Mo
|
||||||
return LiveReloadModelWrapper<ModelData>::wrap(val);
|
return LiveReloadModelWrapper<ModelData>::wrap(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename ModelData>
|
||||||
|
std::shared_ptr<slint::Model<ModelData>>
|
||||||
|
from_slint_value(const slint::interpreter::Value &value,
|
||||||
|
const std::shared_ptr<slint::Model<ModelData>> *)
|
||||||
|
{
|
||||||
|
if (const LiveReloadModelWrapperBase *base = LiveReloadModelWrapperBase::get(value)) {
|
||||||
|
if (auto wrapper = dynamic_cast<const LiveReloadModelWrapper<ModelData> *>(base)) {
|
||||||
|
return wrapper->model;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace slint::private_api::live_reload
|
} // namespace slint::private_api::live_reload
|
||||||
|
|
||||||
#endif // SLINT_FEATURE_LIVE_RELOAD
|
#endif // SLINT_FEATURE_LIVE_RELOAD
|
||||||
|
|
|
@ -441,6 +441,12 @@ fn convert_to_value_fn(ty: &Type) -> String {
|
||||||
});
|
});
|
||||||
format!("([](const auto &tuple) {{ slint::interpreter::Struct s; {}return slint::interpreter::Value(s); }})", init.join(""))
|
format!("([](const auto &tuple) {{ slint::interpreter::Struct s; {}return slint::interpreter::Value(s); }})", init.join(""))
|
||||||
}
|
}
|
||||||
|
// Array of anonymous struct
|
||||||
|
Type::Array(a) if matches!(a.as_ref(), Type::Struct(s) if s.name.is_none()) => {
|
||||||
|
let conf_fn = convert_to_value_fn(&a);
|
||||||
|
let aty = a.cpp_type().unwrap();
|
||||||
|
format!("([](const auto &model) {{ return slint::interpreter::Value(std::make_shared<slint::MapModel<{aty}, slint::interpreter::Value>>(model, {conf_fn})); }})")
|
||||||
|
}
|
||||||
_ => "into_slint_value".into(),
|
_ => "into_slint_value".into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,24 @@ pub unsafe extern "C" fn slint_interpreter_value_new_model(
|
||||||
)))))
|
)))))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// If the value contains a model set from [`slint_interpreter_value_new_model]` with the same vtable pointer,
|
||||||
|
/// return the model that was set.
|
||||||
|
/// Returns a null ptr otherwise
|
||||||
|
#[unsafe(no_mangle)]
|
||||||
|
pub extern "C" fn slint_interpreter_value_to_model(
|
||||||
|
val: &Value,
|
||||||
|
vtable: &ModelAdaptorVTable,
|
||||||
|
) -> *const u8 {
|
||||||
|
if let Value::Model(m) = val {
|
||||||
|
if let Some(m) = m.as_any().downcast_ref::<ModelAdaptorWrapper>() {
|
||||||
|
if core::ptr::eq(m.0.get_vtable() as *const _, vtable as *const _) {
|
||||||
|
return m.0.as_ptr();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
core::ptr::null()
|
||||||
|
}
|
||||||
|
|
||||||
#[unsafe(no_mangle)]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn slint_interpreter_value_type(val: &Value) -> ValueType {
|
pub unsafe extern "C" fn slint_interpreter_value_type(val: &Value) -> ValueType {
|
||||||
val.value_type()
|
val.value_type()
|
||||||
|
@ -575,6 +593,10 @@ impl Model for ModelAdaptorWrapper {
|
||||||
let val = Box::new(data);
|
let val = Box::new(data);
|
||||||
self.0.set_row_data(row, val);
|
self.0.set_row_data(row, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &dyn core::any::Any {
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
|
|
@ -312,7 +312,7 @@ mod ffi {
|
||||||
use i_slint_core::{slice::Slice, SharedString, SharedVector};
|
use i_slint_core::{slice::Slice, SharedString, SharedVector};
|
||||||
type LiveReloadingComponentInner = RefCell<LiveReloadingComponent>;
|
type LiveReloadingComponentInner = RefCell<LiveReloadingComponent>;
|
||||||
|
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
/// LibraryPath is an array of string that have in the form `lib=...`
|
/// LibraryPath is an array of string that have in the form `lib=...`
|
||||||
pub extern "C" fn slint_live_reload_new(
|
pub extern "C" fn slint_live_reload_new(
|
||||||
file_name: Slice<u8>,
|
file_name: Slice<u8>,
|
||||||
|
@ -345,19 +345,19 @@ mod ffi {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn slint_live_reload_clone(
|
pub unsafe extern "C" fn slint_live_reload_clone(
|
||||||
component: *const LiveReloadingComponentInner,
|
component: *const LiveReloadingComponentInner,
|
||||||
) {
|
) {
|
||||||
Rc::increment_strong_count(component);
|
Rc::increment_strong_count(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn slint_live_reload_drop(component: *const LiveReloadingComponentInner) {
|
pub unsafe extern "C" fn slint_live_reload_drop(component: *const LiveReloadingComponentInner) {
|
||||||
Rc::decrement_strong_count(component);
|
Rc::decrement_strong_count(component);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub extern "C" fn slint_live_reload_set_property(
|
pub extern "C" fn slint_live_reload_set_property(
|
||||||
component: &LiveReloadingComponentInner,
|
component: &LiveReloadingComponentInner,
|
||||||
property: Slice<u8>,
|
property: Slice<u8>,
|
||||||
|
@ -371,7 +371,7 @@ mod ffi {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub extern "C" fn slint_live_reload_get_property(
|
pub extern "C" fn slint_live_reload_get_property(
|
||||||
component: &LiveReloadingComponentInner,
|
component: &LiveReloadingComponentInner,
|
||||||
property: Slice<u8>,
|
property: Slice<u8>,
|
||||||
|
@ -385,7 +385,7 @@ mod ffi {
|
||||||
Box::into_raw(Box::new(val))
|
Box::into_raw(Box::new(val))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub extern "C" fn slint_live_reload_invoke(
|
pub extern "C" fn slint_live_reload_invoke(
|
||||||
component: &LiveReloadingComponentInner,
|
component: &LiveReloadingComponentInner,
|
||||||
callback: Slice<u8>,
|
callback: Slice<u8>,
|
||||||
|
@ -401,7 +401,7 @@ mod ffi {
|
||||||
Box::into_raw(Box::new(val))
|
Box::into_raw(Box::new(val))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[unsafe(no_mangle)]
|
||||||
pub unsafe extern "C" fn slint_live_reload_set_callback(
|
pub unsafe extern "C" fn slint_live_reload_set_callback(
|
||||||
component: &LiveReloadingComponentInner,
|
component: &LiveReloadingComponentInner,
|
||||||
callback: Slice<u8>,
|
callback: Slice<u8>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue