mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-03 07:04:34 +00:00
Use Pin<&Self> for Property::get
This commit is contained in:
parent
0029921f1a
commit
2d22bac451
5 changed files with 108 additions and 74 deletions
|
@ -112,15 +112,15 @@ Hello := Rectangle {
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut app = Hello::default();
|
let mut app = Hello::default();
|
||||||
|
|
||||||
app.plus_clicked.set_handler(|context, ()| {
|
app.plus_clicked.set_handler(|context, ()| {
|
||||||
let app = context.get_component::<Hello>().unwrap();
|
let app = context.get_component::<Hello>().unwrap();
|
||||||
app.counter.set(app.counter.get(context) + 1);
|
let counter = Hello::field_offsets().counter.apply_pin(app);
|
||||||
|
counter.set(counter.get(context) + 1);
|
||||||
});
|
});
|
||||||
app.minus_clicked.set_handler(|context, ()| {
|
app.minus_clicked.set_handler(|context, ()| {
|
||||||
let app = context.get_component::<Hello>().unwrap();
|
let app = context.get_component::<Hello>().unwrap();
|
||||||
app.counter.set(app.counter.get(context) - 1);
|
let counter = Hello::field_offsets().counter.apply_pin(app);
|
||||||
|
counter.set(counter.get(context) - 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
app.run();
|
app.run();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,13 @@ fn main() {
|
||||||
|
|
||||||
app.plus_clicked.set_handler(|context, ()| {
|
app.plus_clicked.set_handler(|context, ()| {
|
||||||
let app = context.get_component::<Hello>().unwrap();
|
let app = context.get_component::<Hello>().unwrap();
|
||||||
app.counter.set(app.counter.get(context) + 1);
|
let counter = Hello::field_offsets().counter.apply_pin(app);
|
||||||
|
counter.set(counter.get(context) + 1);
|
||||||
});
|
});
|
||||||
app.minus_clicked.set_handler(|context, ()| {
|
app.minus_clicked.set_handler(|context, ()| {
|
||||||
let app = context.get_component::<Hello>().unwrap();
|
let app = context.get_component::<Hello>().unwrap();
|
||||||
app.counter.set(app.counter.get(context) - 1);
|
let counter = Hello::field_offsets().counter.apply_pin(app);
|
||||||
|
counter.set(counter.get(context) - 1);
|
||||||
});
|
});
|
||||||
app.run();
|
app.run();
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ pub fn generate(component: &Rc<Component>, diag: &mut Diagnostics) -> Option<Tok
|
||||||
let eval_context = sixtyfps::re_exports::EvaluationContext::for_root_component(
|
let eval_context = sixtyfps::re_exports::EvaluationContext::for_root_component(
|
||||||
sixtyfps::re_exports::ComponentRef::new_pin(self)
|
sixtyfps::re_exports::ComponentRef::new_pin(self)
|
||||||
);
|
);
|
||||||
self.#prop_ident.emit(&eval_context, ())
|
Self::field_offsets().#prop_ident.apply_pin(self).emit(&eval_context, ())
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
|
@ -82,7 +82,7 @@ pub fn generate(component: &Rc<Component>, diag: &mut Diagnostics) -> Option<Tok
|
||||||
let eval_context = sixtyfps::re_exports::EvaluationContext::for_root_component(
|
let eval_context = sixtyfps::re_exports::EvaluationContext::for_root_component(
|
||||||
sixtyfps::re_exports::ComponentRef::new_pin(self)
|
sixtyfps::re_exports::ComponentRef::new_pin(self)
|
||||||
);
|
);
|
||||||
self.#prop_ident.get(&eval_context)
|
Self::field_offsets().#prop_ident.apply_pin(self).get(&eval_context)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
|
@ -92,7 +92,7 @@ pub fn generate(component: &Rc<Component>, diag: &mut Diagnostics) -> Option<Tok
|
||||||
quote!(
|
quote!(
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn #setter_ident(&self, value: #rust_property_type) {
|
fn #setter_ident(&self, value: #rust_property_type) {
|
||||||
self.#prop_ident.set(value)
|
Self::field_offsets().#prop_ident.apply(self).set(value)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.into(),
|
.into(),
|
||||||
|
@ -402,10 +402,16 @@ fn access_member(
|
||||||
let name_ident = quote::format_ident!("{}", name);
|
let name_ident = quote::format_ident!("{}", name);
|
||||||
let comp = quote!(#context.get_component::<#component_id>().unwrap());
|
let comp = quote!(#context.get_component::<#component_id>().unwrap());
|
||||||
if e.property_declarations.contains_key(name) {
|
if e.property_declarations.contains_key(name) {
|
||||||
(quote!(#comp.#name_ident), context)
|
(quote!(#component_id::field_offsets().#name_ident.apply_pin(#comp)), context)
|
||||||
} else {
|
} else {
|
||||||
let elem_ident = quote::format_ident!("{}", e.id);
|
let elem_ident = quote::format_ident!("{}", e.id);
|
||||||
(quote!(#comp.#elem_ident.#name_ident), context)
|
let elem_ty = quote::format_ident!("{}", e.base_type.as_builtin().class_name);
|
||||||
|
(
|
||||||
|
quote!((#component_id::field_offsets().#elem_ident + #elem_ty::field_offsets().#name_ident)
|
||||||
|
.apply_pin(#comp)
|
||||||
|
),
|
||||||
|
context,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
access_member(element, name, &enclosing_component, quote!(#context.parent_context.unwrap()))
|
access_member(element, name, &enclosing_component, quote!(#context.parent_context.unwrap()))
|
||||||
|
@ -438,14 +444,16 @@ fn compile_expression(e: &Expression, component: &Rc<Component>) -> TokenStream
|
||||||
}
|
}
|
||||||
Expression::RepeaterIndexReference { element } => {
|
Expression::RepeaterIndexReference { element } => {
|
||||||
if element.upgrade().unwrap().borrow().base_type == Type::Component(component.clone()) {
|
if element.upgrade().unwrap().borrow().base_type == Type::Component(component.clone()) {
|
||||||
quote!({ _self.index.get(context) })
|
let component_id = component_id(&component);
|
||||||
|
quote!({ #component_id::field_offsets().index.apply_pin(_self).get(context) })
|
||||||
} else {
|
} else {
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expression::RepeaterModelReference { element } => {
|
Expression::RepeaterModelReference { element } => {
|
||||||
if element.upgrade().unwrap().borrow().base_type == Type::Component(component.clone()) {
|
if element.upgrade().unwrap().borrow().base_type == Type::Component(component.clone()) {
|
||||||
quote!({ _self.model_data.get(context) })
|
let component_id = component_id(&component);
|
||||||
|
quote!({ #component_id::field_offsets().model_data.apply_pin(_self).get(context) })
|
||||||
} else {
|
} else {
|
||||||
todo!();
|
todo!();
|
||||||
}
|
}
|
||||||
|
@ -554,6 +562,8 @@ fn compute_layout(component: &Component) -> TokenStream {
|
||||||
let mut layouts = vec![];
|
let mut layouts = vec![];
|
||||||
for x in component.layout_constraints.borrow().0.iter() {
|
for x in component.layout_constraints.borrow().0.iter() {
|
||||||
let within = quote::format_ident!("{}", x.within.borrow().id);
|
let within = quote::format_ident!("{}", x.within.borrow().id);
|
||||||
|
let within_ty =
|
||||||
|
quote::format_ident!("{}", x.within.borrow().base_type.as_builtin().class_name);
|
||||||
let row_constraint = vec![quote!(Constraint::default()); x.row_count()];
|
let row_constraint = vec![quote!(Constraint::default()); x.row_count()];
|
||||||
let col_constraint = vec![quote!(Constraint::default()); x.col_count()];
|
let col_constraint = vec![quote!(Constraint::default()); x.col_count()];
|
||||||
let cells = x
|
let cells = x
|
||||||
|
@ -594,8 +604,10 @@ fn compute_layout(component: &Component) -> TokenStream {
|
||||||
solve_grid_layout(&GridLayoutData {
|
solve_grid_layout(&GridLayoutData {
|
||||||
row_constraint: Slice::from_slice(&[#(#row_constraint),*]),
|
row_constraint: Slice::from_slice(&[#(#row_constraint),*]),
|
||||||
col_constraint: Slice::from_slice(&[#(#col_constraint),*]),
|
col_constraint: Slice::from_slice(&[#(#col_constraint),*]),
|
||||||
width: self.#within.width.get(eval_context),
|
width: (Self::field_offsets().#within + #within_ty::field_offsets().width)
|
||||||
height: self.#within.height.get(eval_context),
|
.apply_pin(self).get(eval_context),
|
||||||
|
height: (Self::field_offsets().#within + #within_ty::field_offsets().height)
|
||||||
|
.apply_pin(self).get(eval_context),
|
||||||
x: 0.,
|
x: 0.,
|
||||||
y: 0.,
|
y: 0.,
|
||||||
cells: Slice::from_slice(&[#( Slice::from_slice(&[#( #cells ),*])),*]),
|
cells: Slice::from_slice(&[#( Slice::from_slice(&[#( #cells ),*])),*]),
|
||||||
|
|
|
@ -42,25 +42,27 @@ pub struct Rectangle {
|
||||||
impl Item for Rectangle {
|
impl Item for Rectangle {
|
||||||
fn geometry(self: Pin<&Self>, context: &EvaluationContext) -> Rect {
|
fn geometry(self: Pin<&Self>, context: &EvaluationContext) -> Rect {
|
||||||
euclid::rect(
|
euclid::rect(
|
||||||
self.x.get(context),
|
Self::field_offsets().x.apply_pin(self).get(context),
|
||||||
self.y.get(context),
|
Self::field_offsets().y.apply_pin(self).get(context),
|
||||||
self.width.get(context),
|
Self::field_offsets().width.apply_pin(self).get(context),
|
||||||
self.height.get(context),
|
Self::field_offsets().height.apply_pin(self).get(context),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
fn rendering_primitive(
|
fn rendering_primitive(
|
||||||
self: Pin<&Self>,
|
self: Pin<&Self>,
|
||||||
context: &crate::EvaluationContext,
|
context: &crate::EvaluationContext,
|
||||||
) -> RenderingPrimitive {
|
) -> RenderingPrimitive {
|
||||||
let width = self.width.get(context);
|
let width = Self::field_offsets().x.apply_pin(self).get(context);
|
||||||
let height = self.height.get(context);
|
let height = Self::field_offsets().height.apply_pin(self).get(context);
|
||||||
if width > 0. && height > 0. {
|
if width > 0. && height > 0. {
|
||||||
RenderingPrimitive::Rectangle {
|
RenderingPrimitive::Rectangle {
|
||||||
x: self.x.get(context),
|
x: Self::field_offsets().x.apply_pin(self).get(context),
|
||||||
y: self.y.get(context),
|
y: Self::field_offsets().y.apply_pin(self).get(context),
|
||||||
width,
|
width,
|
||||||
height,
|
height,
|
||||||
color: Color::from_argb_encoded(self.color.get(context)),
|
color: Color::from_argb_encoded(
|
||||||
|
Self::field_offsets().color.apply_pin(self).get(context),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
RenderingPrimitive::NoContents
|
RenderingPrimitive::NoContents
|
||||||
|
@ -104,10 +106,10 @@ pub struct Image {
|
||||||
impl Item for Image {
|
impl Item for Image {
|
||||||
fn geometry(self: Pin<&Self>, context: &crate::EvaluationContext) -> Rect {
|
fn geometry(self: Pin<&Self>, context: &crate::EvaluationContext) -> Rect {
|
||||||
euclid::rect(
|
euclid::rect(
|
||||||
self.x.get(context),
|
Self::field_offsets().x.apply_pin(self).get(context),
|
||||||
self.y.get(context),
|
Self::field_offsets().y.apply_pin(self).get(context),
|
||||||
self.width.get(context),
|
Self::field_offsets().width.apply_pin(self).get(context),
|
||||||
self.height.get(context),
|
Self::field_offsets().height.apply_pin(self).get(context),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
fn rendering_primitive(
|
fn rendering_primitive(
|
||||||
|
@ -115,9 +117,9 @@ impl Item for Image {
|
||||||
context: &crate::EvaluationContext,
|
context: &crate::EvaluationContext,
|
||||||
) -> RenderingPrimitive {
|
) -> RenderingPrimitive {
|
||||||
RenderingPrimitive::Image {
|
RenderingPrimitive::Image {
|
||||||
x: self.x.get(context),
|
x: Self::field_offsets().x.apply_pin(self).get(context),
|
||||||
y: self.y.get(context),
|
y: Self::field_offsets().y.apply_pin(self).get(context),
|
||||||
source: self.source.get(context),
|
source: Self::field_offsets().source.apply_pin(self).get(context),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,19 +162,26 @@ pub struct Text {
|
||||||
impl Item for Text {
|
impl Item for Text {
|
||||||
// FIXME: width / height. or maybe it doesn't matter? (
|
// FIXME: width / height. or maybe it doesn't matter? (
|
||||||
fn geometry(self: Pin<&Self>, context: &crate::EvaluationContext) -> Rect {
|
fn geometry(self: Pin<&Self>, context: &crate::EvaluationContext) -> Rect {
|
||||||
euclid::rect(self.x.get(context), self.y.get(context), 0., 0.)
|
euclid::rect(
|
||||||
|
Self::field_offsets().x.apply_pin(self).get(context),
|
||||||
|
Self::field_offsets().y.apply_pin(self).get(context),
|
||||||
|
0.,
|
||||||
|
0.,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
fn rendering_primitive(
|
fn rendering_primitive(
|
||||||
self: Pin<&Self>,
|
self: Pin<&Self>,
|
||||||
context: &crate::EvaluationContext,
|
context: &crate::EvaluationContext,
|
||||||
) -> RenderingPrimitive {
|
) -> RenderingPrimitive {
|
||||||
RenderingPrimitive::Text {
|
RenderingPrimitive::Text {
|
||||||
x: self.x.get(context),
|
x: Self::field_offsets().x.apply_pin(self).get(context),
|
||||||
y: self.y.get(context),
|
y: Self::field_offsets().y.apply_pin(self).get(context),
|
||||||
text: self.text.get(context),
|
text: Self::field_offsets().text.apply_pin(self).get(context),
|
||||||
font_family: self.font_family.get(context),
|
font_family: Self::field_offsets().font_family.apply_pin(self).get(context),
|
||||||
font_pixel_size: self.font_pixel_size.get(context),
|
font_pixel_size: Self::field_offsets().font_pixel_size.apply_pin(self).get(context),
|
||||||
color: Color::from_argb_encoded(self.color.get(context)),
|
color: Color::from_argb_encoded(
|
||||||
|
Self::field_offsets().color.apply_pin(self).get(context),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,10 +223,10 @@ pub struct TouchArea {
|
||||||
impl Item for TouchArea {
|
impl Item for TouchArea {
|
||||||
fn geometry(self: Pin<&Self>, context: &crate::EvaluationContext) -> Rect {
|
fn geometry(self: Pin<&Self>, context: &crate::EvaluationContext) -> Rect {
|
||||||
euclid::rect(
|
euclid::rect(
|
||||||
self.x.get(context),
|
Self::field_offsets().x.apply_pin(self).get(context),
|
||||||
self.y.get(context),
|
Self::field_offsets().y.apply_pin(self).get(context),
|
||||||
self.width.get(context),
|
Self::field_offsets().width.apply_pin(self).get(context),
|
||||||
self.height.get(context),
|
Self::field_offsets().height.apply_pin(self).get(context),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
fn rendering_primitive(
|
fn rendering_primitive(
|
||||||
|
@ -237,13 +246,13 @@ impl Item for TouchArea {
|
||||||
context: &crate::EvaluationContext,
|
context: &crate::EvaluationContext,
|
||||||
) {
|
) {
|
||||||
println!("Touch Area Event {:?}", event);
|
println!("Touch Area Event {:?}", event);
|
||||||
self.pressed.set(match event.what {
|
Self::field_offsets().pressed.apply_pin(self).set(match event.what {
|
||||||
super::datastructures::MouseEventType::MousePressed => true,
|
super::datastructures::MouseEventType::MousePressed => true,
|
||||||
super::datastructures::MouseEventType::MouseReleased => false,
|
super::datastructures::MouseEventType::MouseReleased => false,
|
||||||
super::datastructures::MouseEventType::MouseMoved => return,
|
super::datastructures::MouseEventType::MouseMoved => return,
|
||||||
});
|
});
|
||||||
if matches!(event.what, super::datastructures::MouseEventType::MouseReleased) {
|
if matches!(event.what, super::datastructures::MouseEventType::MouseReleased) {
|
||||||
self.clicked.emit(context, ())
|
Self::field_offsets().clicked.apply_pin(self).emit(context, ())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ use crate::abi::primitives::PropertyAnimation;
|
||||||
use crate::ComponentRefPin;
|
use crate::ComponentRefPin;
|
||||||
use core::cell::*;
|
use core::cell::*;
|
||||||
use core::ops::DerefMut;
|
use core::ops::DerefMut;
|
||||||
|
use core::pin::Pin;
|
||||||
use std::rc::{Rc, Weak};
|
use std::rc::{Rc, Weak};
|
||||||
|
|
||||||
thread_local!(static CURRENT_BINDING : RefCell<Option<Rc<dyn PropertyNotify>>> = Default::default());
|
thread_local!(static CURRENT_BINDING : RefCell<Option<Rc<dyn PropertyNotify>>> = Default::default());
|
||||||
|
@ -178,7 +179,7 @@ impl<T: Clone + 'static> Property<T> {
|
||||||
///
|
///
|
||||||
/// The context must be the constext matching the Component which contains this
|
/// The context must be the constext matching the Component which contains this
|
||||||
/// property
|
/// property
|
||||||
pub fn get(&self, context: &EvaluationContext) -> T {
|
pub fn get(self: Pin<&Self>, context: &EvaluationContext) -> T {
|
||||||
self.update(context);
|
self.update(context);
|
||||||
self.inner.clone().register_current_binding_as_dependency();
|
self.inner.clone().register_current_binding_as_dependency();
|
||||||
self.try_borrow().expect("Binding loop detected").1.clone()
|
self.try_borrow().expect("Binding loop detected").1.clone()
|
||||||
|
@ -303,6 +304,10 @@ impl<T: Clone + InterpolatedPropertyValue + 'static> Property<T> {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn properties_simple_test() {
|
fn properties_simple_test() {
|
||||||
|
fn g(prop: &Property<i32>, ctx: &EvaluationContext) -> i32 {
|
||||||
|
unsafe { Pin::new_unchecked(prop).get(ctx) }
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct Component {
|
struct Component {
|
||||||
width: Property<i32>,
|
width: Property<i32>,
|
||||||
|
@ -319,22 +324,22 @@ fn properties_simple_test() {
|
||||||
let w = Rc::downgrade(&compo);
|
let w = Rc::downgrade(&compo);
|
||||||
compo.area.set_binding(move |ctx| {
|
compo.area.set_binding(move |ctx| {
|
||||||
let compo = w.upgrade().unwrap();
|
let compo = w.upgrade().unwrap();
|
||||||
compo.width.get(ctx) * compo.height.get(ctx)
|
g(&compo.width, ctx) * g(&compo.height, ctx)
|
||||||
});
|
});
|
||||||
compo.width.set(4);
|
compo.width.set(4);
|
||||||
compo.height.set(8);
|
compo.height.set(8);
|
||||||
assert_eq!(compo.width.get(&dummy_eval_context), 4);
|
assert_eq!(g(&compo.width, &dummy_eval_context), 4);
|
||||||
assert_eq!(compo.height.get(&dummy_eval_context), 8);
|
assert_eq!(g(&compo.height, &dummy_eval_context), 8);
|
||||||
assert_eq!(compo.area.get(&dummy_eval_context), 4 * 8);
|
assert_eq!(g(&compo.area, &dummy_eval_context), 4 * 8);
|
||||||
|
|
||||||
let w = Rc::downgrade(&compo);
|
let w = Rc::downgrade(&compo);
|
||||||
compo.width.set_binding(move |ctx| {
|
compo.width.set_binding(move |ctx| {
|
||||||
let compo = w.upgrade().unwrap();
|
let compo = w.upgrade().unwrap();
|
||||||
compo.height.get(ctx) * 2
|
g(&compo.height, ctx) * 2
|
||||||
});
|
});
|
||||||
assert_eq!(compo.width.get(&dummy_eval_context), 8 * 2);
|
assert_eq!(g(&compo.width, &dummy_eval_context), 8 * 2);
|
||||||
assert_eq!(compo.height.get(&dummy_eval_context), 8);
|
assert_eq!(g(&compo.height, &dummy_eval_context), 8);
|
||||||
assert_eq!(compo.area.get(&dummy_eval_context), 8 * 8 * 2);
|
assert_eq!(g(&compo.area, &dummy_eval_context), 8 * 8 * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
|
@ -724,6 +729,9 @@ mod test {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn properties_test_animation_triggered_by_set() {
|
fn properties_test_animation_triggered_by_set() {
|
||||||
|
fn g(prop: &Property<i32>, ctx: &EvaluationContext) -> i32 {
|
||||||
|
unsafe { Pin::new_unchecked(prop).get(ctx) }
|
||||||
|
}
|
||||||
let dummy_eval_context = EvaluationContext {
|
let dummy_eval_context = EvaluationContext {
|
||||||
component: unsafe {
|
component: unsafe {
|
||||||
core::pin::Pin::new_unchecked(vtable::VRef::from_raw(
|
core::pin::Pin::new_unchecked(vtable::VRef::from_raw(
|
||||||
|
@ -738,38 +746,41 @@ mod test {
|
||||||
let w = Rc::downgrade(&compo);
|
let w = Rc::downgrade(&compo);
|
||||||
compo.width_times_two.set_binding(move |context| {
|
compo.width_times_two.set_binding(move |context| {
|
||||||
let compo = w.upgrade().unwrap();
|
let compo = w.upgrade().unwrap();
|
||||||
compo.width.get(context) * 2
|
g(&compo.width, context) * 2
|
||||||
});
|
});
|
||||||
|
|
||||||
let animation_details = PropertyAnimation { duration: 10000 };
|
let animation_details = PropertyAnimation { duration: 10000 };
|
||||||
|
|
||||||
compo.width.set(100);
|
compo.width.set(100);
|
||||||
assert_eq!(compo.width.get(&dummy_eval_context), 100);
|
assert_eq!(g(&compo.width, &dummy_eval_context), 100);
|
||||||
assert_eq!(compo.width_times_two.get(&dummy_eval_context), 200);
|
assert_eq!(g(&compo.width_times_two, &dummy_eval_context), 200);
|
||||||
|
|
||||||
let animation = compo.width.set_animated_value(200, &animation_details);
|
let animation = compo.width.set_animated_value(200, &animation_details);
|
||||||
assert_eq!(compo.width.get(&dummy_eval_context), 100);
|
assert_eq!(g(&compo.width, &dummy_eval_context), 100);
|
||||||
assert_eq!(compo.width_times_two.get(&dummy_eval_context), 200);
|
assert_eq!(g(&compo.width_times_two, &dummy_eval_context), 200);
|
||||||
assert_eq!(animation.borrow().from_value, 100);
|
assert_eq!(animation.borrow().from_value, 100);
|
||||||
assert_eq!(animation.borrow().to_value, 200);
|
assert_eq!(animation.borrow().to_value, 200);
|
||||||
|
|
||||||
animation.clone().update_animation_state(AnimationState::Running { progress: 0.5 });
|
animation.clone().update_animation_state(AnimationState::Running { progress: 0.5 });
|
||||||
assert_eq!(compo.width.get(&dummy_eval_context), 150);
|
assert_eq!(g(&compo.width, &dummy_eval_context), 150);
|
||||||
assert_eq!(compo.width_times_two.get(&dummy_eval_context), 300);
|
assert_eq!(g(&compo.width_times_two, &dummy_eval_context), 300);
|
||||||
|
|
||||||
animation.clone().update_animation_state(AnimationState::Running { progress: 1.0 });
|
animation.clone().update_animation_state(AnimationState::Running { progress: 1.0 });
|
||||||
assert_eq!(compo.width.get(&dummy_eval_context), 200);
|
assert_eq!(g(&compo.width, &dummy_eval_context), 200);
|
||||||
assert_eq!(compo.width_times_two.get(&dummy_eval_context), 400);
|
assert_eq!(g(&compo.width_times_two, &dummy_eval_context), 400);
|
||||||
|
|
||||||
animation.clone().update_animation_state(AnimationState::Stopped);
|
animation.clone().update_animation_state(AnimationState::Stopped);
|
||||||
assert_eq!(compo.width.get(&dummy_eval_context), 200);
|
assert_eq!(g(&compo.width, &dummy_eval_context), 200);
|
||||||
assert_eq!(compo.width_times_two.get(&dummy_eval_context), 400);
|
assert_eq!(g(&compo.width_times_two, &dummy_eval_context), 400);
|
||||||
|
|
||||||
assert_eq!(Rc::strong_count(&animation), 1);
|
assert_eq!(Rc::strong_count(&animation), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn properties_test_animation_triggered_by_binding() {
|
fn properties_test_animation_triggered_by_binding() {
|
||||||
|
fn g(prop: &Property<i32>, ctx: &EvaluationContext) -> i32 {
|
||||||
|
unsafe { Pin::new_unchecked(prop).get(ctx) }
|
||||||
|
}
|
||||||
let dummy_eval_context = EvaluationContext {
|
let dummy_eval_context = EvaluationContext {
|
||||||
component: unsafe {
|
component: unsafe {
|
||||||
core::pin::Pin::new_unchecked(vtable::VRef::from_raw(
|
core::pin::Pin::new_unchecked(vtable::VRef::from_raw(
|
||||||
|
@ -784,7 +795,7 @@ mod test {
|
||||||
let w = Rc::downgrade(&compo);
|
let w = Rc::downgrade(&compo);
|
||||||
compo.width_times_two.set_binding(move |context| {
|
compo.width_times_two.set_binding(move |context| {
|
||||||
let compo = w.upgrade().unwrap();
|
let compo = w.upgrade().unwrap();
|
||||||
compo.width.get(context) * 2
|
g(&compo.width, context) * 2
|
||||||
});
|
});
|
||||||
|
|
||||||
let w = Rc::downgrade(&compo);
|
let w = Rc::downgrade(&compo);
|
||||||
|
@ -794,29 +805,29 @@ mod test {
|
||||||
let animation = compo.width.set_animated_binding(
|
let animation = compo.width.set_animated_binding(
|
||||||
move |context| {
|
move |context| {
|
||||||
let compo = w.upgrade().unwrap();
|
let compo = w.upgrade().unwrap();
|
||||||
compo.feed_property.get(context)
|
g(&compo.feed_property, context)
|
||||||
},
|
},
|
||||||
&animation_details,
|
&animation_details,
|
||||||
);
|
);
|
||||||
|
|
||||||
compo.feed_property.set(100);
|
compo.feed_property.set(100);
|
||||||
assert_eq!(compo.width.get(&dummy_eval_context), 100);
|
assert_eq!(g(&compo.width, &dummy_eval_context), 100);
|
||||||
assert_eq!(compo.width_times_two.get(&dummy_eval_context), 200);
|
assert_eq!(g(&compo.width_times_two, &dummy_eval_context), 200);
|
||||||
|
|
||||||
compo.feed_property.set(200);
|
compo.feed_property.set(200);
|
||||||
assert_eq!(compo.width.get(&dummy_eval_context), 100);
|
assert_eq!(g(&compo.width, &dummy_eval_context), 100);
|
||||||
assert_eq!(compo.width_times_two.get(&dummy_eval_context), 200);
|
assert_eq!(g(&compo.width_times_two, &dummy_eval_context), 200);
|
||||||
|
|
||||||
animation.clone().update_animation_state(AnimationState::Running { progress: 0.5 });
|
animation.clone().update_animation_state(AnimationState::Running { progress: 0.5 });
|
||||||
|
|
||||||
assert_eq!(compo.width.get(&dummy_eval_context), 150);
|
assert_eq!(g(&compo.width, &dummy_eval_context), 150);
|
||||||
assert_eq!(compo.width_times_two.get(&dummy_eval_context), 300);
|
assert_eq!(g(&compo.width_times_two, &dummy_eval_context), 300);
|
||||||
assert_eq!(animation.borrow().from_value, 100);
|
assert_eq!(animation.borrow().from_value, 100);
|
||||||
assert_eq!(animation.borrow().to_value, 200);
|
assert_eq!(animation.borrow().to_value, 200);
|
||||||
|
|
||||||
animation.clone().update_animation_state(AnimationState::Running { progress: 1.0 });
|
animation.clone().update_animation_state(AnimationState::Running { progress: 1.0 });
|
||||||
|
|
||||||
assert_eq!(compo.width.get(&dummy_eval_context), 200);
|
assert_eq!(g(&compo.width, &dummy_eval_context), 200);
|
||||||
assert_eq!(compo.width_times_two.get(&dummy_eval_context), 400);
|
assert_eq!(g(&compo.width_times_two, &dummy_eval_context), 400);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue