pub struct AnimationStore {
anims: RefCell<Vec<Box<dyn CoreItemAnimation>>>,
}Expand description
A store of animations
It has interior mutability, because when pushing an animation into it, we need to return a reference to the animation, which is bound to the store’s lifetime.
To allow the mutation, we use a RefCell<Vec<Box<dyn AnyAnimation>>> in its inner.
§Safety Contract
The following invariants must be maintained:
-
No mutation after push: Once an animation is pushed into the store, it should never be mutated or removed. The only allowed mutation is pushing new animations into the store.
-
No Vec reallocation issues: The returned references from
push_eval_dynamicpoint directly to the heap-allocatedAnimationCell<T>data inside theBox<dyn AnyAnimation>. Even if theVecreallocates (which moves theBoxes), the heap data itself doesn’t move, so the pointers remain valid. This is safe becauseBoxowns heap-allocated data, and the data doesn’t move when theBoxis moved within theVec.
Fields§
§anims: RefCell<Vec<Box<dyn CoreItemAnimation>>>Implementations§
Source§impl AnimationStore
impl AnimationStore
Sourcepub fn push_animation<T: AnyExtractCoreItem>(
&self,
anim: AnimationCell<T>,
) -> &AnimationCell<T>
pub fn push_animation<T: AnyExtractCoreItem>( &self, anim: AnimationCell<T>, ) -> &AnimationCell<T>
Push an AnimationCell<T> into the store and return a reference to it.
The returned reference is bound to &self’s lifetime, which means it will be invalidated
when the store is dropped. Since we use RefCell for interior mutability, we can modify
the internal Vec while holding a shared reference &self.
§Safety
This function uses unsafe code to return a reference that outlives the RefCell borrow.
The safety relies on the following guarantees:
-
Pointer validity: The raw pointer
ptrpoints to the heap-allocatedAnimationCell<T>that is now owned by theVec<Box<dyn AnyAnimation>>insideself.anims. -
Memory layout: When we coerce
Box<AnimationCell<T>>toBox<dyn AnyAnimation>, only the vtable pointer changes. The data pointer (pointing to the actualAnimationCell<T>on the heap) remains the same, soptris still valid. -
Vec reallocation safety: Even if the
Vecreallocates (which moves theBoxes), the heap-allocatedAnimationCell<T>data inside eachBoxdoes not move. The pointerptrpoints directly to this heap data, not to theBoxitself, so it remains valid regardless ofVecreallocations. This is a key property ofBox: moving theBoxdoesn’t move the data it points to on the heap. -
Lifetime binding: The returned reference
&AnimationCell<T>has a lifetime that is inferred from&self, ensuring it cannot outlive the store. This is enforced by Rust’s borrow checker. -
No mutation after push: Once pushed, the animation is never mutated or removed, so the pointer remains valid for the lifetime of the store.
Trait Implementations§
Source§impl Default for AnimationStore
impl Default for AnimationStore
Source§fn default() -> AnimationStore
fn default() -> AnimationStore
Auto Trait Implementations§
impl !Freeze for AnimationStore
impl !RefUnwindSafe for AnimationStore
impl !Send for AnimationStore
impl !Sync for AnimationStore
impl Unpin for AnimationStore
impl !UnwindSafe for AnimationStore
Blanket Implementations§
§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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