15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
2926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) * Copyright (C) 2013 Google Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions are
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Redistributions of source code must retain the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Redistributions in binary form must reproduce the above
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * copyright notice, this list of conditions and the following disclaimer
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the documentation and/or other materials provided with the
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * distribution.
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *     * Neither the name of Google Inc. nor the names of its
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * contributors may be used to endorse or promote products derived from
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * this software without specific prior written permission.
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3181a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)#include "config.h"
32d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "core/animation/AnimationNode.h"
3309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
34d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "core/animation/AnimationNodeTiming.h"
35d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/animation/AnimationPlayer.h"
36d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)#include "core/animation/TimingCalculations.h"
3781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
38c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
3981a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
4009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)namespace {
4109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
4209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)Timing::FillMode resolvedFillMode(Timing::FillMode fillMode, bool isAnimation)
4309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
4409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (fillMode != Timing::FillModeAuto)
4509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return fillMode;
4609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (isAnimation)
4709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return Timing::FillModeNone;
4809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return Timing::FillModeBoth;
4909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
5009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
5109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)} // namespace
5209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
53c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)AnimationNode::AnimationNode(const Timing& timing, PassOwnPtrWillBeRawPtr<EventDelegate> eventDelegate)
54d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    : m_parent(nullptr)
5593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)    , m_startTime(0)
56d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    , m_player(nullptr)
5710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    , m_timing(timing)
58f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)    , m_eventDelegate(eventDelegate)
59f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)    , m_calculated()
6009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    , m_needsUpdate(true)
6109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    , m_lastUpdateTime(nullValue())
6293ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles){
6310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    m_timing.assertValid();
6493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)}
6593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
66d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)double AnimationNode::iterationDuration() const
6781a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles){
6810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    double result = std::isnan(m_timing.iterationDuration) ? intrinsicIterationDuration() : m_timing.iterationDuration;
6909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT(result >= 0);
7009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return result;
7109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
7209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
73d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)double AnimationNode::repeatedDuration() const
7409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
7510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    const double result = multiplyZeroAlwaysGivesZero(iterationDuration(), m_timing.iterationCount);
7609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT(result >= 0);
7709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return result;
7809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
7909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
80d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)double AnimationNode::activeDurationInternal() const
8109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
8210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    const double result = m_timing.playbackRate
8310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        ? repeatedDuration() / std::abs(m_timing.playbackRate)
8493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)        : std::numeric_limits<double>::infinity();
8509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    ASSERT(result >= 0);
8609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return result;
8709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
8893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
89d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void AnimationNode::updateSpecifiedTiming(const Timing& timing)
9009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
91a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    // FIXME: Test whether the timing is actually different?
9210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch    m_timing = timing;
9309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    invalidate();
9409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (m_player)
95d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_player->setOutdated();
96a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    specifiedTimingChanged();
9709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
9893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
99d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void AnimationNode::updateInheritedTime(double inheritedTime, TimingUpdateReason reason) const
10009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
10109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    bool needsUpdate = m_needsUpdate || (m_lastUpdateTime != inheritedTime && !(isNull(m_lastUpdateTime) && isNull(inheritedTime)));
10209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_needsUpdate = false;
10309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    m_lastUpdateTime = inheritedTime;
10493ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)
10509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    const double localTime = inheritedTime - m_startTime;
10609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    double timeToNextIteration = std::numeric_limits<double>::infinity();
10709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (needsUpdate) {
10810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        const double activeDuration = this->activeDurationInternal();
10909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
11010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        const Phase currentPhase = calculatePhase(activeDuration, localTime, m_timing);
11109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        // FIXME: parentPhase depends on groups being implemented.
112d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        const AnimationNode::Phase parentPhase = AnimationNode::PhaseActive;
11310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch        const double activeTime = calculateActiveTime(activeDuration, resolvedFillMode(m_timing.fillMode, isAnimation()), localTime, parentPhase, currentPhase, m_timing);
11409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
11509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        double currentIteration;
11609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        double timeFraction;
11709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        if (const double iterationDuration = this->iterationDuration()) {
11810f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch            const double startOffset = multiplyZeroAlwaysGivesZero(m_timing.iterationStart, iterationDuration);
11909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            ASSERT(startOffset >= 0);
12010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch            const double scaledActiveTime = calculateScaledActiveTime(activeDuration, activeTime, startOffset, m_timing);
12110f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch            const double iterationTime = calculateIterationTime(iterationDuration, repeatedDuration(), scaledActiveTime, startOffset, m_timing);
12209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
12310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch            currentIteration = calculateCurrentIteration(iterationDuration, iterationTime, scaledActiveTime, m_timing);
12410f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch            timeFraction = calculateTransformedTime(currentIteration, iterationDuration, iterationTime, m_timing) / iterationDuration;
12509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
12609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            if (!isNull(iterationTime)) {
12710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch                timeToNextIteration = (iterationDuration - iterationTime) / std::abs(m_timing.playbackRate);
12809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                if (activeDuration - activeTime < timeToNextIteration)
12909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)                    timeToNextIteration = std::numeric_limits<double>::infinity();
13009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            }
13109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        } else {
13209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            const double localIterationDuration = 1;
13310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch            const double localRepeatedDuration = localIterationDuration * m_timing.iterationCount;
13409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            ASSERT(localRepeatedDuration >= 0);
13510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch            const double localActiveDuration = m_timing.playbackRate ? localRepeatedDuration / std::abs(m_timing.playbackRate) : std::numeric_limits<double>::infinity();
13609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            ASSERT(localActiveDuration >= 0);
13710f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch            const double localLocalTime = localTime < m_timing.startDelay ? localTime : localActiveDuration + m_timing.startDelay;
138d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)            const AnimationNode::Phase localCurrentPhase = calculatePhase(localActiveDuration, localLocalTime, m_timing);
13910f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch            const double localActiveTime = calculateActiveTime(localActiveDuration, resolvedFillMode(m_timing.fillMode, isAnimation()), localLocalTime, parentPhase, localCurrentPhase, m_timing);
14010f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch            const double startOffset = m_timing.iterationStart * localIterationDuration;
14109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)            ASSERT(startOffset >= 0);
14210f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch            const double scaledActiveTime = calculateScaledActiveTime(localActiveDuration, localActiveTime, startOffset, m_timing);
14310f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch            const double iterationTime = calculateIterationTime(localIterationDuration, localRepeatedDuration, scaledActiveTime, startOffset, m_timing);
14409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
14510f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch            currentIteration = calculateCurrentIteration(localIterationDuration, iterationTime, scaledActiveTime, m_timing);
14610f88d5669dbd969c059d61ba09fa37dd72ac559Ben Murdoch            timeFraction = calculateTransformedTime(currentIteration, localIterationDuration, iterationTime, m_timing);
14709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        }
14809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
14909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_calculated.currentIteration = currentIteration;
15009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_calculated.timeFraction = timeFraction;
15109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
15209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_calculated.phase = currentPhase;
15309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_calculated.isInEffect = !isNull(activeTime);
15409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_calculated.isInPlay = phase() == PhaseActive && (!m_parent || m_parent->isInPlay());
15509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_calculated.isCurrent = phase() == PhaseBefore || isInPlay() || (m_parent && m_parent->isCurrent());
15609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_calculated.localTime = m_lastUpdateTime - m_startTime;
15709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
158bfe3590b1806e3ff18f46ee3af5d4b83078f305aTorne (Richard Coles)
15909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // Test for events even if timing didn't need an update as the player may have gained a start time.
16009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    // FIXME: Refactor so that we can ASSERT(m_player) here, this is currently required to be nullable for testing.
161c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    if (reason == TimingUpdateForAnimationFrame && (!m_player || m_player->hasStartTime() || m_player->paused())) {
162323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        if (m_eventDelegate)
163323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)            m_eventDelegate->onEventCondition(this);
16409380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
16551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)
16609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (needsUpdate)  {
16709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        // FIXME: This probably shouldn't be recursive.
168d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        updateChildrenAndEffects();
16909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_calculated.timeToForwardsEffectChange = calculateTimeToEffectChange(true, localTime, timeToNextIteration);
17009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        m_calculated.timeToReverseEffectChange = calculateTimeToEffectChange(false, localTime, timeToNextIteration);
17109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    }
17281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)}
17381a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)
174d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)const AnimationNode::CalculatedTiming& AnimationNode::ensureCalculated() const
17509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles){
17609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    if (!m_player)
17709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)        return m_calculated;
178d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (m_player->outdated())
179323480423219ecd77329f8326dc5e0e3b50926d4Torne (Richard Coles)        m_player->update(TimingUpdateOnDemand);
180d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(!m_player->outdated());
18109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    return m_calculated;
18209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)}
18309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
184d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)PassRefPtrWillBeRawPtr<AnimationNodeTiming> AnimationNode::timing()
185d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
186d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    return AnimationNodeTiming::create(this);
187d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)}
188d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)
189d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)void AnimationNode::trace(Visitor* visitor)
190d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles){
191d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    visitor->trace(m_parent);
192d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)    visitor->trace(m_player);
193c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    visitor->trace(m_eventDelegate);
194d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
195d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
196c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
197