mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-01 06:11:16 +00:00
WIP: Remove sixtyfps_interpreter::Value::Array
This is never created
This commit is contained in:
parent
a1e9aed4ca
commit
de40e002c3
7 changed files with 75 additions and 117 deletions
|
@ -413,7 +413,7 @@ private:
|
||||||
|
|
||||||
inline Value::Value(const sixtyfps::SharedVector<Value> &array)
|
inline Value::Value(const sixtyfps::SharedVector<Value> &array)
|
||||||
{
|
{
|
||||||
cbindgen_private::sixtyfps_interpreter_value_new_array(
|
cbindgen_private::sixtyfps_interpreter_value_new_array_model(
|
||||||
&reinterpret_cast<const sixtyfps::SharedVector<ValueOpaque> &>(array), &inner);
|
&reinterpret_cast<const sixtyfps::SharedVector<ValueOpaque> &>(array), &inner);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,7 +464,8 @@ inline Value::Value(const std::shared_ptr<sixtyfps::Model<Value>> &model)
|
||||||
return reinterpret_cast<ModelWrapper *>(self.instance)->model->row_count();
|
return reinterpret_cast<ModelWrapper *>(self.instance)->model->row_count();
|
||||||
};
|
};
|
||||||
auto row_data = [](VRef<ModelAdaptorVTable> self, uintptr_t row, ValueOpaque *out) {
|
auto row_data = [](VRef<ModelAdaptorVTable> self, uintptr_t row, ValueOpaque *out) {
|
||||||
std::optional<Value> v = reinterpret_cast<ModelWrapper *>(self.instance)->model->row_data(int(row));
|
std::optional<Value> v =
|
||||||
|
reinterpret_cast<ModelWrapper *>(self.instance)->model->row_data(int(row));
|
||||||
if (v.has_value()) {
|
if (v.has_value()) {
|
||||||
*out = v->inner;
|
*out = v->inner;
|
||||||
cbindgen_private::sixtyfps_interpreter_value_new(&v->inner);
|
cbindgen_private::sixtyfps_interpreter_value_new(&v->inner);
|
||||||
|
@ -630,7 +631,9 @@ public:
|
||||||
std::optional<Value> invoke_callback(std::string_view name, std::span<const Value> args) const
|
std::optional<Value> invoke_callback(std::string_view name, std::span<const Value> args) const
|
||||||
{
|
{
|
||||||
using namespace cbindgen_private;
|
using namespace cbindgen_private;
|
||||||
Slice<ValueOpaque> args_view { const_cast<ValueOpaque *>(reinterpret_cast<const ValueOpaque *>(args.data())), args.size() };
|
Slice<ValueOpaque> args_view { const_cast<ValueOpaque *>(
|
||||||
|
reinterpret_cast<const ValueOpaque *>(args.data())),
|
||||||
|
args.size() };
|
||||||
ValueOpaque out;
|
ValueOpaque out;
|
||||||
if (sixtyfps_interpreter_component_instance_invoke_callback(
|
if (sixtyfps_interpreter_component_instance_invoke_callback(
|
||||||
inner(), sixtyfps::private_api::string_to_slice(name), args_view, &out)) {
|
inner(), sixtyfps::private_api::string_to_slice(name), args_view, &out)) {
|
||||||
|
@ -665,7 +668,8 @@ public:
|
||||||
bool set_callback(std::string_view name, F callback) const
|
bool set_callback(std::string_view name, F callback) const
|
||||||
{
|
{
|
||||||
using cbindgen_private::ValueOpaque;
|
using cbindgen_private::ValueOpaque;
|
||||||
auto actual_cb = [](void *data, cbindgen_private::Slice<ValueOpaque> arg, ValueOpaque *ret) {
|
auto actual_cb = [](void *data, cbindgen_private::Slice<ValueOpaque> arg,
|
||||||
|
ValueOpaque *ret) {
|
||||||
std::span<const Value> args_view { reinterpret_cast<const Value *>(arg.ptr), arg.len };
|
std::span<const Value> args_view { reinterpret_cast<const Value *>(arg.ptr), arg.len };
|
||||||
Value r = (*reinterpret_cast<F *>(data))(args_view);
|
Value r = (*reinterpret_cast<F *>(data))(args_view);
|
||||||
new (ret) Value(std::move(r));
|
new (ret) Value(std::move(r));
|
||||||
|
@ -729,7 +733,8 @@ public:
|
||||||
bool set_global_callback(std::string_view global, std::string_view name, F callback) const
|
bool set_global_callback(std::string_view global, std::string_view name, F callback) const
|
||||||
{
|
{
|
||||||
using cbindgen_private::ValueOpaque;
|
using cbindgen_private::ValueOpaque;
|
||||||
auto actual_cb = [](void *data, cbindgen_private::Slice<ValueOpaque> arg, ValueOpaque *ret) {
|
auto actual_cb = [](void *data, cbindgen_private::Slice<ValueOpaque> arg,
|
||||||
|
ValueOpaque *ret) {
|
||||||
std::span<const Value> args_view { reinterpret_cast<const Value *>(arg.ptr), arg.len };
|
std::span<const Value> args_view { reinterpret_cast<const Value *>(arg.ptr), arg.len };
|
||||||
Value r = (*reinterpret_cast<F *>(data))(args_view);
|
Value r = (*reinterpret_cast<F *>(data))(args_view);
|
||||||
new (ret) Value(std::move(r));
|
new (ret) Value(std::move(r));
|
||||||
|
@ -746,7 +751,9 @@ public:
|
||||||
std::span<const Value> args) const
|
std::span<const Value> args) const
|
||||||
{
|
{
|
||||||
using namespace cbindgen_private;
|
using namespace cbindgen_private;
|
||||||
Slice<ValueOpaque> args_view { const_cast<ValueOpaque *>(reinterpret_cast<const ValueOpaque *>(args.data())), args.size() };
|
Slice<ValueOpaque> args_view { const_cast<ValueOpaque *>(
|
||||||
|
reinterpret_cast<const ValueOpaque *>(args.data())),
|
||||||
|
args.size() };
|
||||||
ValueOpaque out;
|
ValueOpaque out;
|
||||||
if (sixtyfps_interpreter_component_instance_invoke_global_callback(
|
if (sixtyfps_interpreter_component_instance_invoke_global_callback(
|
||||||
inner(), sixtyfps::private_api::string_to_slice(global),
|
inner(), sixtyfps::private_api::string_to_slice(global),
|
||||||
|
|
|
@ -7,6 +7,7 @@ use rand::RngCore;
|
||||||
use sixtyfps_compilerlib::langtype::Type;
|
use sixtyfps_compilerlib::langtype::Type;
|
||||||
use sixtyfps_corelib::window::WindowHandleAccess;
|
use sixtyfps_corelib::window::WindowHandleAccess;
|
||||||
use sixtyfps_corelib::{ImageInner, SharedVector};
|
use sixtyfps_corelib::{ImageInner, SharedVector};
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
mod js_model;
|
mod js_model;
|
||||||
mod persistent_context;
|
mod persistent_context;
|
||||||
|
@ -180,11 +181,12 @@ fn to_eval_value<'cx>(
|
||||||
Type::Array(a) => match val.downcast::<JsArray>() {
|
Type::Array(a) => match val.downcast::<JsArray>() {
|
||||||
Ok(arr) => {
|
Ok(arr) => {
|
||||||
let vec = arr.to_vec(cx)?;
|
let vec = arr.to_vec(cx)?;
|
||||||
Ok(Value::Array(
|
Ok(Value::Model(Rc::new(sixtyfps_corelib::model::SharedVectorModel::from(
|
||||||
vec.into_iter()
|
vec.into_iter()
|
||||||
.map(|i| to_eval_value(i, (*a).clone(), cx, persistent_context))
|
.map(|i| to_eval_value(i, (*a).clone(), cx, persistent_context))
|
||||||
.collect::<Result<SharedVector<_>, _>>()?,
|
.collect::<Result<SharedVector<_>, _>>()?,
|
||||||
))
|
))
|
||||||
|
as Rc<dyn sixtyfps_corelib::model::Model<Data = Value>>))
|
||||||
}
|
}
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
let obj = val.downcast_or_throw::<JsObject, _>(cx)?;
|
let obj = val.downcast_or_throw::<JsObject, _>(cx)?;
|
||||||
|
@ -259,14 +261,6 @@ fn to_js_value<'cx>(
|
||||||
| &ImageInner::EmbeddedImage { .. }
|
| &ImageInner::EmbeddedImage { .. }
|
||||||
| &ImageInner::StaticTextures { .. } => JsNull::new().as_value(cx), // TODO: maybe pass around node buffers?
|
| &ImageInner::StaticTextures { .. } => JsNull::new().as_value(cx), // TODO: maybe pass around node buffers?
|
||||||
},
|
},
|
||||||
Value::Array(a) => {
|
|
||||||
let js_array = JsArray::new(cx, a.len() as _);
|
|
||||||
for (i, e) in a.into_iter().enumerate() {
|
|
||||||
let v = to_js_value(e, cx, persistent_context)?;
|
|
||||||
js_array.set(cx, i as u32, v)?;
|
|
||||||
}
|
|
||||||
js_array.as_value(cx)
|
|
||||||
}
|
|
||||||
Value::Model(model) => {
|
Value::Model(model) => {
|
||||||
if let Some(js_model) = model.as_any().downcast_ref::<js_model::JsModel>() {
|
if let Some(js_model) = model.as_any().downcast_ref::<js_model::JsModel>() {
|
||||||
js_model.get_object(cx, persistent_context)?.as_value(cx)
|
js_model.get_object(cx, persistent_context)?.as_value(cx)
|
||||||
|
|
|
@ -30,8 +30,6 @@ pub enum ValueType {
|
||||||
String,
|
String,
|
||||||
/// Correspond to the `bool` type in .60
|
/// Correspond to the `bool` type in .60
|
||||||
Bool,
|
Bool,
|
||||||
/// An Array in the .60 language.
|
|
||||||
Array,
|
|
||||||
/// A more complex model which is not created by the interpreter itself (ValueType::Array can also be used for models)
|
/// A more complex model which is not created by the interpreter itself (ValueType::Array can also be used for models)
|
||||||
Model,
|
Model,
|
||||||
/// An object
|
/// An object
|
||||||
|
@ -57,7 +55,7 @@ impl From<LangType> for ValueType {
|
||||||
| LangType::UnitProduct(_) => Self::Number,
|
| LangType::UnitProduct(_) => Self::Number,
|
||||||
LangType::String => Self::String,
|
LangType::String => Self::String,
|
||||||
LangType::Color => Self::Brush,
|
LangType::Color => Self::Brush,
|
||||||
LangType::Array(_) => Self::Array,
|
LangType::Array(_) => Self::Model,
|
||||||
LangType::Bool => Self::Bool,
|
LangType::Bool => Self::Bool,
|
||||||
LangType::Struct { .. } => Self::Struct,
|
LangType::Struct { .. } => Self::Struct,
|
||||||
LangType::Void => Self::Void,
|
LangType::Void => Self::Void,
|
||||||
|
@ -93,8 +91,6 @@ pub enum Value {
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
/// Correspond to the `image` type in .60
|
/// Correspond to the `image` type in .60
|
||||||
Image(Image),
|
Image(Image),
|
||||||
/// An Array in the .60 language.
|
|
||||||
Array(SharedVector<Value>),
|
|
||||||
/// A more complex model which is not created by the interpreter itself (Value::Array can also be used for models)
|
/// A more complex model which is not created by the interpreter itself (Value::Array can also be used for models)
|
||||||
Model(Rc<dyn sixtyfps_corelib::model::Model<Data = Value>>),
|
Model(Rc<dyn sixtyfps_corelib::model::Model<Data = Value>>),
|
||||||
/// An object
|
/// An object
|
||||||
|
@ -123,18 +119,7 @@ impl Value {
|
||||||
Value::Number(_) => ValueType::Number,
|
Value::Number(_) => ValueType::Number,
|
||||||
Value::String(_) => ValueType::String,
|
Value::String(_) => ValueType::String,
|
||||||
Value::Bool(_) => ValueType::Bool,
|
Value::Bool(_) => ValueType::Bool,
|
||||||
Value::Array(_) => ValueType::Array,
|
Value::Model(_) => ValueType::Model,
|
||||||
Value::Model(model) => {
|
|
||||||
if model
|
|
||||||
.as_any()
|
|
||||||
.downcast_ref::<sixtyfps_corelib::model::SharedVectorModel<Value>>()
|
|
||||||
.is_some()
|
|
||||||
{
|
|
||||||
ValueType::Array
|
|
||||||
} else {
|
|
||||||
ValueType::Model
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Value::Struct(_) => ValueType::Struct,
|
Value::Struct(_) => ValueType::Struct,
|
||||||
Value::Brush(_) => ValueType::Brush,
|
Value::Brush(_) => ValueType::Brush,
|
||||||
Value::Image(_) => ValueType::Image,
|
Value::Image(_) => ValueType::Image,
|
||||||
|
@ -157,31 +142,17 @@ impl PartialEq for Value {
|
||||||
Value::String(lhs) => matches!(other, Value::String(rhs) if lhs == rhs),
|
Value::String(lhs) => matches!(other, Value::String(rhs) if lhs == rhs),
|
||||||
Value::Bool(lhs) => matches!(other, Value::Bool(rhs) if lhs == rhs),
|
Value::Bool(lhs) => matches!(other, Value::Bool(rhs) if lhs == rhs),
|
||||||
Value::Image(lhs) => matches!(other, Value::Image(rhs) if lhs == rhs),
|
Value::Image(lhs) => matches!(other, Value::Image(rhs) if lhs == rhs),
|
||||||
Value::Array(lhs) => {
|
|
||||||
match other {
|
|
||||||
Value::Array(rhs) => return lhs == rhs,
|
|
||||||
Value::Model(model) => {
|
|
||||||
if let Some(rhs_array) =
|
|
||||||
model.as_any().downcast_ref::<SharedVectorModel<Value>>()
|
|
||||||
{
|
|
||||||
return lhs == &rhs_array.shared_vector();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
Value::Model(lhs) => {
|
Value::Model(lhs) => {
|
||||||
match other {
|
if let Value::Model(rhs) = other {
|
||||||
Value::Model(rhs) => return Rc::ptr_eq(lhs, rhs),
|
match (
|
||||||
Value::Array(rhs_array) => {
|
lhs.as_any().downcast_ref::<SharedVectorModel<Value>>(),
|
||||||
if let Some(lhs_array) =
|
rhs.as_any().downcast_ref::<SharedVectorModel<Value>>(),
|
||||||
lhs.as_any().downcast_ref::<SharedVectorModel<Value>>()
|
) {
|
||||||
{
|
(Some(lhs_array), Some(rhs_array)) => {
|
||||||
return &lhs_array.shared_vector() == rhs_array;
|
return lhs_array.shared_vector() == rhs_array.shared_vector()
|
||||||
}
|
}
|
||||||
|
_ => return Rc::ptr_eq(lhs, rhs),
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
@ -205,7 +176,6 @@ impl std::fmt::Debug for Value {
|
||||||
Value::String(s) => write!(f, "Value::String({:?})", s),
|
Value::String(s) => write!(f, "Value::String({:?})", s),
|
||||||
Value::Bool(b) => write!(f, "Value::Bool({:?})", b),
|
Value::Bool(b) => write!(f, "Value::Bool({:?})", b),
|
||||||
Value::Image(i) => write!(f, "Value::Image({:?})", i),
|
Value::Image(i) => write!(f, "Value::Image({:?})", i),
|
||||||
Value::Array(a) => write!(f, "Value::Array({:?})", a),
|
|
||||||
Value::Model(_) => write!(f, "Value::Model(<model object>)"),
|
Value::Model(_) => write!(f, "Value::Model(<model object>)"),
|
||||||
Value::Struct(s) => write!(f, "Value::Struct({:?})", s),
|
Value::Struct(s) => write!(f, "Value::Struct({:?})", s),
|
||||||
Value::Brush(b) => write!(f, "Value::Brush({:?})", b),
|
Value::Brush(b) => write!(f, "Value::Brush({:?})", b),
|
||||||
|
@ -455,23 +425,6 @@ impl FromIterator<(String, Value)> for Struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// FIXME: use SharedArray instead?
|
|
||||||
impl From<Vec<Value>> for Value {
|
|
||||||
fn from(a: Vec<Value>) -> Self {
|
|
||||||
Value::Array(a.into_iter().collect())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl TryInto<Vec<Value>> for Value {
|
|
||||||
type Error = Value;
|
|
||||||
fn try_into(self) -> Result<Vec<Value>, Value> {
|
|
||||||
if let Value::Array(a) = self {
|
|
||||||
Ok(a.into_iter().collect())
|
|
||||||
} else {
|
|
||||||
Err(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ComponentCompiler is the entry point to the SixtyFPS interpreter that can be used
|
/// ComponentCompiler is the entry point to the SixtyFPS interpreter that can be used
|
||||||
/// to load .60 files or compile them on-the-fly from a string.
|
/// to load .60 files or compile them on-the-fly from a string.
|
||||||
pub struct ComponentCompiler {
|
pub struct ComponentCompiler {
|
||||||
|
|
|
@ -174,9 +174,6 @@ pub fn eval_expression(expression: &Expression, local_context: &mut EvalLocalCon
|
||||||
let array = eval_expression(array, local_context);
|
let array = eval_expression(array, local_context);
|
||||||
let index = eval_expression(index, local_context);
|
let index = eval_expression(index, local_context);
|
||||||
match (array, index) {
|
match (array, index) {
|
||||||
(Value::Array(vec), Value::Number(index)) => {
|
|
||||||
vec.as_slice().get(index as usize).cloned().unwrap_or(Value::Void)
|
|
||||||
}
|
|
||||||
(Value::Model(model), Value::Number(index)) => {
|
(Value::Model(model), Value::Number(index)) => {
|
||||||
if (index as usize) < model.row_count() {
|
if (index as usize) < model.row_count() {
|
||||||
model.model_tracker().track_row_data_changes(index as usize);
|
model.model_tracker().track_row_data_changes(index as usize);
|
||||||
|
@ -415,9 +412,6 @@ pub fn eval_expression(expression: &Expression, local_context: &mut EvalLocalCon
|
||||||
panic!("internal error: incorrect argument count to ArrayLength")
|
panic!("internal error: incorrect argument count to ArrayLength")
|
||||||
}
|
}
|
||||||
match eval_expression(&arguments[0], local_context) {
|
match eval_expression(&arguments[0], local_context) {
|
||||||
Value::Array(array) => {
|
|
||||||
Value::Number(array.len() as f64)
|
|
||||||
}
|
|
||||||
Value::Model(model) => {
|
Value::Model(model) => {
|
||||||
model.model_tracker().track_row_count_changes();
|
model.model_tracker().track_row_count_changes();
|
||||||
Value::Number(model.row_count() as f64)
|
Value::Number(model.row_count() as f64)
|
||||||
|
@ -893,14 +887,13 @@ fn check_value_type(value: &Value, ty: &Type) -> bool {
|
||||||
Type::Image => matches!(value, Value::Image(_)),
|
Type::Image => matches!(value, Value::Image(_)),
|
||||||
Type::Bool => matches!(value, Value::Bool(_)),
|
Type::Bool => matches!(value, Value::Bool(_)),
|
||||||
Type::Model => {
|
Type::Model => {
|
||||||
matches!(value, Value::Model(_) | Value::Bool(_) | Value::Number(_) | Value::Array(_))
|
matches!(value, Value::Model(_) | Value::Bool(_) | Value::Number(_))
|
||||||
}
|
}
|
||||||
Type::PathData => matches!(value, Value::PathData(_)),
|
Type::PathData => matches!(value, Value::PathData(_)),
|
||||||
Type::Easing => matches!(value, Value::EasingCurve(_)),
|
Type::Easing => matches!(value, Value::EasingCurve(_)),
|
||||||
Type::Brush => matches!(value, Value::Brush(_)),
|
Type::Brush => matches!(value, Value::Brush(_)),
|
||||||
Type::Array(inner) => {
|
Type::Array(_) => {
|
||||||
matches!(value, Value::Model(_))
|
matches!(value, Value::Model(_))
|
||||||
|| matches!(value, Value::Array(vec) if vec.iter().all(|x| check_value_type(x, inner)))
|
|
||||||
}
|
}
|
||||||
Type::Struct { fields, .. } => {
|
Type::Struct { fields, .. } => {
|
||||||
matches!(value, Value::Struct(str) if str.iter().all(|(k, v)| fields.get(k).map_or(false, |ty| check_value_type(v, ty))))
|
matches!(value, Value::Struct(str) if str.iter().all(|(k, v)| fields.get(k).map_or(false, |ty| check_value_type(v, ty))))
|
||||||
|
@ -1164,7 +1157,7 @@ pub fn default_value_for_type(ty: &Type) -> Value {
|
||||||
Type::Struct { fields, .. } => Value::Struct(
|
Type::Struct { fields, .. } => Value::Struct(
|
||||||
fields.iter().map(|(n, t)| (n.clone(), default_value_for_type(t))).collect::<Struct>(),
|
fields.iter().map(|(n, t)| (n.clone(), default_value_for_type(t))).collect::<Struct>(),
|
||||||
),
|
),
|
||||||
Type::Array(_) => Value::Array(Default::default()),
|
Type::Array(_) => Value::Void,
|
||||||
Type::Percent => Value::Number(0.),
|
Type::Percent => Value::Number(0.),
|
||||||
Type::Enumeration(e) => {
|
Type::Enumeration(e) => {
|
||||||
Value::EnumerationValue(e.name.clone(), e.values.get(e.default_value).unwrap().clone())
|
Value::EnumerationValue(e.name.clone(), e.values.get(e.default_value).unwrap().clone())
|
||||||
|
|
|
@ -3,13 +3,40 @@
|
||||||
|
|
||||||
use crate::dynamic_component::ErasedComponentBox;
|
use crate::dynamic_component::ErasedComponentBox;
|
||||||
|
|
||||||
use super::*;
|
//use super::*;
|
||||||
use sixtyfps_corelib::model::{Model, ModelNotify, SharedVectorModel};
|
use sixtyfps_corelib::model::{Model, ModelNotify, SharedVectorModel};
|
||||||
use sixtyfps_corelib::slice::Slice;
|
use sixtyfps_corelib::slice::Slice;
|
||||||
use sixtyfps_corelib::window::{WindowHandleAccess, WindowRc};
|
use sixtyfps_corelib::window::{WindowHandleAccess, WindowRc};
|
||||||
use std::ffi::c_void;
|
use std::ffi::c_void;
|
||||||
use vtable::VRef;
|
use vtable::VRef;
|
||||||
|
|
||||||
|
/// This enum represents the different public variants of the [`Value`] enum, without
|
||||||
|
/// the contained values.
|
||||||
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||||
|
#[repr(i8)]
|
||||||
|
pub enum ValueType {
|
||||||
|
/// The variant that expresses the non-type. This is the default.
|
||||||
|
Void,
|
||||||
|
/// An `int` or a `float` (this is also used for unit based type such as `length` or `angle`)
|
||||||
|
Number,
|
||||||
|
/// Correspond to the `string` type in .60
|
||||||
|
String,
|
||||||
|
/// Correspond to the `bool` type in .60
|
||||||
|
Bool,
|
||||||
|
/// An Array in the .60 language.
|
||||||
|
Array,
|
||||||
|
/// A more complex model which is not created by the interpreter itself (ValueType::Array can also be used for models)
|
||||||
|
Model,
|
||||||
|
/// An object
|
||||||
|
Struct,
|
||||||
|
/// Correspond to `brush` or `color` type in .60. For color, this is then a [`Brush::SolidColor`]
|
||||||
|
Brush,
|
||||||
|
/// Correspond to `image` type in .60.
|
||||||
|
Image,
|
||||||
|
/// The type is not a public type but something internal.
|
||||||
|
Other = -1,
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[cfg(target_pointer_width = "64")]
|
#[cfg(target_pointer_width = "64")]
|
||||||
pub struct ValueOpaque([usize; 7]);
|
pub struct ValueOpaque([usize; 7]);
|
||||||
|
@ -75,21 +102,21 @@ pub unsafe extern "C" fn sixtyfps_interpreter_value_new_bool(b: bool, val: *mut
|
||||||
std::ptr::write(val as *mut Value, Value::Bool(b))
|
std::ptr::write(val as *mut Value, Value::Bool(b))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a new Value in the given memory location as array
|
/// Construct a new Value in the given memory location as array model
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn sixtyfps_interpreter_value_new_array(
|
pub unsafe extern "C" fn sixtyfps_interpreter_value_new_array_model(
|
||||||
a: &SharedVector<ValueOpaque>,
|
a: &SharedVector<ValueOpaque>,
|
||||||
val: *mut ValueOpaque,
|
val: *mut ValueOpaque,
|
||||||
) {
|
) {
|
||||||
std::ptr::write(
|
std::ptr::write(
|
||||||
val as *mut Value,
|
val as *mut Value,
|
||||||
Value::Array(
|
Value::Model(Rc::new(SharedVectorModel::<Value>::from(
|
||||||
{
|
{
|
||||||
// Safety: We assert that Value and ValueOpaque have the same size and alignment
|
// Safety: We assert that Value and ValueOpaque have the same size and alignment
|
||||||
std::mem::transmute::<&SharedVector<ValueOpaque>, &SharedVector<Value>>(a)
|
std::mem::transmute::<&SharedVector<ValueOpaque>, &SharedVector<Value>>(a)
|
||||||
}
|
}
|
||||||
.clone(),
|
.clone(),
|
||||||
),
|
)) as Rc<dyn Model<Data = Value>>),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +155,7 @@ pub unsafe extern "C" fn sixtyfps_interpreter_value_new_model(
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn sixtyfps_interpreter_value_type(val: *const ValueOpaque) -> ValueType {
|
pub unsafe extern "C" fn sixtyfps_interpreter_value_type(val: *const ValueOpaque) -> ValueType {
|
||||||
(&*val).as_value().value_type()
|
match (&*val).as_value().value_type() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -164,14 +191,6 @@ pub extern "C" fn sixtyfps_interpreter_value_to_array(
|
||||||
out: *mut SharedVector<ValueOpaque>,
|
out: *mut SharedVector<ValueOpaque>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
match val.as_value() {
|
match val.as_value() {
|
||||||
Value::Array(v) => unsafe {
|
|
||||||
// Safety: We assert that Value and ValueOpaque have the same size and alignment
|
|
||||||
std::ptr::write(
|
|
||||||
out,
|
|
||||||
std::mem::transmute::<&SharedVector<Value>, &SharedVector<ValueOpaque>>(v).clone(),
|
|
||||||
);
|
|
||||||
true
|
|
||||||
},
|
|
||||||
Value::Model(m) => {
|
Value::Model(m) => {
|
||||||
if let Some(model) = m.as_any().downcast_ref::<SharedVectorModel<Value>>() {
|
if let Some(model) = m.as_any().downcast_ref::<SharedVectorModel<Value>>() {
|
||||||
let vec = model.shared_vector();
|
let vec = model.shared_vector();
|
||||||
|
|
|
@ -7,12 +7,11 @@ use std::cell::RefCell;
|
||||||
|
|
||||||
pub struct ValueModel {
|
pub struct ValueModel {
|
||||||
value: RefCell<Value>,
|
value: RefCell<Value>,
|
||||||
notify: sixtyfps_corelib::model::ModelNotify,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ValueModel {
|
impl ValueModel {
|
||||||
pub fn new(value: Value) -> Self {
|
pub fn new(value: Value) -> Self {
|
||||||
Self { value: RefCell::new(value), notify: Default::default() }
|
Self { value: RefCell::new(value) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,24 +19,18 @@ impl ModelTracker for ValueModel {
|
||||||
fn attach_peer(&self, peer: sixtyfps_corelib::model::ModelPeer) {
|
fn attach_peer(&self, peer: sixtyfps_corelib::model::ModelPeer) {
|
||||||
if let Value::Model(ref model_ptr) = *self.value.borrow() {
|
if let Value::Model(ref model_ptr) = *self.value.borrow() {
|
||||||
model_ptr.model_tracker().attach_peer(peer)
|
model_ptr.model_tracker().attach_peer(peer)
|
||||||
} else {
|
|
||||||
self.notify.attach_peer(peer)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn track_row_count_changes(&self) {
|
fn track_row_count_changes(&self) {
|
||||||
if let Value::Model(ref model_ptr) = *self.value.borrow() {
|
if let Value::Model(ref model_ptr) = *self.value.borrow() {
|
||||||
model_ptr.model_tracker().track_row_count_changes()
|
model_ptr.model_tracker().track_row_count_changes()
|
||||||
} else {
|
|
||||||
self.notify.track_row_count_changes()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn track_row_data_changes(&self, row: usize) {
|
fn track_row_data_changes(&self, row: usize) {
|
||||||
if let Value::Model(ref model_ptr) = *self.value.borrow() {
|
if let Value::Model(ref model_ptr) = *self.value.borrow() {
|
||||||
model_ptr.model_tracker().track_row_data_changes(row)
|
model_ptr.model_tracker().track_row_data_changes(row)
|
||||||
} else {
|
|
||||||
self.notify.track_row_data_changes(row)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,7 +48,6 @@ impl Model for ValueModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Value::Number(x) => *x as usize,
|
Value::Number(x) => *x as usize,
|
||||||
Value::Array(a) => a.len(),
|
|
||||||
Value::Void => 0,
|
Value::Void => 0,
|
||||||
Value::Model(model_ptr) => model_ptr.row_count(),
|
Value::Model(model_ptr) => model_ptr.row_count(),
|
||||||
x => panic!("Invalid model {:?}", x),
|
x => panic!("Invalid model {:?}", x),
|
||||||
|
@ -69,7 +61,6 @@ impl Model for ValueModel {
|
||||||
Some(match &*self.value.borrow() {
|
Some(match &*self.value.borrow() {
|
||||||
Value::Bool(_) => Value::Void,
|
Value::Bool(_) => Value::Void,
|
||||||
Value::Number(_) => Value::Number(row as _),
|
Value::Number(_) => Value::Number(row as _),
|
||||||
Value::Array(a) => a[row].clone(),
|
|
||||||
Value::Model(model_ptr) => model_ptr.row_data(row)?,
|
Value::Model(model_ptr) => model_ptr.row_data(row)?,
|
||||||
x => panic!("Invalid model {:?}", x),
|
x => panic!("Invalid model {:?}", x),
|
||||||
})
|
})
|
||||||
|
@ -82,10 +73,6 @@ impl Model for ValueModel {
|
||||||
|
|
||||||
fn set_row_data(&self, row: usize, data: Self::Data) {
|
fn set_row_data(&self, row: usize, data: Self::Data) {
|
||||||
match &mut *self.value.borrow_mut() {
|
match &mut *self.value.borrow_mut() {
|
||||||
Value::Array(a) => {
|
|
||||||
a.make_mut_slice()[row] = data;
|
|
||||||
self.notify.row_changed(row)
|
|
||||||
}
|
|
||||||
Value::Model(model_ptr) => model_ptr.set_row_data(row, data),
|
Value::Model(model_ptr) => model_ptr.set_row_data(row, data),
|
||||||
_ => eprintln!("Trying to change the value of a read-only integer model."),
|
_ => eprintln!("Trying to change the value of a read-only integer model."),
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,11 @@
|
||||||
|
|
||||||
#![doc = include_str!("README.md")]
|
#![doc = include_str!("README.md")]
|
||||||
|
|
||||||
|
use sixtyfps_corelib::SharedVector;
|
||||||
use sixtyfps_interpreter::{ComponentInstance, SharedString, Value};
|
use sixtyfps_interpreter::{ComponentInstance, SharedString, Value};
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
|
use std::rc::Rc;
|
||||||
use std::sync::atomic::{AtomicU32, Ordering};
|
use std::sync::atomic::{AtomicU32, Ordering};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::task::Wake;
|
use std::task::Wake;
|
||||||
|
@ -105,10 +107,10 @@ fn main() -> Result<()> {
|
||||||
sixtyfps_interpreter::Value::Number(x) => Some(x.into()),
|
sixtyfps_interpreter::Value::Number(x) => Some(x.into()),
|
||||||
sixtyfps_interpreter::Value::String(x) => Some(x.as_str().into()),
|
sixtyfps_interpreter::Value::String(x) => Some(x.as_str().into()),
|
||||||
sixtyfps_interpreter::Value::Bool(x) => Some(x.into()),
|
sixtyfps_interpreter::Value::Bool(x) => Some(x.into()),
|
||||||
sixtyfps_interpreter::Value::Array(arr) => {
|
sixtyfps_interpreter::Value::Model(model) => {
|
||||||
let mut res = Vec::with_capacity(arr.len());
|
let mut res = Vec::with_capacity(model.row_count());
|
||||||
for x in arr {
|
for i in 0..model.row_count() {
|
||||||
res.push(to_json(x)?);
|
res.push(to_json(model.row_data(i).unwrap())?);
|
||||||
}
|
}
|
||||||
Some(serde_json::Value::Array(res))
|
Some(serde_json::Value::Array(res))
|
||||||
}
|
}
|
||||||
|
@ -264,9 +266,12 @@ fn load_data(instance: &ComponentInstance, data_path: &std::path::Path) -> Resul
|
||||||
sixtyfps_interpreter::Value::Number(n.as_f64().unwrap_or(f64::NAN))
|
sixtyfps_interpreter::Value::Number(n.as_f64().unwrap_or(f64::NAN))
|
||||||
}
|
}
|
||||||
serde_json::Value::String(s) => SharedString::from(s.as_str()).into(),
|
serde_json::Value::String(s) => SharedString::from(s.as_str()).into(),
|
||||||
serde_json::Value::Array(array) => {
|
serde_json::Value::Array(array) => sixtyfps_interpreter::Value::Model(Rc::new(
|
||||||
sixtyfps_interpreter::Value::Array(array.iter().map(from_json).collect())
|
sixtyfps_corelib::model::SharedVectorModel::from(
|
||||||
}
|
array.iter().map(from_json).collect::<SharedVector<Value>>(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
as Rc<dyn sixtyfps_corelib::model::Model<Data = sixtyfps_interpreter::Value>>),
|
||||||
serde_json::Value::Object(obj) => obj
|
serde_json::Value::Object(obj) => obj
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(k, v)| (k.clone(), from_json(v)))
|
.map(|(k, v)| (k.clone(), from_json(v)))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue