use std::cell::RefCell;
use piet::RenderContext;
use std::rc::Rc;
use crate::runtime::StackFrame;
use crate::PaxEngine;
use pax_runtime_api::{EasingCurve, PropertyInstance, TransitionManager, TransitionQueueEntry};
pub struct PropertyExpression<T: Default> {
pub id: usize,
pub cached_value: T,
pub transition_manager: TransitionManager<T>,
}
impl<T: Default> PropertyExpression<T> {
pub fn new(id: usize) -> Self {
Self {
id,
cached_value: Default::default(),
transition_manager: TransitionManager::new(),
}
}
}
impl<T: Default + Clone> PropertyInstance<T> for PropertyExpression<T> {
fn get(&self) -> &T {
&self.cached_value
}
fn get_mut(&mut self) -> &mut T {
unreachable!()
}
fn _get_vtable_id(&self) -> Option<usize> {
Some(self.id)
}
fn set(&mut self, value: T) {
self.cached_value = value;
}
fn ease_to(&mut self, new_value: T, duration_frames: u64, curve: EasingCurve) {
self.transition_manager.value = Some(self.get().clone());
self.transition_manager.queue.clear();
self.transition_manager
.queue
.push_back(TransitionQueueEntry {
global_frame_started: None,
duration_frames,
curve,
starting_value: self.cached_value.clone(),
ending_value: new_value,
});
}
fn ease_to_later(&mut self, new_value: T, duration_frames: u64, curve: EasingCurve) {
if let None = self.transition_manager.value {
self.transition_manager.value = Some(self.get().clone());
}
self.transition_manager
.queue
.push_back(TransitionQueueEntry {
global_frame_started: None,
duration_frames,
curve,
starting_value: self.cached_value.clone(),
ending_value: new_value,
});
}
fn _get_transition_manager(&mut self) -> Option<&mut TransitionManager<T>> {
if let None = self.transition_manager.value {
None
} else {
Some(&mut self.transition_manager)
}
}
}
pub struct ExpressionContext<'a, R: 'static + RenderContext> {
pub engine: &'a PaxEngine<R>,
pub stack_frame: Rc<RefCell<StackFrame<R>>>,
}