Use api::Struct in Value::Struct, replacing Value::Object

This commit is contained in:
Simon Hausmann 2021-03-15 12:55:39 +01:00
parent f1a7847820
commit a4c196df60
3 changed files with 31 additions and 29 deletions

View file

@ -210,18 +210,18 @@ fn to_eval_value<'cx>(
Type::Bool => Ok(Value::Bool(val.downcast_or_throw::<JsBoolean, _>(cx)?.value())), Type::Bool => Ok(Value::Bool(val.downcast_or_throw::<JsBoolean, _>(cx)?.value())),
Type::Object { fields, .. } => { Type::Object { fields, .. } => {
let obj = val.downcast_or_throw::<JsObject, _>(cx)?; let obj = val.downcast_or_throw::<JsObject, _>(cx)?;
Ok(Value::Object( Ok(Value::Struct(
fields fields
.iter() .iter()
.map(|(pro_name, pro_ty)| { .map(|(pro_name, pro_ty)| {
Ok(( Ok((
pro_name.clone(), pro_name.clone(),
to_eval_value( sixtyfps_interpreter::api::Value(to_eval_value(
obj.get(cx, pro_name.as_str())?, obj.get(cx, pro_name.as_str())?,
pro_ty.clone(), pro_ty.clone(),
cx, cx,
persistent_context, persistent_context,
)?, )?),
)) ))
}) })
.collect::<Result<_, _>>()?, .collect::<Result<_, _>>()?,
@ -268,11 +268,11 @@ fn to_js_value<'cx>(
} }
js_array.as_value(cx) js_array.as_value(cx)
} }
Value::Object(o) => { Value::Struct(o) => {
let js_object = JsObject::new(cx); let js_object = JsObject::new(cx);
for (k, e) in o.into_iter() { for (k, e) in o.iter() {
let v = to_js_value(e, cx)?; let v = to_js_value(e.0, cx)?;
js_object.set(cx, k.as_str(), v)?; js_object.set(cx, k, v)?;
} }
js_object.as_value(cx) js_object.as_value(cx)
} }

View file

@ -33,7 +33,7 @@ pub use sixtyfps_compilerlib::diagnostics::{Diagnostic, DiagnosticLevel};
/// assert_eq!(v.try_into(), Ok(100u32)); /// assert_eq!(v.try_into(), Ok(100u32));
/// ``` /// ```
#[derive(Clone, PartialEq, Debug, Default)] #[derive(Clone, PartialEq, Debug, Default)]
pub struct Value(pub(crate) eval::Value); pub struct Value(pub eval::Value); // FIXME: Make inner pub(crate) once everything is ported
/// A dummy structure that can be converted to and from [`Value`]. /// A dummy structure that can be converted to and from [`Value`].
/// ///
@ -94,6 +94,7 @@ pub_value_conversion!(
// TODO! model // TODO! model
#[derive(Clone, PartialEq, Debug, Default)]
/// This type represent a runtime instance of structure in `.60`. /// This type represent a runtime instance of structure in `.60`.
/// ///
/// This can either be an instance of a name structure introduced /// This can either be an instance of a name structure introduced
@ -136,14 +137,14 @@ impl Struct {
impl From<Struct> for Value { impl From<Struct> for Value {
fn from(s: Struct) -> Self { fn from(s: Struct) -> Self {
Self(eval::Value::Object(s.0)) Self(eval::Value::Struct(s))
} }
} }
impl TryInto<Struct> for Value { impl TryInto<Struct> for Value {
type Error = Value; type Error = Value;
fn try_into(self) -> Result<Struct, Value> { fn try_into(self) -> Result<Struct, Value> {
if let eval::Value::Object(o) = self.0 { if let eval::Value::Struct(o) = self.0 {
Ok(Struct(o)) Ok(o)
} else { } else {
Err(self) Err(self)
} }

View file

@ -7,6 +7,7 @@
This file is also available under commercial licensing terms. This file is also available under commercial licensing terms.
Please contact info@sixtyfps.io for more information. Please contact info@sixtyfps.io for more information.
LICENSE END */ LICENSE END */
use crate::api::Struct;
use crate::dynamic_component::InstanceRef; use crate::dynamic_component::InstanceRef;
use core::convert::TryInto; use core::convert::TryInto;
use core::iter::FromIterator; use core::iter::FromIterator;
@ -122,7 +123,7 @@ pub enum Value {
/// A more complex model which is not created by the interpreter itself (Value::Array can also be used for model) /// A more complex model which is not created by the interpreter itself (Value::Array can also be used for model)
Model(ModelPtr), Model(ModelPtr),
/// An object /// An object
Object(HashMap<String, Value>), Struct(Struct),
/// Corresespond to `brush` or `color` type in .60. For color, this is then a [`Brush::SolidColor`] /// Corresespond to `brush` or `color` type in .60. For color, this is then a [`Brush::SolidColor`]
Brush(Brush), Brush(Brush),
/// The elements of a path /// The elements of a path
@ -174,7 +175,7 @@ declare_value_conversion!(Number => [u32, u64, i32, i64, f32, f64, usize, isize]
declare_value_conversion!(String => [SharedString] ); declare_value_conversion!(String => [SharedString] );
declare_value_conversion!(Bool => [bool] ); declare_value_conversion!(Bool => [bool] );
declare_value_conversion!(Image => [ImageReference] ); declare_value_conversion!(Image => [ImageReference] );
declare_value_conversion!(Object => [HashMap<String, Value>] ); declare_value_conversion!(Struct => [Struct] );
declare_value_conversion!(Brush => [Brush] ); declare_value_conversion!(Brush => [Brush] );
declare_value_conversion!(PathElements => [PathData]); declare_value_conversion!(PathElements => [PathData]);
declare_value_conversion!(EasingCurve => [corelib::animations::EasingCurve]); declare_value_conversion!(EasingCurve => [corelib::animations::EasingCurve]);
@ -184,19 +185,19 @@ macro_rules! declare_value_struct_conversion {
(struct $name:path { $($field:ident),* $(,)? }) => { (struct $name:path { $($field:ident),* $(,)? }) => {
impl From<$name> for Value { impl From<$name> for Value {
fn from($name { $($field),* }: $name) -> Self { fn from($name { $($field),* }: $name) -> Self {
let mut hm = HashMap::new(); let mut struct_ = Struct::default();
$(hm.insert(stringify!($field).into(), $field.into());)* $(struct_.set_property(stringify!($field).into(), crate::api::Value($field.into()));)*
Value::Object(hm) Value::Struct(struct_)
} }
} }
impl TryInto<$name> for Value { impl TryInto<$name> for Value {
type Error = (); type Error = ();
fn try_into(self) -> Result<$name, ()> { fn try_into(self) -> Result<$name, ()> {
match self { match self {
Self::Object(x) => { Self::Struct(x) => {
type Ty = $name; type Ty = $name;
Ok(Ty { Ok(Ty {
$($field: x.get(stringify!($field)).ok_or(())?.clone().try_into().map_err(|_|())?),* $($field: x.get_property(stringify!($field)).ok_or(())?.0.clone().try_into().map_err(|_|())?),*
}) })
} }
_ => Err(()), _ => Err(()),
@ -381,8 +382,8 @@ pub fn eval_expression(e: &Expression, local_context: &mut EvalLocalContext) ->
local_context.function_arguments[*index].clone() local_context.function_arguments[*index].clone()
} }
Expression::ObjectAccess { base, name } => { Expression::ObjectAccess { base, name } => {
if let Value::Object(mut o) = eval_expression(base, local_context) { if let Value::Struct(o) = eval_expression(base, local_context) {
o.remove(name).unwrap_or(Value::Void) o.get_property(name).map_or(Value::Void, |public_value| public_value.0)
} else { } else {
Value::Void Value::Void
} }
@ -613,9 +614,8 @@ pub fn eval_expression(e: &Expression, local_context: &mut EvalLocalContext) ->
("height".to_string(), Value::Number(size.height as f64)), ("height".to_string(), Value::Number(size.height as f64)),
] ]
.iter() .iter()
.cloned() .map(|(name, value)| (name.clone(), crate::api::Value(value.clone()))).collect();
.collect(); Value::Struct(values)
Value::Object(values)
} else { } else {
panic!("internal error: argument to ImplicitItemWidth must be an element") panic!("internal error: argument to ImplicitItemWidth must be an element")
} }
@ -684,10 +684,10 @@ pub fn eval_expression(e: &Expression, local_context: &mut EvalLocalContext) ->
Expression::Array { values, .. } => Value::Array( Expression::Array { values, .. } => Value::Array(
values.iter().map(|e| eval_expression(e, local_context)).collect(), values.iter().map(|e| eval_expression(e, local_context)).collect(),
), ),
Expression::Object { values, .. } => Value::Object( Expression::Object { values, .. } => Value::Struct(
values values
.iter() .iter()
.map(|(k, v)| (k.clone(), eval_expression(v, local_context))) .map(|(k, v)| (k.clone(), crate::api::Value(eval_expression(v, local_context))))
.collect(), .collect(),
), ),
Expression::PathElements { elements } => { Expression::PathElements { elements } => {
@ -789,10 +789,11 @@ fn eval_assignement(lhs: &Expression, op: char, rhs: Value, local_context: &mut
} }
} }
Expression::ObjectAccess { base, name } => { Expression::ObjectAccess { base, name } => {
if let Value::Object(mut o) = eval_expression(base, local_context) { if let Value::Struct(mut o) = eval_expression(base, local_context) {
let r = o.get_mut(name).unwrap(); let mut r = o.get_property(name).unwrap().0;
*r = if op == '=' { rhs } else { eval(std::mem::take(r)) }; r = if op == '=' { rhs } else { eval(std::mem::take(&mut r)) };
eval_assignement(base, '=', Value::Object(o), local_context) o.set_property(name.to_owned(), crate::api::Value(r));
eval_assignement(base, '=', Value::Struct(o), local_context)
} }
} }
Expression::RepeaterModelReference { element } => { Expression::RepeaterModelReference { element } => {