use serde::{Deserialize, Serialize};
use std::{marker::PhantomData, rc::Rc};
mod graph_operations;
mod local_property;
mod properties_table;
mod shared_graph;
mod shared_property;
#[cfg(test)]
mod shared_tests;
#[cfg(test)]
mod tests;
mod untyped_property;
use crate::{Duration, EasingCurve, Interpolatable, TransitionQueueEntry};
use self::properties_table::{PropertyType, PROPERTY_MILLIS, PROPERTY_TIME};
pub use local_property::LocalProperty;
pub use properties_table::EffectDrainReport;
use properties_table::PROPERTY_TABLE;
#[doc(hidden)]
pub use shared_graph::{BindingScope, BindingScopeGuard};
pub use shared_graph::{PropertyGraph, PropertyGraphGuard};
pub use shared_property::{Property, Published, SharedPropertyValue};
pub use untyped_property::UntypedProperty;
mod private {
slotmap::new_key_type!(
pub struct PropertyId;
);
}
pub trait PropertyValue: Default + Clone + Interpolatable + 'static {}
impl<T: Default + Clone + Interpolatable + 'static> PropertyValue for T {}
pub trait PropertyBinding<T: PropertyValue>: Sized {
fn from_value(value: T) -> Self;
fn local(&self) -> LocalProperty<T>;
fn from_local(source: LocalProperty<T>) -> Self;
#[doc(hidden)]
fn value_for_conversion(&self) -> T;
}
thread_local! {
static GRAPH_CONVERSION: std::cell::Cell<bool> = const { std::cell::Cell::new(false) };
}
pub(crate) fn with_graph_conversion<R>(f: impl FnOnce() -> R) -> R {
struct Restore(bool);
impl Drop for Restore {
fn drop(&mut self) {
GRAPH_CONVERSION.with(|active| active.set(self.0));
}
}
let _restore = Restore(GRAPH_CONVERSION.with(|active| active.replace(true)));
f()
}
pub fn property_table_total_properties_count() -> usize {
PROPERTY_TABLE.with(|t| t.total_properties_count())
}
#[doc(hidden)]
pub fn register_effect_property(prop: &LocalProperty<()>) {
PROPERTY_TABLE.with(|t| t.register_effect(prop.untyped.id));
}
#[doc(hidden)]
pub fn register_effect_property_with_name(prop: &LocalProperty<()>, debug_name: &str) {
PROPERTY_TABLE.with(|t| t.register_effect_with_name(prop.untyped.id, Some(debug_name)));
}
#[doc(hidden)]
pub fn drain_effects(max_iterations: usize) -> usize {
PROPERTY_TABLE.with(|t| t.drain_effects(max_iterations))
}
#[doc(hidden)]
pub fn drain_effects_with_report(max_iterations: usize) -> EffectDrainReport {
PROPERTY_TABLE.with(|t| t.drain_effects_with_report(max_iterations))
}
#[doc(hidden)]
pub fn property_outbound_debug_names(prop: &UntypedProperty) -> Vec<String> {
PROPERTY_TABLE.with(|t| t.outbound_debug_names(prop.id))
}
#[doc(hidden)]
pub fn property_has_direct_outbound(source: &UntypedProperty, outbound: &UntypedProperty) -> bool {
PROPERTY_TABLE.with(|t| t.has_direct_outbound(source.id, outbound.id))
}
pub fn register_time(prop: &LocalProperty<u64>) {
PROPERTY_TIME.with_borrow_mut(|time| *time = prop.clone());
}
pub fn register_millis(prop: &LocalProperty<u64>) {
PROPERTY_MILLIS.with_borrow_mut(|time| *time = prop.clone());
}
#[doc(hidden)]
pub fn current_frame() -> u64 {
PROPERTY_TIME.with_borrow(|time| time.get())
}