Files
tubestation/dom/animation/AnimationTimeline.cpp
Boris Chiou bee79af4be Bug 1676791 - Part 2: Implement the infrastructure of scroll-linked animations. r=emilio,hiro
The basic part of the infrastructure of scroll-linked animations. This is
designed based on scroll-linked animation generated by CSS. We will
implement the timing computation and hook the ScrollTimeline to the CSS
animations in the following patches.

All the tests are in the patch that hooks ScrollTimeline to CSS Animation.

Differential Revision: https://phabricator.services.mozilla.com/D129100
2021-12-08 01:16:28 +00:00

90 lines
3.0 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "AnimationTimeline.h"
#include "mozilla/AnimationComparator.h"
#include "mozilla/dom/Animation.h"
namespace mozilla::dom {
AnimationTimeline::~AnimationTimeline() { mAnimationOrder.clear(); }
NS_IMPL_CYCLE_COLLECTION_CLASS(AnimationTimeline)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(AnimationTimeline)
tmp->mAnimationOrder.clear();
NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow, mAnimations)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(AnimationTimeline)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow, mAnimations)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(AnimationTimeline)
NS_IMPL_CYCLE_COLLECTING_ADDREF(AnimationTimeline)
NS_IMPL_CYCLE_COLLECTING_RELEASE(AnimationTimeline)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AnimationTimeline)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
bool AnimationTimeline::Tick() {
bool needsTicks = false;
nsTArray<Animation*> animationsToRemove;
for (Animation* animation = mAnimationOrder.getFirst(); animation;
animation =
static_cast<LinkedListElement<Animation>*>(animation)->getNext()) {
// Skip any animations that are longer need associated with this timeline.
if (animation->GetTimeline() != this) {
// If animation has some other timeline, it better not be also in the
// animation list of this timeline object!
MOZ_ASSERT(!animation->GetTimeline());
animationsToRemove.AppendElement(animation);
continue;
}
needsTicks |= animation->NeedsTicks();
// Even if |animation| doesn't need future ticks, we should still
// Tick it this time around since it might just need a one-off tick in
// order to dispatch events.
animation->Tick();
if (!animation->NeedsTicks()) {
animationsToRemove.AppendElement(animation);
}
}
for (Animation* animation : animationsToRemove) {
RemoveAnimation(animation);
}
return needsTicks;
}
void AnimationTimeline::NotifyAnimationUpdated(Animation& aAnimation) {
if (mAnimations.EnsureInserted(&aAnimation)) {
if (aAnimation.GetTimeline() && aAnimation.GetTimeline() != this) {
aAnimation.GetTimeline()->RemoveAnimation(&aAnimation);
}
mAnimationOrder.insertBack(&aAnimation);
}
}
void AnimationTimeline::RemoveAnimation(Animation* aAnimation) {
MOZ_ASSERT(!aAnimation->GetTimeline() || aAnimation->GetTimeline() == this);
if (static_cast<LinkedListElement<Animation>*>(aAnimation)->isInList()) {
static_cast<LinkedListElement<Animation>*>(aAnimation)->remove();
}
mAnimations.Remove(aAnimation);
}
} // namespace mozilla::dom