diff --git a/CHANGELOG.md b/CHANGELOG.md index 8403c5db2..7510b8a69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ as well as the [Rust migration guide for the `sixtyfps` crate](api/sixtyfps-rs/m - In Rust and C++, `sixtyfps::Image::size()` now returns an integer size type. - `sixtyfps::interpreter::CallCallbackError` was renamed to `sixtyfps::interpreter::InvokeCallbackError` - Some deprecation warning in .60 became hard errors + - Replace `ModelHandle` with `ModelRc` ### Added diff --git a/api/sixtyfps-node/native/lib.rs b/api/sixtyfps-node/native/lib.rs index e2f3782cd..62eb9fbbd 100644 --- a/api/sixtyfps-node/native/lib.rs +++ b/api/sixtyfps-node/native/lib.rs @@ -5,7 +5,7 @@ use core::cell::RefCell; use neon::prelude::*; use rand::RngCore; use sixtyfps_compilerlib::langtype::Type; -use sixtyfps_corelib::model::{Model, ModelHandle}; +use sixtyfps_corelib::model::{Model, ModelRc}; use sixtyfps_corelib::window::WindowHandleAccess; use sixtyfps_corelib::{ImageInner, SharedVector}; use std::rc::Rc; @@ -182,21 +182,20 @@ fn to_eval_value<'cx>( Type::Array(a) => match val.downcast::() { Ok(arr) => { let vec = arr.to_vec(cx)?; - Ok(Value::Model(ModelHandle::new(Rc::new( + Ok(Value::Model(ModelRc::new(Rc::new( sixtyfps_corelib::model::SharedVectorModel::from( vec.into_iter() .map(|i| to_eval_value(i, (*a).clone(), cx, persistent_context)) .collect::, _>>()?, ), - ) - as Rc>))) + )))) } Err(_) => { let obj = val.downcast_or_throw::(cx)?; obj.get(cx, "rowCount")?.downcast_or_throw::(cx)?; obj.get(cx, "rowData")?.downcast_or_throw::(cx)?; let m = js_model::JsModel::new(obj, *a, cx, persistent_context)?; - Ok(Value::Model(ModelHandle::new(m))) + Ok(Value::Model(ModelRc::new(m))) } }, Type::Image => { diff --git a/api/sixtyfps-rs/lib.rs b/api/sixtyfps-rs/lib.rs index fb15e3aae..09f73d5c8 100644 --- a/api/sixtyfps-rs/lib.rs +++ b/api/sixtyfps-rs/lib.rs @@ -181,7 +181,7 @@ The follow table summarizes the entire mapping: | `duration` | `i64` | At run-time, durations are always represented as signed 64-bit integers with millisecond precision. | | `angle` | `f32` | The value in degrees | | structure | `struct` of the same name | | -| array | [`ModelHandle`] | | +| array | [`ModelRc`] | | For user defined structures in the .60, an extra struct is generated. For example, if the `.60` contains @@ -233,7 +233,7 @@ pub use sixtyfps_corelib::graphics::{ Brush, Color, Image, LoadImageError, Rgb8Pixel, Rgba8Pixel, RgbaColor, SharedPixelBuffer, }; pub use sixtyfps_corelib::model::{ - Model, ModelHandle, ModelNotify, ModelPeer, ModelTracker, StandardListViewItem, VecModel, + Model, ModelNotify, ModelPeer, ModelRc, ModelTracker, StandardListViewItem, VecModel, }; pub use sixtyfps_corelib::sharedvector::SharedVector; pub use sixtyfps_corelib::string::SharedString; diff --git a/api/sixtyfps-rs/migration.md b/api/sixtyfps-rs/migration.md index 35d40273f..b65f71677 100644 --- a/api/sixtyfps-rs/migration.md +++ b/api/sixtyfps-rs/migration.md @@ -62,3 +62,6 @@ fn model_tracker(&self) -> &dyn ModelTracker { } ``` +#### Minor changes to `Model` + +`ModelRc` replaces `ModelHandle`. diff --git a/docs/tutorial/rust/src/main_game_logic_in_rust.rs b/docs/tutorial/rust/src/main_game_logic_in_rust.rs index 735648a88..f6f79f267 100644 --- a/docs/tutorial/rust/src/main_game_logic_in_rust.rs +++ b/docs/tutorial/rust/src/main_game_logic_in_rust.rs @@ -20,7 +20,7 @@ fn main() { // ANCHOR: game_logic // Assign the shuffled Vec to the model property let tiles_model = std::rc::Rc::new(sixtyfps::VecModel::from(tiles)); - main_window.set_memory_tiles(sixtyfps::ModelHandle::new(tiles_model.clone())); + main_window.set_memory_tiles(sixtyfps::ModelRc::new(tiles_model.clone())); let main_window_weak = main_window.as_weak(); main_window.on_check_if_pair_solved(move || { diff --git a/docs/tutorial/rust/src/main_tiles_from_rust.rs b/docs/tutorial/rust/src/main_tiles_from_rust.rs index 6f2f5b449..18238215c 100644 --- a/docs/tutorial/rust/src/main_tiles_from_rust.rs +++ b/docs/tutorial/rust/src/main_tiles_from_rust.rs @@ -20,7 +20,7 @@ fn main() { // Assign the shuffled Vec to the model property let tiles_model = std::rc::Rc::new(sixtyfps::VecModel::from(tiles)); - main_window.set_memory_tiles(sixtyfps::ModelHandle::new(tiles_model)); + main_window.set_memory_tiles(sixtyfps::ModelRc::new(tiles_model)); main_window.run(); } diff --git a/examples/imagefilter/main.rs b/examples/imagefilter/main.rs index 147e4f409..7b9ba2812 100644 --- a/examples/imagefilter/main.rs +++ b/examples/imagefilter/main.rs @@ -140,7 +140,7 @@ pub fn main() { ]); let filters = Rc::new(filters); - main_window.set_filters(sixtyfps::ModelHandle::new(filters.clone())); + main_window.set_filters(sixtyfps::ModelRc::new(filters.clone())); main_window.on_filter_image(move |filter_index| { let filter_fn = filters.0[filter_index as usize].apply_function; diff --git a/examples/memory/main.rs b/examples/memory/main.rs index 9a35a0944..0ccfa8aad 100644 --- a/examples/memory/main.rs +++ b/examples/memory/main.rs @@ -1,7 +1,7 @@ // Copyright © SixtyFPS GmbH // SPDX-License-Identifier: (GPL-3.0-only OR LicenseRef-SixtyFPS-commercial) -use sixtyfps::{Model, ModelHandle, Timer, VecModel}; +use sixtyfps::{Model, ModelRc, Timer, VecModel}; use std::rc::Rc; use std::time::Duration; @@ -30,7 +30,7 @@ pub fn main() { let tiles_model = Rc::new(VecModel::from(tiles)); - main_window.set_memory_tiles(ModelHandle::new(tiles_model.clone())); + main_window.set_memory_tiles(ModelRc::new(tiles_model.clone())); let main_window_weak = main_window.as_weak(); diff --git a/examples/printerdemo/rust/main.rs b/examples/printerdemo/rust/main.rs index 6018fb76e..8ffa457bf 100644 --- a/examples/printerdemo/rust/main.rs +++ b/examples/printerdemo/rust/main.rs @@ -59,7 +59,7 @@ pub fn main() { }); main_window .global::() - .set_printer_queue(sixtyfps::ModelHandle::new(printer_queue.data.clone())); + .set_printer_queue(sixtyfps::ModelRc::new(printer_queue.data.clone())); main_window.on_quit(move || { #[cfg(not(target_arch = "wasm32"))] diff --git a/examples/slide_puzzle/main.rs b/examples/slide_puzzle/main.rs index 55f09f9eb..912839f96 100644 --- a/examples/slide_puzzle/main.rs +++ b/examples/slide_puzzle/main.rs @@ -180,7 +180,7 @@ pub fn main() { finished: false, })); state.borrow_mut().randomize(); - main_window.set_pieces(sixtyfps::ModelHandle::new(state.borrow().pieces.clone())); + main_window.set_pieces(sixtyfps::ModelRc::new(state.borrow().pieces.clone())); let state_copy = state.clone(); main_window.on_piece_clicked(move |p| { diff --git a/examples/todo/rust/main.rs b/examples/todo/rust/main.rs index e9f30647e..80b7f52fe 100644 --- a/examples/todo/rust/main.rs +++ b/examples/todo/rust/main.rs @@ -45,7 +45,7 @@ pub fn main() { } }); - main_window.set_todo_model(sixtyfps::ModelHandle::new(todo_model)); + main_window.set_todo_model(sixtyfps::ModelRc::new(todo_model)); main_window.run(); } diff --git a/sixtyfps_compiler/generator/rust.rs b/sixtyfps_compiler/generator/rust.rs index 264b9e95c..d59aa677c 100644 --- a/sixtyfps_compiler/generator/rust.rs +++ b/sixtyfps_compiler/generator/rust.rs @@ -78,7 +78,7 @@ fn rust_type(ty: &Type) -> Option { Type::Struct { name: Some(name), .. } => Some(struct_name_to_tokens(name)), Type::Array(o) => { let inner = rust_type(o)?; - Some(quote!(sixtyfps::re_exports::ModelHandle<#inner>)) + Some(quote!(sixtyfps::re_exports::ModelRc<#inner>)) } Type::Enumeration(e) => { let e = ident(&e.name); @@ -536,7 +536,7 @@ fn generate_sub_component( let mut model = compile_expression(&repeated.model, &ctx); if repeated.model.ty(&ctx) == Type::Bool { - model = quote!(sixtyfps::re_exports::ModelHandle::new(sixtyfps::re_exports::Rc::::new(#model))) + model = quote!(sixtyfps::re_exports::ModelRc::new(sixtyfps::re_exports::Rc::::new(#model))) } init.push(quote! { @@ -1273,7 +1273,7 @@ fn compile_expression(expr: &Expression, ctx: &EvaluationContext) -> TokenStream )) } (Type::Float32, Type::Model) | (Type::Int32, Type::Model) => { - quote!(sixtyfps::re_exports::ModelHandle::new(sixtyfps::re_exports::Rc::::new(#f as usize))) + quote!(sixtyfps::re_exports::ModelRc::new(sixtyfps::re_exports::Rc::::new(#f as usize))) } (Type::Float32, Type::Color) => { quote!(sixtyfps::re_exports::Color::from_argb_encoded(#f as u32)) @@ -1446,7 +1446,7 @@ fn compile_expression(expr: &Expression, ctx: &EvaluationContext) -> TokenStream let base_e = compile_expression(array, ctx); let index_e = compile_expression(index, ctx); let value_e = compile_expression(value, ctx); - quote!((#base_e).set_row_data(#index_e as usize, #value_e as _);) + quote!((#base_e).set_row_data(#index_e as usize, #value_e as _)) } Expression::BinaryExpression { lhs, rhs, op } => { let (conv1, conv2) = match crate::expression_tree::operator_class(*op) { @@ -1536,7 +1536,7 @@ fn compile_expression(expr: &Expression, ctx: &EvaluationContext) -> TokenStream let val = values.iter().map(|e| compile_expression(e, ctx)); if *as_model { let rust_element_ty = rust_type(element_ty).unwrap(); - quote!(sixtyfps::re_exports::ModelHandle::new( + quote!(sixtyfps::re_exports::ModelRc::new( sixtyfps::re_exports::Rc::new(sixtyfps::re_exports::VecModel::<#rust_element_ty>::from( sixtyfps::re_exports::vec![#(#val as _),*] )) diff --git a/sixtyfps_runtime/corelib/model.rs b/sixtyfps_runtime/corelib/model.rs index b9a93251a..8481c0fb5 100644 --- a/sixtyfps_runtime/corelib/model.rs +++ b/sixtyfps_runtime/corelib/model.rs @@ -239,14 +239,14 @@ pub trait Model { /// Return something that can be downcast'ed (typically self) /// - /// This is useful to get back to the actual model from a ModelHandle stored + /// This is useful to get back to the actual model from a `ModelRc` stored /// in a component. /// /// ``` /// # use sixtyfps_corelib::model::*; /// # use std::rc::Rc; /// let vec_model = Rc::new(VecModel::from(vec![1i32, 2, 3])); - /// let handle = ModelHandle::from(vec_model as Rc>); + /// let handle = ModelRc::new(vec_model as Rc>); /// // later: /// handle.as_any().downcast_ref::>().unwrap().push(4); /// assert_eq!(handle.row_data(3).unwrap(), 4); @@ -305,11 +305,11 @@ pub struct VecModel { impl VecModel { /// Allocate a new model from a slice - pub fn from_slice(slice: &[T]) -> ModelHandle + pub fn from_slice(slice: &[T]) -> ModelRc where T: Clone, { - ModelHandle(Some(Rc::::new(slice.to_vec().into()))) + ModelRc::new(Rc::::new(slice.to_vec().into())) } /// Add a row at the end of the model @@ -462,56 +462,49 @@ impl Model for bool { } } -/// Properties of type array in the .60 language are represented as -/// an [`Option`] of an [`Rc`] of something implemented the [`Model`] trait +/// Properties of type Array in the .60 language are represented as +/// a `ModelRc` that implements the `Model` trait. #[derive(derive_more::Deref, derive_more::DerefMut, derive_more::From, derive_more::Into)] -pub struct ModelHandle(pub Option>>); +pub struct ModelRc(Option>>); -impl core::fmt::Debug for ModelHandle { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - write!(f, "ModelHandle({:?})", self.0.as_ref().map(|_| "dyn Model")) +impl core::fmt::Debug for ModelRc { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "ModelRc(dyn Model)") } } -impl Clone for ModelHandle { +impl Clone for ModelRc { fn clone(&self) -> Self { Self(self.0.clone()) } } -impl Default for ModelHandle { + +impl Default for ModelRc { fn default() -> Self { Self(None) } } -impl core::cmp::PartialEq for ModelHandle { +impl core::cmp::PartialEq for ModelRc { fn eq(&self, other: &Self) -> bool { match (&self.0, &other.0) { (None, None) => true, - (None, Some(_)) => false, - (Some(_), None) => false, (Some(a), Some(b)) => core::ptr::eq( (&**a) as *const dyn Model as *const u8, (&**b) as *const dyn Model as *const u8, ), + _ => false, } } } -impl From>> for ModelHandle { - fn from(x: Rc>) -> Self { - Self(Some(x)) - } -} - -impl ModelHandle { - /// Create a new handle wrapping the given model +impl ModelRc { pub fn new(model: Rc>) -> Self { Self(Some(model)) } } -impl Model for ModelHandle { +impl Model for ModelRc { type Data = T; fn row_count(&self) -> usize { @@ -524,7 +517,7 @@ impl Model for ModelHandle { fn set_row_data(&self, row: usize, data: Self::Data) { if let Some(model) = self.0.as_ref() { - model.set_row_data(row, data) + model.set_row_data(row, data); } } @@ -656,7 +649,7 @@ impl ErasedRepeater for Repeater { pub struct Repeater { inner: RefCell>, #[pin] - model: Property>, + model: Property>, #[pin] is_dirty: Property, /// Only used for the list view to track if the scrollbar has changed and item needs to be layed out again. @@ -694,24 +687,22 @@ impl PinnedDrop for Repeater { } impl Repeater { - fn model(self: Pin<&Self>) -> ModelHandle { - // Safety: Repeater does not implement drop and never let access model as mutable + fn model(self: Pin<&Self>) -> ModelRc { + // Safety: Repeater does not implement drop and never allows access to model as mutable let model = self.project_ref().model; if model.is_dirty() { *self.inner.borrow_mut() = RepeaterInner::default(); self.is_dirty.set(true); - if let ModelHandle(Some(m)) = model.get() { - let peer = self.peer.get_or_init(|| { - //Safety: we will reset it when we Drop the Repeater - Rc::pin(DependencyNode::new( - self.get_ref() as &dyn ErasedRepeater as *const dyn ErasedRepeater - )) - }); + let m = model.get(); + let peer = self.peer.get_or_init(|| { + //Safety: we will reset it when we Drop the Repeater + Rc::pin(DependencyNode::new( + self.get_ref() as &dyn ErasedRepeater as *const dyn ErasedRepeater + )) + }); - m.model_tracker() - .attach_peer(ModelPeer { inner: PinWeak::downgrade(peer.clone()) }); - } + m.model_tracker().attach_peer(ModelPeer { inner: PinWeak::downgrade(peer.clone()) }); } model.get() } @@ -719,12 +710,9 @@ impl Repeater { /// Call this function to make sure that the model is updated. /// The init function is the function to create a component pub fn ensure_updated(self: Pin<&Self>, init: impl Fn() -> ComponentRc) { - if let ModelHandle(Some(model)) = self.model() { - if self.project_ref().is_dirty.get() { - self.ensure_updated_impl(init, &model, model.row_count()); - } - } else { - self.inner.borrow_mut().components.clear(); + let model = self.model(); + if self.project_ref().is_dirty.get() { + self.ensure_updated_impl(init, &model, model.row_count()); } } @@ -732,7 +720,7 @@ impl Repeater { fn ensure_updated_impl( self: Pin<&Self>, init: impl Fn() -> ComponentRc, - model: &Rc>, + model: &ModelRc, count: usize, ) -> bool { let mut inner = self.inner.borrow_mut(); @@ -769,11 +757,7 @@ impl Repeater { viewport_y.set(0.); }; - let model = if let ModelHandle(Some(model)) = self.model() { - model - } else { - return empty_model(); - }; + let model = self.model(); let row_count = model.row_count(); if row_count == 0 { return empty_model(); @@ -785,8 +769,7 @@ impl Repeater { let geometry_updated = listview_geometry_tracker .evaluate_if_dirty(|| { // Fetch the model again to make sure that it is a dependency of this geometry tracker. - // invariant: model existence was checked earlier, so unwrap() should be safe. - let model = self.model().0.unwrap(); + let model = self.model(); // Also register a dependency to "is_dirty" let _ = self.project_ref().is_dirty.get(); @@ -904,14 +887,13 @@ impl Repeater { /// Sets the data directly in the model pub fn model_set_row_data(self: Pin<&Self>, row: usize, data: C::Data) { - if let ModelHandle(Some(model)) = self.model() { - model.set_row_data(row, data); - if let Some(c) = self.inner.borrow_mut().components.get_mut(row) { - if c.0 == RepeatedComponentState::Dirty { - if let Some(comp) = c.1.as_ref() { - comp.update(row, model.row_data(row).unwrap()); - c.0 = RepeatedComponentState::Clean; - } + let model = self.model(); + model.set_row_data(row, data); + if let Some(c) = self.inner.borrow_mut().components.get_mut(row) { + if c.0 == RepeatedComponentState::Dirty { + if let Some(comp) = c.1.as_ref() { + comp.update(row, model.row_data(row).unwrap()); + c.0 = RepeatedComponentState::Clean; } } } @@ -920,7 +902,7 @@ impl Repeater { impl Repeater { /// Set the model binding - pub fn set_model_binding(&self, binding: impl Fn() -> ModelHandle + 'static) { + pub fn set_model_binding(&self, binding: impl Fn() -> ModelRc + 'static) { self.model.set_binding(binding); } @@ -991,7 +973,7 @@ pub struct StandardListViewItem { #[test] fn test_tracking_model_handle() { let model: Rc> = Rc::new(Default::default()); - let handle = ModelHandle::new(model.clone()); + let handle = ModelRc::new(model.clone()); let tracker = Box::pin(crate::properties::PropertyTracker::default()); assert_eq!( tracker.as_ref().evaluate(|| { @@ -1028,7 +1010,7 @@ fn test_tracking_model_handle() { #[test] fn test_data_tracking() { let model: Rc> = Rc::new(VecModel::from(vec![0, 1, 2, 3, 4])); - let handle = ModelHandle::new(model.clone()); + let handle = ModelRc::new(model.clone()); let tracker = Box::pin(crate::properties::PropertyTracker::default()); assert_eq!( tracker.as_ref().evaluate(|| { diff --git a/sixtyfps_runtime/interpreter/api.rs b/sixtyfps_runtime/interpreter/api.rs index 1ce5fc49c..3e9f481cb 100644 --- a/sixtyfps_runtime/interpreter/api.rs +++ b/sixtyfps_runtime/interpreter/api.rs @@ -4,7 +4,7 @@ use core::convert::TryInto; use sixtyfps_compilerlib::langtype::Type as LangType; use sixtyfps_corelib::graphics::Image; -use sixtyfps_corelib::model::{Model, ModelHandle}; +use sixtyfps_corelib::model::{Model, ModelRc}; use sixtyfps_corelib::{Brush, PathData, SharedString, SharedVector}; use std::borrow::Cow; use std::collections::HashMap; @@ -92,7 +92,7 @@ pub enum Value { /// Correspond to the `image` type in .60 Image(Image), /// A model (that includes array in .60) - Model(ModelHandle), + Model(ModelRc), /// An object Struct(Struct), /// Correspond to `brush` or `color` type in .60. For color, this is then a [`Brush::SolidColor`] @@ -144,11 +144,7 @@ impl PartialEq for Value { Value::Image(lhs) => matches!(other, Value::Image(rhs) if lhs == rhs), Value::Model(lhs) => { if let Value::Model(rhs) = other { - match (&lhs.0, &rhs.0) { - (None, None) => true, - (None, Some(_)) | (Some(_), None) => false, - (Some(a), Some(b)) => Rc::ptr_eq(a, b), - } + lhs == rhs } else { false } @@ -1364,13 +1360,13 @@ fn component_definition_model_properties() { let instance = comp_def.create(); - let int_model = Value::Model(ModelHandle::new(Rc::new(VecModel::from_slice(&[ + let int_model = Value::Model(ModelRc::new(Rc::new(VecModel::from_slice(&[ Value::Number(14.), Value::Number(15.), Value::Number(16.), ])))); - let empty_model = Value::Model(ModelHandle::new(Rc::new(VecModel::::default()))); - let model_with_string = Value::Model(ModelHandle::new(Rc::new(VecModel::from_slice(&[ + let empty_model = Value::Model(ModelRc::new(Rc::new(VecModel::::default()))); + let model_with_string = Value::Model(ModelRc::new(Rc::new(VecModel::from_slice(&[ Value::Number(1000.), Value::String("foo".into()), Value::Number(1111.), diff --git a/sixtyfps_runtime/interpreter/dynamic_component.rs b/sixtyfps_runtime/interpreter/dynamic_component.rs index db27eda6c..3640334b0 100644 --- a/sixtyfps_runtime/interpreter/dynamic_component.rs +++ b/sixtyfps_runtime/interpreter/dynamic_component.rs @@ -1355,9 +1355,7 @@ pub fn instantiate( InstanceRef::from_pin_ref(c, guard) }), ); - sixtyfps_corelib::model::ModelHandle(Some(Rc::new( - crate::value_model::ValueModel::new(m), - ))) + sixtyfps_corelib::model::ModelRc::new(Rc::new(crate::value_model::ValueModel::new(m))) }); } diff --git a/sixtyfps_runtime/interpreter/eval.rs b/sixtyfps_runtime/interpreter/eval.rs index b37b589e8..491887a83 100644 --- a/sixtyfps_runtime/interpreter/eval.rs +++ b/sixtyfps_runtime/interpreter/eval.rs @@ -7,7 +7,7 @@ use core::convert::TryInto; use core::pin::Pin; use corelib::graphics::{GradientStop, LinearGradientBrush, PathElement}; use corelib::items::{ItemRef, PropertyAnimation}; -use corelib::model::{Model, ModelHandle}; +use corelib::model::{Model, ModelRc}; use corelib::rtti::AnimatedBindingKind; use corelib::window::{WindowHandleAccess, WindowRc}; use corelib::{Brush, Color, PathData, SharedString, SharedVector}; @@ -568,10 +568,10 @@ pub fn eval_expression(expression: &Expression, local_context: &mut EvalLocalCon } } Expression::Array { values, .. } => Value::Model( - ModelHandle::new(Rc::new(corelib::model::SharedVectorModel::from( + ModelRc::new(Rc::new(corelib::model::SharedVectorModel::from( values.iter().map(|e| eval_expression(e, local_context)).collect::>() - )) as Rc>) - ), + ) + ))), Expression::Struct { values, .. } => Value::Struct( values .iter() diff --git a/sixtyfps_runtime/interpreter/ffi.rs b/sixtyfps_runtime/interpreter/ffi.rs index d5b39bbcc..6eb0d762a 100644 --- a/sixtyfps_runtime/interpreter/ffi.rs +++ b/sixtyfps_runtime/interpreter/ffi.rs @@ -85,7 +85,7 @@ pub unsafe extern "C" fn sixtyfps_interpreter_value_new_array_model( let vec = std::mem::transmute::, SharedVector>(a.clone()); std::ptr::write( val as *mut Value, - Value::Model(ModelHandle::new(Rc::new(SharedVectorModel::::from(vec)))), + Value::Model(ModelRc::new(Rc::new(SharedVectorModel::::from(vec)))), ) } @@ -121,7 +121,7 @@ pub unsafe extern "C" fn sixtyfps_interpreter_value_new_model( ) { std::ptr::write( val as *mut Value, - Value::Model(ModelHandle::new(Rc::new(ModelAdaptorWrapper(model)))), + Value::Model(ModelRc::new(Rc::new(ModelAdaptorWrapper(model)))), ) } diff --git a/tests/cases/crashes/layout_deleted_item.60 b/tests/cases/crashes/layout_deleted_item.60 index 07f67e468..d87096a04 100644 --- a/tests/cases/crashes/layout_deleted_item.60 +++ b/tests/cases/crashes/layout_deleted_item.60 @@ -52,7 +52,7 @@ assert(!instance.get_hover()); use sixtyfps::Model; let instance = TestCase::new(); let vec_model = std::rc::Rc::new(sixtyfps::VecModel::from(vec![1i32, 2i32])); -instance.set_model(sixtyfps::ModelHandle::from(vec_model.clone() as std::rc::Rc>)); +instance.set_model(sixtyfps::ModelRc::new(vec_model.clone() as std::rc::Rc>)); instance.on_clicked(move || dbg!(vec_model.remove(vec_model.row_count() - 1))); sixtyfps::testing::send_mouse_click(&instance, 95., 5.); assert_eq!(instance.get_model().row_count(), 1); diff --git a/tests/cases/models/array.60 b/tests/cases/models/array.60 index d9fca6abc..66f2c0c83 100644 --- a/tests/cases/models/array.60 +++ b/tests/cases/models/array.60 @@ -43,7 +43,7 @@ assert_eq!(instance.get_n(), 4); assert_eq!(instance.get_third_int(), 3); let model: std::rc::Rc> = std::rc::Rc::new(vec![1, 2, 3, 4, 5, 6, 7].into()); -instance.set_ints(sixtyfps::ModelHandle::new(model.clone())); +instance.set_ints(sixtyfps::ModelRc::new(model.clone())); assert_eq!(instance.get_num_ints(), 7); assert_eq!(instance.get_third_int(), 3); model.push(8); diff --git a/tests/cases/models/model.60 b/tests/cases/models/model.60 index 5f8378fed..9d634296d 100644 --- a/tests/cases/models/model.60 +++ b/tests/cases/models/model.60 @@ -62,7 +62,7 @@ let another_model = std::rc::Rc::new(sixtyfps::VecModel::::from( ("a3".into(), "world".into(), 333.), ])); -instance.set_model(sixtyfps::ModelHandle::new(another_model.clone())); +instance.set_model(sixtyfps::ModelRc::new(another_model.clone())); sixtyfps::testing::send_mouse_click(&instance, 25., 5.); assert_eq!(instance.get_clicked_score(), 333000); diff --git a/tests/cases/models/write_to_model.60 b/tests/cases/models/write_to_model.60 index 78801d4a5..18fb0c487 100644 --- a/tests/cases/models/write_to_model.60 +++ b/tests/cases/models/write_to_model.60 @@ -61,7 +61,7 @@ let another_model = std::rc::Rc::new(sixtyfps::VecModel::::from( ("a3".into(), "world".into(), 333.), ])); -instance.set_model(sixtyfps::ModelHandle::new(another_model.clone())); +instance.set_model(sixtyfps::ModelRc::new(another_model.clone())); sixtyfps::testing::send_mouse_click(&instance, 25., 5.); assert_eq!(instance.get_clicked_score(), 336); diff --git a/tools/viewer/main.rs b/tools/viewer/main.rs index dff91e7c6..1a23a5035 100644 --- a/tools/viewer/main.rs +++ b/tools/viewer/main.rs @@ -3,7 +3,7 @@ #![doc = include_str!("README.md")] -use sixtyfps_corelib::model::{Model, ModelHandle}; +use sixtyfps_corelib::model::{Model, ModelRc}; use sixtyfps_corelib::SharedVector; use sixtyfps_interpreter::{ComponentInstance, SharedString, Value}; use std::future::Future; @@ -268,12 +268,9 @@ fn load_data(instance: &ComponentInstance, data_path: &std::path::Path) -> Resul } serde_json::Value::String(s) => SharedString::from(s.as_str()).into(), serde_json::Value::Array(array) => sixtyfps_interpreter::Value::Model( - ModelHandle::new(Rc::new(sixtyfps_corelib::model::SharedVectorModel::from( + ModelRc::new(Rc::new(sixtyfps_corelib::model::SharedVectorModel::from( array.iter().map(from_json).collect::>(), - )) - as Rc< - dyn sixtyfps_corelib::model::Model, - >), + ))), ), serde_json::Value::Object(obj) => obj .iter()