zng_var

Struct VARS

source
pub struct VARS;
Expand description

Variable updates and animation service.

Implementations§

source§

impl VARS

source

pub fn update_id(&self) -> VarUpdateId

Id of the current vars update in the app scope.

Variable with AnyVar::last_update equal to this are new.

source

pub fn animations_enabled(&self) -> ArcCowVar<bool, ArcVar<bool>>

Read-write that defines if animations are enabled on the app.

The value is the same as sys_animations_enabled, if set the variable disconnects from system config.

source

pub fn sys_animations_enabled(&self) -> ReadOnlyArcVar<bool>

Read-only that tracks if animations are enabled in the operating system.

This is true by default, it updates when the operating system config changes.

source

pub fn frame_duration(&self) -> ArcVar<Duration>

Variable that defines the global frame duration, the default is 60fps (1.0 / 60.0).secs().

source

pub fn animation_time_scale(&self) -> ArcVar<Factor>

Variable that defines a global scale for the elapsed time of animations.

source

pub fn current_modify(&self) -> ModifyInfo

Info about the current context when requesting variable modification.

If is currently inside a VARS.animate closure, or inside a Var::modify closure requested by an animation, or inside an AnimationController, returns the info that was collected at the moment the animation was requested. Outside of animations gets an info with importance guaranteed to override the modify_importance.

source

pub fn animate<A>(&self, animation: A) -> AnimationHandle
where A: FnMut(&Animation) + Send + 'static,

Adds an animation closure that is called every frame to update captured variables, starting after next frame.

This is used to implement all Var<T> animations, it enables any kind of variable animation, including multiple variables.

Returns an AnimationHandle that can be used to monitor the animation status and to stop or to make the animation perm.

§Variable Control

Animations assume control of a variable on the first time they cause its value to be new, after this moment the AnyVar::is_animating value is true and AnyVar::modify_importance is the animation’s importance, until the animation stops. Only one animation can control a variable at a time, if an animation loses control of a variable all attempts to modify it from inside the animation are ignored.

Later started animations steal control from previous animations, update, modify or set calls also remove the variable from being affected by a running animation, even if just set to an equal value, that is, not actually updated.

§Nested Animations

Other animations can be started from inside the animation closure, these nested animations have the same importance as the parent animation, the animation handle is different and AnyVar::is_animating is false if the nested animation is dropped before the parent animation. But because the animations share the same importance the parent animation can set the variable again.

§Examples

The example animates a text variable from "Animation at 0%" to "Animation at 100%", when the animation stops the completed variable is set to true.

fn animate_text(text: &impl Var<Txt>, completed: &impl Var<bool>) {
    let transition = animation::Transition::new(0u8, 100);
    let mut prev_value = 101;
    VARS.animate(clmv!(text, completed, |animation| {
        let step = easing::expo(animation.elapsed_stop(1.secs()));
        let value = transition.sample(step);
        if value != prev_value {
            if value == 100 {
                animation.stop();
                let _ = completed.set(true);
            }
            let _ = text.set(formatx!("Animation at {value}%"));
            prev_value = value;
        }
    }))
    .perm()
}

Note that the animation can be stopped from the inside, the closure parameter is an Animation. In the example this is the only way to stop the animation, because perm was called. Animations hold a clone of the variables they affect and exist for the duration of the app if not stopped, causing the app to wake and call the animation closure for every frame.

This method is the most basic animation interface, used to build all other animations, its rare that you will need to use it directly, most of the time animation effects can be composted using the Var easing and mapping methods.

let value = var(0u8);
let text = value.map(|v| formatx!("Animation at {v}%"));
value.ease(100, 1.secs(), easing::expo);
§Optimization Tips

When no animation is running the app sleeps awaiting for an external event, update request or timer elapse, when at least one animation is running the app awakes every VARS.frame_duration. You can use Animation::sleep to pause the animation for a duration, if all animations are sleeping the app is also sleeping.

Animations lose control over a variable permanently when a newer animation modifies the var or the var is modified directly, but even if the animation can’t control any variables it keeps running. This happens because the system has no insight of all side effects caused by the animation closure. You can use the VARS.current_modify and AnyVar::modify_importance to detect when the animation no longer affects any variables and stop the animation to avoid awaking the app for no reason.

These optimizations are already implemented by the animations provided as methods of Var<T>.

§External Controller

The animation can be controlled from the inside using the Animation reference, it can be stopped using the returned AnimationHandle, and it can also be controlled by a registered AnimationController that can manage multiple animations at the same time, see with_animation_controller for more details.

source

pub fn with_animation_controller<R>( &self, controller: impl AnimationController, animate: impl FnOnce() -> R, ) -> R

Calls animate while controller is registered as the animation controller.

The controller is notified of animation events for each animation spawned by animate and can affect then with the same level of access as VARS.animate. Only one controller can affect animations at a time.

This can be used to manage multiple animations at the same time, or to get VARS.animate level of access to an animation that is not implemented to allow such access. Note that animation implementers are not required to support the full Animation API, for example, there is no guarantee that a restart requested by the controller will repeat the same animation.

The controller can start new animations, these animations will have the same controller if not overridden, you can use this method and the () controller to avoid this behavior.

source

pub fn perm(&self, value: impl Any + Send)

Keep the value alive for the app lifetime.

Auto Trait Implementations§

§

impl Freeze for VARS

§

impl RefUnwindSafe for VARS

§

impl Send for VARS

§

impl Sync for VARS

§

impl Unpin for VARS

§

impl UnwindSafe for VARS

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> IntoEither for T

source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> Pointable for T

§

const ALIGN: usize = _

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more