From 9b13b363c36d1a80a6e08a5bf6be1e211746b87e Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 3 Aug 2020 17:31:56 +0200 Subject: [PATCH] Move corelib::abi::properties to corelib::properties And the bits that are only there for the C binding are now in an ffi sub-module. --- api/sixtyfps-rs/lib.rs | 2 +- sixtyfps_runtime/corelib/build.rs | 2 +- sixtyfps_runtime/corelib/eventloop.rs | 4 +- sixtyfps_runtime/corelib/graphics.rs | 3 +- sixtyfps_runtime/corelib/lib.rs | 5 +- .../corelib/{abi => }/properties.rs | 493 +++++++++--------- sixtyfps_runtime/corelib/rtti.rs | 2 +- .../interpreter/dynamic_component.rs | 8 +- 8 files changed, 269 insertions(+), 250 deletions(-) rename sixtyfps_runtime/corelib/{abi => }/properties.rs (79%) diff --git a/api/sixtyfps-rs/lib.rs b/api/sixtyfps-rs/lib.rs index 96b2b9990..db257eb10 100644 --- a/api/sixtyfps-rs/lib.rs +++ b/api/sixtyfps-rs/lib.rs @@ -76,7 +76,6 @@ pub mod re_exports { pub use once_cell::unsync::OnceCell; pub use pin_weak::rc::*; pub use sixtyfps_corelib::abi::datastructures::*; - pub use sixtyfps_corelib::abi::properties::{Property, PropertyListenerScope}; pub use sixtyfps_corelib::abi::signals::Signal; pub use sixtyfps_corelib::abi::slice::Slice; pub use sixtyfps_corelib::animations::EasingCurve; @@ -93,6 +92,7 @@ pub mod re_exports { grid_layout_info, solve_grid_layout, solve_path_layout, GridLayoutCellData, GridLayoutData, PathLayoutData, PathLayoutItemData, }; + pub use sixtyfps_corelib::properties::{Property, PropertyListenerScope}; pub use sixtyfps_corelib::Color; pub use sixtyfps_corelib::ComponentVTable_static; pub use sixtyfps_corelib::Resource; diff --git a/sixtyfps_runtime/corelib/build.rs b/sixtyfps_runtime/corelib/build.rs index d6d1679d7..99cb5a3b2 100644 --- a/sixtyfps_runtime/corelib/build.rs +++ b/sixtyfps_runtime/corelib/build.rs @@ -78,7 +78,7 @@ fn main() { cbindgen::Builder::new() .with_config(config.clone()) - .with_src(crate_dir.join("abi/properties.rs")) + .with_src(crate_dir.join("properties.rs")) .with_src(crate_dir.join("abi/signals.rs")) .with_after_include("namespace sixtyfps { struct Color; }") .generate() diff --git a/sixtyfps_runtime/corelib/eventloop.rs b/sixtyfps_runtime/corelib/eventloop.rs index 74789ac50..79b335312 100644 --- a/sixtyfps_runtime/corelib/eventloop.rs +++ b/sixtyfps_runtime/corelib/eventloop.rs @@ -6,7 +6,7 @@ use std::{ }; use vtable::*; -use crate::{graphics::Size, input::MouseEventType}; +use crate::{graphics::Size, input::MouseEventType, properties::PropertyListenerScope}; #[cfg(not(target_arch = "wasm32"))] use winit::platform::desktop::EventLoopExtDesktop; @@ -87,7 +87,7 @@ impl EventLoop { ) { use winit::event::Event; use winit::event_loop::{ControlFlow, EventLoopWindowTarget}; - let layout_listener = Rc::pin(crate::abi::properties::PropertyListenerScope::default()); + let layout_listener = Rc::pin(PropertyListenerScope::default()); let mut cursor_pos = winit::dpi::PhysicalPosition::new(0., 0.); let mut run_fn = move |event: Event<()>, diff --git a/sixtyfps_runtime/corelib/graphics.rs b/sixtyfps_runtime/corelib/graphics.rs index e4e3a793d..013d5637c 100644 --- a/sixtyfps_runtime/corelib/graphics.rs +++ b/sixtyfps_runtime/corelib/graphics.rs @@ -1,5 +1,6 @@ extern crate alloc; use crate::input::{MouseEvent, MouseEventType}; +use crate::properties::InterpolatedPropertyValue; #[cfg(feature = "rtti")] use crate::rtti::{BuiltinItem, FieldInfo, FieldOffset, PropertyInfo, ValueType}; @@ -83,7 +84,7 @@ impl From for Color { } } -impl crate::abi::properties::InterpolatedPropertyValue for Color { +impl InterpolatedPropertyValue for Color { fn interpolate(self, target_value: Self, t: f32) -> Self { Self { red: self.red.interpolate(target_value.red, t), diff --git a/sixtyfps_runtime/corelib/lib.rs b/sixtyfps_runtime/corelib/lib.rs index 48a19ac73..e28381d31 100644 --- a/sixtyfps_runtime/corelib/lib.rs +++ b/sixtyfps_runtime/corelib/lib.rs @@ -28,7 +28,6 @@ pub mod abi { #![allow(unsafe_code)] pub mod datastructures; pub mod model; - pub mod properties; pub mod sharedarray; pub mod signals; pub mod slice; @@ -37,6 +36,7 @@ pub mod abi { } pub mod items; +pub mod properties; #[doc(inline)] pub use abi::string::SharedString; @@ -48,7 +48,7 @@ pub use abi::sharedarray::SharedArray; pub use graphics::Resource; #[doc(inline)] -pub use abi::properties::Property; +pub use properties::Property; #[doc(inline)] pub use abi::signals::Signal; @@ -77,4 +77,5 @@ pub fn use_modules() -> usize { + layout::solve_grid_layout as usize + item_tree::ffi::sixtyfps_visit_item_tree as usize + graphics::ffi::sixtyfps_new_path_elements as usize + + properties::ffi::sixtyfps_property_init as usize } diff --git a/sixtyfps_runtime/corelib/abi/properties.rs b/sixtyfps_runtime/corelib/properties.rs similarity index 79% rename from sixtyfps_runtime/corelib/abi/properties.rs rename to sixtyfps_runtime/corelib/properties.rs index bec2e4b9a..866a952f7 100644 --- a/sixtyfps_runtime/corelib/abi/properties.rs +++ b/sixtyfps_runtime/corelib/properties.rs @@ -5,7 +5,11 @@ thin dst container, and intrusive linked list */ +#![allow(unsafe_code)] + mod single_linked_list_pin { + #![allow(unsafe_code)] + ///! A singled linked list whose nodes are pinned use core::pin::Pin; type NodePtr = Option>>>; @@ -726,85 +730,6 @@ fn properties_simple_test() { assert_eq!(g(&compo.area), 8 * 8 * 2); } -#[allow(non_camel_case_types)] -type c_void = (); -#[repr(C)] -/// Has the same layout as PropertyHandle -pub struct PropertyHandleOpaque(PropertyHandle); - -/// Initialize the first pointer of the Property. Does not initialize the content. -/// `out` is assumed to be uninitialized -#[no_mangle] -pub unsafe extern "C" fn sixtyfps_property_init(out: *mut PropertyHandleOpaque) { - core::ptr::write(out, PropertyHandleOpaque(PropertyHandle::default())); -} - -/// To be called before accessing the value -#[no_mangle] -pub unsafe extern "C" fn sixtyfps_property_update(handle: &PropertyHandleOpaque, val: *mut c_void) { - handle.0.update(val); - handle.0.register_as_dependency_to_current_binding(); -} - -/// Mark the fact that the property was changed and that its binding need to be removed, and -/// The dependencies marked dirty -#[no_mangle] -pub unsafe extern "C" fn sixtyfps_property_set_changed(handle: &PropertyHandleOpaque) { - handle.0.remove_binding(); - handle.0.mark_dirty(); -} - -fn make_c_function_binding( - binding: extern "C" fn(*mut c_void, *mut c_void), - user_data: *mut c_void, - drop_user_data: Option, -) -> impl Fn(*mut ()) -> BindingResult { - struct CFunctionBinding { - binding_function: extern "C" fn(*mut c_void, *mut T), - user_data: *mut c_void, - drop_user_data: Option, - } - - impl Drop for CFunctionBinding { - fn drop(&mut self) { - if let Some(x) = self.drop_user_data { - x(self.user_data) - } - } - } - - let b = CFunctionBinding { binding_function: binding, user_data, drop_user_data }; - - move |value_ptr| { - (b.binding_function)(b.user_data, value_ptr); - BindingResult::KeepBinding - } -} - -/// Set a binding -/// -/// The current implementation will do usually two memory alocation: -/// 1. the allocation from the calling code to allocate user_data -/// 2. the box allocation within this binding -/// It might be possible to reduce that by passing something with a -/// vtable, so there is the need for less memory allocation. -#[no_mangle] -pub unsafe extern "C" fn sixtyfps_property_set_binding( - handle: &PropertyHandleOpaque, - binding: extern "C" fn(user_data: *mut c_void, pointer_to_value: *mut c_void), - user_data: *mut c_void, - drop_user_data: Option, -) { - let binding = make_c_function_binding(binding, user_data, drop_user_data); - handle.0.set_binding(binding); -} - -/// Destroy handle -#[no_mangle] -pub unsafe extern "C" fn sixtyfps_property_drop(handle: *mut PropertyHandleOpaque) { - core::ptr::read(handle); -} - /// InterpolatedPropertyValue is a trait used to enable properties to be used with /// animations that interpolate values. The basic requirement is the ability to apply /// a progress that's typically between 0 and 1 to a range. @@ -841,126 +766,6 @@ impl InterpolatedPropertyValue for u8 { } } -fn c_set_animated_value( - handle: &PropertyHandleOpaque, - from: T, - to: T, - animation_data: &PropertyAnimation, -) { - let d = RefCell::new(PropertyValueAnimationData::new(from, to, animation_data.clone())); - handle.0.set_binding(move |val: *mut ()| { - let (value, finished) = d.borrow_mut().compute_interpolated_value(); - unsafe { - *(val as *mut T) = value; - } - if finished { - BindingResult::RemoveBinding - } else { - crate::animations::CURRENT_ANIMATION_DRIVER - .with(|driver| driver.set_has_active_animations()); - BindingResult::KeepBinding - } - }); -} - -/// Internal function to set up a property animation to the specified target value for an integer property. -#[no_mangle] -pub unsafe extern "C" fn sixtyfps_property_set_animated_value_int( - handle: &PropertyHandleOpaque, - from: i32, - to: i32, - animation_data: &PropertyAnimation, -) { - c_set_animated_value(handle, from, to, animation_data) -} - -/// Internal function to set up a property animation to the specified target value for a float property. -#[no_mangle] -pub unsafe extern "C" fn sixtyfps_property_set_animated_value_float( - handle: &PropertyHandleOpaque, - from: f32, - to: f32, - animation_data: &PropertyAnimation, -) { - c_set_animated_value(handle, from, to, animation_data) -} - -/// Internal function to set up a property animation to the specified target value for a color property. -#[no_mangle] -pub unsafe extern "C" fn sixtyfps_property_set_animated_value_color( - handle: &PropertyHandleOpaque, - from: Color, - to: Color, - animation_data: &PropertyAnimation, -) { - c_set_animated_value(handle, from, to, animation_data); -} - -unsafe fn c_set_animated_binding( - handle: &PropertyHandleOpaque, - binding: extern "C" fn(*mut c_void, *mut T), - user_data: *mut c_void, - drop_user_data: Option, - animation_data: &PropertyAnimation, -) { - let binding = core::mem::transmute::< - extern "C" fn(*mut c_void, *mut T), - extern "C" fn(*mut c_void, *mut ()), - >(binding); - handle.0.set_binding(AnimatedBindingCallable:: { - original_binding: PropertyHandle { - handle: Cell::new( - (alloc_binding_holder(make_c_function_binding(binding, user_data, drop_user_data)) - as usize) - | 0b10, - ), - }, - state: Cell::new(AnimatedBindingState::NotAnimating), - animation_data: RefCell::new(PropertyValueAnimationData::new( - T::default(), - T::default(), - animation_data.clone(), - )), - }); - handle.0.mark_dirty(); -} - -/// Internal function to set up a property animation between values produced by the specified binding for an integer property. -#[no_mangle] -pub unsafe extern "C" fn sixtyfps_property_set_animated_binding_int( - handle: &PropertyHandleOpaque, - binding: extern "C" fn(*mut c_void, *mut i32), - user_data: *mut c_void, - drop_user_data: Option, - animation_data: &PropertyAnimation, -) { - c_set_animated_binding(handle, binding, user_data, drop_user_data, animation_data); -} - -/// Internal function to set up a property animation between values produced by the specified binding for a float property. -#[no_mangle] -pub unsafe extern "C" fn sixtyfps_property_set_animated_binding_float( - handle: &PropertyHandleOpaque, - binding: extern "C" fn(*mut c_void, *mut f32), - user_data: *mut c_void, - drop_user_data: Option, - animation_data: &PropertyAnimation, -) { - c_set_animated_binding(handle, binding, user_data, drop_user_data, animation_data); -} - -/// Internal function to set up a property animation between values produced by the specified binding for a color property. -#[no_mangle] -pub unsafe extern "C" fn sixtyfps_property_set_animated_binding_color( - handle: &PropertyHandleOpaque, - binding: extern "C" fn(*mut c_void, *mut Color), - user_data: *mut c_void, - drop_user_data: Option, - animation_data: &PropertyAnimation, -) { - c_set_animated_binding(handle, binding, user_data, drop_user_data, animation_data); -} - #[cfg(test)] mod animation_tests { use super::*; @@ -1221,48 +1026,260 @@ fn test_property_listener_scope() { assert!(!scope.is_dirty()); } -#[repr(C)] -/// Opaque type representing the PropertyListenerScope -pub struct PropertyListenerOpaque { - dependencies: usize, - dep_nodes: [usize; 2], - vtable: usize, - dirty: bool, -} +pub(crate) mod ffi { + use super::*; -static_assertions::assert_eq_align!(PropertyListenerOpaque, PropertyListenerScope); -static_assertions::assert_eq_size!(PropertyListenerOpaque, PropertyListenerScope); + #[allow(non_camel_case_types)] + type c_void = (); + #[repr(C)] + /// Has the same layout as PropertyHandle + pub struct PropertyHandleOpaque(PropertyHandle); -/// Initialize the first pointer of the PropertyListenerScope. -/// `out` is assumed to be uninitialized -/// sixtyfps_property_listener_scope_drop need to be called after that -#[no_mangle] -pub unsafe extern "C" fn sixtyfps_property_listener_scope_init(out: *mut PropertyListenerOpaque) { - core::ptr::write(out as *mut PropertyListenerScope, PropertyListenerScope::default()); -} + /// Initialize the first pointer of the Property. Does not initialize the content. + /// `out` is assumed to be uninitialized + #[no_mangle] + pub unsafe extern "C" fn sixtyfps_property_init(out: *mut PropertyHandleOpaque) { + core::ptr::write(out, PropertyHandleOpaque(PropertyHandle::default())); + } -/// Call the callback with the user data. Any properties access within the callback will be registered. -#[no_mangle] -pub unsafe extern "C" fn sixtyfps_property_listener_scope_evaluate( - handle: *const PropertyListenerOpaque, - callback: extern "C" fn(user_data: *mut c_void), - user_data: *mut c_void, -) { - Pin::new_unchecked(&*(handle as *const PropertyListenerScope)).evaluate(|| callback(user_data)) -} + /// To be called before accessing the value + #[no_mangle] + pub unsafe extern "C" fn sixtyfps_property_update( + handle: &PropertyHandleOpaque, + val: *mut c_void, + ) { + handle.0.update(val); + handle.0.register_as_dependency_to_current_binding(); + } -/// Query if the property listener is dirty -#[no_mangle] -pub unsafe extern "C" fn sixtyfps_property_listener_scope_is_dirty( - handle: *const PropertyListenerOpaque, -) -> bool { - (*(handle as *const PropertyListenerScope)).is_dirty() -} + /// Mark the fact that the property was changed and that its binding need to be removed, and + /// The dependencies marked dirty + #[no_mangle] + pub unsafe extern "C" fn sixtyfps_property_set_changed(handle: &PropertyHandleOpaque) { + handle.0.remove_binding(); + handle.0.mark_dirty(); + } -/// Destroy handle -#[no_mangle] -pub unsafe extern "C" fn sixtyfps_property_listener_scope_drop( - handle: *mut PropertyListenerOpaque, -) { - core::ptr::read(handle as *mut PropertyListenerScope); + fn make_c_function_binding( + binding: extern "C" fn(*mut c_void, *mut c_void), + user_data: *mut c_void, + drop_user_data: Option, + ) -> impl Fn(*mut ()) -> BindingResult { + struct CFunctionBinding { + binding_function: extern "C" fn(*mut c_void, *mut T), + user_data: *mut c_void, + drop_user_data: Option, + } + + impl Drop for CFunctionBinding { + fn drop(&mut self) { + if let Some(x) = self.drop_user_data { + x(self.user_data) + } + } + } + + let b = CFunctionBinding { binding_function: binding, user_data, drop_user_data }; + + move |value_ptr| { + (b.binding_function)(b.user_data, value_ptr); + BindingResult::KeepBinding + } + } + + /// Set a binding + /// + /// The current implementation will do usually two memory alocation: + /// 1. the allocation from the calling code to allocate user_data + /// 2. the box allocation within this binding + /// It might be possible to reduce that by passing something with a + /// vtable, so there is the need for less memory allocation. + #[no_mangle] + pub unsafe extern "C" fn sixtyfps_property_set_binding( + handle: &PropertyHandleOpaque, + binding: extern "C" fn(user_data: *mut c_void, pointer_to_value: *mut c_void), + user_data: *mut c_void, + drop_user_data: Option, + ) { + let binding = make_c_function_binding(binding, user_data, drop_user_data); + handle.0.set_binding(binding); + } + + /// Destroy handle + #[no_mangle] + pub unsafe extern "C" fn sixtyfps_property_drop(handle: *mut PropertyHandleOpaque) { + core::ptr::read(handle); + } + + fn c_set_animated_value( + handle: &PropertyHandleOpaque, + from: T, + to: T, + animation_data: &PropertyAnimation, + ) { + let d = RefCell::new(PropertyValueAnimationData::new(from, to, animation_data.clone())); + handle.0.set_binding(move |val: *mut ()| { + let (value, finished) = d.borrow_mut().compute_interpolated_value(); + unsafe { + *(val as *mut T) = value; + } + if finished { + BindingResult::RemoveBinding + } else { + crate::animations::CURRENT_ANIMATION_DRIVER + .with(|driver| driver.set_has_active_animations()); + BindingResult::KeepBinding + } + }); + } + + /// Internal function to set up a property animation to the specified target value for an integer property. + #[no_mangle] + pub unsafe extern "C" fn sixtyfps_property_set_animated_value_int( + handle: &PropertyHandleOpaque, + from: i32, + to: i32, + animation_data: &PropertyAnimation, + ) { + c_set_animated_value(handle, from, to, animation_data) + } + + /// Internal function to set up a property animation to the specified target value for a float property. + #[no_mangle] + pub unsafe extern "C" fn sixtyfps_property_set_animated_value_float( + handle: &PropertyHandleOpaque, + from: f32, + to: f32, + animation_data: &PropertyAnimation, + ) { + c_set_animated_value(handle, from, to, animation_data) + } + + /// Internal function to set up a property animation to the specified target value for a color property. + #[no_mangle] + pub unsafe extern "C" fn sixtyfps_property_set_animated_value_color( + handle: &PropertyHandleOpaque, + from: Color, + to: Color, + animation_data: &PropertyAnimation, + ) { + c_set_animated_value(handle, from, to, animation_data); + } + + unsafe fn c_set_animated_binding( + handle: &PropertyHandleOpaque, + binding: extern "C" fn(*mut c_void, *mut T), + user_data: *mut c_void, + drop_user_data: Option, + animation_data: &PropertyAnimation, + ) { + let binding = core::mem::transmute::< + extern "C" fn(*mut c_void, *mut T), + extern "C" fn(*mut c_void, *mut ()), + >(binding); + handle.0.set_binding(AnimatedBindingCallable:: { + original_binding: PropertyHandle { + handle: Cell::new( + (alloc_binding_holder(make_c_function_binding( + binding, + user_data, + drop_user_data, + )) as usize) + | 0b10, + ), + }, + state: Cell::new(AnimatedBindingState::NotAnimating), + animation_data: RefCell::new(PropertyValueAnimationData::new( + T::default(), + T::default(), + animation_data.clone(), + )), + }); + handle.0.mark_dirty(); + } + + /// Internal function to set up a property animation between values produced by the specified binding for an integer property. + #[no_mangle] + pub unsafe extern "C" fn sixtyfps_property_set_animated_binding_int( + handle: &PropertyHandleOpaque, + binding: extern "C" fn(*mut c_void, *mut i32), + user_data: *mut c_void, + drop_user_data: Option, + animation_data: &PropertyAnimation, + ) { + c_set_animated_binding(handle, binding, user_data, drop_user_data, animation_data); + } + + /// Internal function to set up a property animation between values produced by the specified binding for a float property. + #[no_mangle] + pub unsafe extern "C" fn sixtyfps_property_set_animated_binding_float( + handle: &PropertyHandleOpaque, + binding: extern "C" fn(*mut c_void, *mut f32), + user_data: *mut c_void, + drop_user_data: Option, + animation_data: &PropertyAnimation, + ) { + c_set_animated_binding(handle, binding, user_data, drop_user_data, animation_data); + } + + /// Internal function to set up a property animation between values produced by the specified binding for a color property. + #[no_mangle] + pub unsafe extern "C" fn sixtyfps_property_set_animated_binding_color( + handle: &PropertyHandleOpaque, + binding: extern "C" fn(*mut c_void, *mut Color), + user_data: *mut c_void, + drop_user_data: Option, + animation_data: &PropertyAnimation, + ) { + c_set_animated_binding(handle, binding, user_data, drop_user_data, animation_data); + } + + #[repr(C)] + /// Opaque type representing the PropertyListenerScope + pub struct PropertyListenerOpaque { + dependencies: usize, + dep_nodes: [usize; 2], + vtable: usize, + dirty: bool, + } + + static_assertions::assert_eq_align!(PropertyListenerOpaque, PropertyListenerScope); + static_assertions::assert_eq_size!(PropertyListenerOpaque, PropertyListenerScope); + + /// Initialize the first pointer of the PropertyListenerScope. + /// `out` is assumed to be uninitialized + /// sixtyfps_property_listener_scope_drop need to be called after that + #[no_mangle] + pub unsafe extern "C" fn sixtyfps_property_listener_scope_init( + out: *mut PropertyListenerOpaque, + ) { + core::ptr::write(out as *mut PropertyListenerScope, PropertyListenerScope::default()); + } + + /// Call the callback with the user data. Any properties access within the callback will be registered. + #[no_mangle] + pub unsafe extern "C" fn sixtyfps_property_listener_scope_evaluate( + handle: *const PropertyListenerOpaque, + callback: extern "C" fn(user_data: *mut c_void), + user_data: *mut c_void, + ) { + Pin::new_unchecked(&*(handle as *const PropertyListenerScope)) + .evaluate(|| callback(user_data)) + } + + /// Query if the property listener is dirty + #[no_mangle] + pub unsafe extern "C" fn sixtyfps_property_listener_scope_is_dirty( + handle: *const PropertyListenerOpaque, + ) -> bool { + (*(handle as *const PropertyListenerScope)).is_dirty() + } + + /// Destroy handle + #[no_mangle] + pub unsafe extern "C" fn sixtyfps_property_listener_scope_drop( + handle: *mut PropertyListenerOpaque, + ) { + core::ptr::read(handle as *mut PropertyListenerScope); + } } diff --git a/sixtyfps_runtime/corelib/rtti.rs b/sixtyfps_runtime/corelib/rtti.rs index 524cfd3a8..f104573e2 100644 --- a/sixtyfps_runtime/corelib/rtti.rs +++ b/sixtyfps_runtime/corelib/rtti.rs @@ -109,7 +109,7 @@ impl PropertyInfo where Value: TryInto, T: TryInto, - T: crate::abi::properties::InterpolatedPropertyValue, + T: crate::properties::InterpolatedPropertyValue, { fn get(&self, item: Pin<&Item>) -> Result { self.0.get(item) diff --git a/sixtyfps_runtime/interpreter/dynamic_component.rs b/sixtyfps_runtime/interpreter/dynamic_component.rs index 33ce1cfed..b69f97968 100644 --- a/sixtyfps_runtime/interpreter/dynamic_component.rs +++ b/sixtyfps_runtime/interpreter/dynamic_component.rs @@ -8,11 +8,12 @@ use sixtyfps_compilerlib::layout::{GridLayout, Layout, LayoutItem, PathLayout}; use sixtyfps_compilerlib::typeregister::Type; use sixtyfps_compilerlib::*; use sixtyfps_corelib::abi::datastructures::{ComponentVTable, ItemVTable, WindowProperties}; -use sixtyfps_corelib::abi::{properties::PropertyListenerScope, slice::Slice}; +use sixtyfps_corelib::abi::slice::Slice; use sixtyfps_corelib::graphics::Resource; use sixtyfps_corelib::item_tree::{ItemTreeNode, ItemVisitorRefMut}; use sixtyfps_corelib::items::{Flickable, PropertyAnimation, Rectangle}; use sixtyfps_corelib::layout::LayoutInfo; +use sixtyfps_corelib::properties::{InterpolatedPropertyValue, PropertyListenerScope}; use sixtyfps_corelib::rtti::PropertyInfo; use sixtyfps_corelib::ComponentRefPin; use sixtyfps_corelib::{rtti, Color, Property, SharedString, Signal}; @@ -324,9 +325,8 @@ fn generate_component(root_component: &Rc) -> Rc>(), ) } - fn animated_property_info< - T: Clone + Default + sixtyfps_corelib::abi::properties::InterpolatedPropertyValue + 'static, - >() -> (Box>, dynamic_type::StaticTypeInfo) + fn animated_property_info( + ) -> (Box>, dynamic_type::StaticTypeInfo) where T: std::convert::TryInto, eval::Value: std::convert::TryInto,