#include "config.h"
#include "AnimationBase.h"
-#include "AnimationController.h"
-#include "KeyframeAnimation.h"
-#include "ImplicitAnimation.h"
-#include "CompositeAnimation.h"
+#include "AnimationController.h"
#include "CSSPropertyNames.h"
#include "CString.h"
+#include "CompositeAnimation.h"
#include "Document.h"
#include "EventNames.h"
#include "FloatConversion.h"
#include "Frame.h"
+#include "ImplicitAnimation.h"
+#include "KeyframeAnimation.h"
#include "RenderObject.h"
#include "RenderStyle.h"
#include "SystemTime.h"
}
AnimationEventDispatcher::AnimationEventDispatcher(AnimationBase* anim)
-: AnimationTimerBase(anim)
-, m_property(CSSPropertyInvalid)
-, m_reset(false)
-, m_elapsedTime(-1)
+ : AnimationTimerBase(anim)
+ , m_property(CSSPropertyInvalid)
+ , m_reset(false)
+ , m_elapsedTime(-1)
{
}
class PropertyWrapperBase {
public:
PropertyWrapperBase(int prop)
- : m_prop(prop)
- { }
+ : m_prop(prop)
+ {
+ }
+
virtual ~PropertyWrapperBase() { }
- virtual bool equals(const RenderStyle* a, const RenderStyle* b) const=0;
- virtual void blend(RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double prog) const=0;
-
+ virtual bool equals(const RenderStyle* a, const RenderStyle* b) const = 0;
+ virtual void blend(RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const = 0;
+
int property() const { return m_prop; }
-
+
private:
int m_prop;
};
class PropertyWrapperGetter : public PropertyWrapperBase {
public:
PropertyWrapperGetter(int prop, T (RenderStyle::*getter)() const)
- : PropertyWrapperBase(prop)
- , m_getter(getter)
- { }
-
+ : PropertyWrapperBase(prop)
+ , m_getter(getter)
+ {
+ }
+
virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
{
return (a->*m_getter)() == (b->*m_getter)();
}
-
+
protected:
T (RenderStyle::*m_getter)() const;
};
class PropertyWrapper : public PropertyWrapperGetter<T> {
public:
PropertyWrapper(int prop, T (RenderStyle::*getter)() const, void (RenderStyle::*setter)(T))
- : PropertyWrapperGetter<T>(prop, getter)
- , m_setter(setter)
- { }
-
- virtual void blend(RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double prog) const
+ : PropertyWrapperGetter<T>(prop, getter)
+ , m_setter(setter)
{
- (dst->*m_setter)(blendFunc((a->*PropertyWrapperGetter<T>::m_getter)(), (b->*PropertyWrapperGetter<T>::m_getter)(), prog));
}
+ virtual void blend(RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
+ {
+ (dst->*m_setter)(blendFunc((a->*PropertyWrapperGetter<T>::m_getter)(), (b->*PropertyWrapperGetter<T>::m_getter)(), progress));
+ }
+
protected:
void (RenderStyle::*m_setter)(T);
};
class PropertyWrapperShadow : public PropertyWrapperGetter<ShadowData*> {
public:
PropertyWrapperShadow(int prop, ShadowData* (RenderStyle::*getter)() const, void (RenderStyle::*setter)(ShadowData*, bool))
- : PropertyWrapperGetter<ShadowData*>(prop, getter)
- , m_setter(setter)
- { }
-
+ : PropertyWrapperGetter<ShadowData*>(prop, getter)
+ , m_setter(setter)
+ {
+ }
+
virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
{
- ShadowData* shadowa = (a->*m_getter)();
- ShadowData* shadowb = (b->*m_getter)();
-
- if (!shadowa && shadowb || shadowa && !shadowb)
+ ShadowData* shadowA = (a->*m_getter)();
+ ShadowData* shadowB = (b->*m_getter)();
+
+ if (!shadowA && shadowB || shadowA && !shadowB)
return false;
- if (shadowa && shadowb && (*shadowa != *shadowb))
+ if (shadowA && shadowB && (*shadowA != *shadowB))
return false;
return true;
}
-
- virtual void blend(RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double prog) const
+
+ virtual void blend(RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
{
- ShadowData* shadowa = (a->*m_getter)();
- ShadowData* shadowb = (b->*m_getter)();
+ ShadowData* shadowA = (a->*m_getter)();
+ ShadowData* shadowB = (b->*m_getter)();
ShadowData defaultShadowData(0, 0, 0, Color::transparent);
-
- if (!shadowa)
- shadowa = &defaultShadowData;
- if (!shadowb)
- shadowb = &defaultShadowData;
-
- (dst->*m_setter)(blendFunc(shadowa, shadowb, prog), false);
+
+ if (!shadowA)
+ shadowA = &defaultShadowData;
+ if (!shadowB)
+ shadowB = &defaultShadowData;
+
+ (dst->*m_setter)(blendFunc(shadowA, shadowB, progress), false);
}
-
+
private:
void (RenderStyle::*m_setter)(ShadowData*, bool);
};
class PropertyWrapperMaybeInvalidColor : public PropertyWrapperBase {
public:
PropertyWrapperMaybeInvalidColor(int prop, const Color& (RenderStyle::*getter)() const, void (RenderStyle::*setter)(const Color&))
- : PropertyWrapperBase(prop)
- , m_getter(getter)
- , m_setter(setter)
- { }
-
+ : PropertyWrapperBase(prop)
+ , m_getter(getter)
+ , m_setter(setter)
+ {
+ }
+
virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
{
Color fromColor = (a->*m_getter)();
fromColor = a->color();
if (!toColor.isValid())
toColor = b->color();
-
+
return fromColor == toColor;
}
-
- virtual void blend(RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double prog) const
+
+ virtual void blend(RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress) const
{
Color fromColor = (a->*m_getter)();
Color toColor = (b->*m_getter)();
fromColor = a->color();
if (!toColor.isValid())
toColor = b->color();
- (dst->*m_setter)(blendFunc(fromColor, toColor, prog));
+ (dst->*m_setter)(blendFunc(fromColor, toColor, progress));
}
-
+
private:
const Color& (RenderStyle::*m_getter)() const;
void (RenderStyle::*m_setter)(const Color&);
// FIXME: This data is never destroyed. Maybe we should ref count it and toss it when the last AnimationController is destroyed?
if (gPropertyWrappers == 0) {
gPropertyWrappers = new Vector<PropertyWrapperBase*>();
-
+
// build the list of property wrappers to do the comparisons and blends
gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyLeft, &RenderStyle::left, &RenderStyle::setLeft));
gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyRight, &RenderStyle::right, &RenderStyle::setRight));
gPropertyWrappers->append(new PropertyWrapper<const IntSize&>(CSSPropertyWebkitBorderBottomRightRadius, &RenderStyle::borderBottomRightRadius, &RenderStyle::setBorderBottomRightRadius));
gPropertyWrappers->append(new PropertyWrapper<EVisibility>(CSSPropertyVisibility, &RenderStyle::visibility, &RenderStyle::setVisibility));
gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyZoom, &RenderStyle::zoom, &RenderStyle::setZoom));
-
+
// FIXME: these might be invalid colors, need to check for that
gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyWebkitColumnRuleColor, &RenderStyle::columnRuleColor, &RenderStyle::setColumnRuleColor));
gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyWebkitTextStrokeColor, &RenderStyle::textStrokeColor, &RenderStyle::setTextStrokeColor));
gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyBorderTopColor, &RenderStyle::borderTopColor, &RenderStyle::setBorderTopColor));
gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyBorderBottomColor, &RenderStyle::borderBottomColor, &RenderStyle::setBorderBottomColor));
gPropertyWrappers->append(new PropertyWrapperMaybeInvalidColor(CSSPropertyOutlineColor, &RenderStyle::outlineColor, &RenderStyle::setOutlineColor));
-
+
// These are for shadows
gPropertyWrappers->append(new PropertyWrapperShadow(CSSPropertyWebkitBoxShadow, &RenderStyle::boxShadow, &RenderStyle::setBoxShadow));
gPropertyWrappers->append(new PropertyWrapperShadow(CSSPropertyTextShadow, &RenderStyle::textShadow, &RenderStyle::setTextShadow));
-
+
// Make sure unused slots have a value
for (unsigned int i = 0; i < (unsigned int) numCSSProperties; ++i)
gPropertyWrapperMap[i] = CSSPropertyInvalid;
-
+
size_t n = gPropertyWrappers->size();
for (unsigned int i = 0; i < n; ++i) {
ASSERT((*gPropertyWrappers)[i]->property() - firstCSSProperty < numCSSProperties);
}
AnimationBase::AnimationBase(const Animation* transition, RenderObject* renderer, CompositeAnimation* compAnim)
-: m_animState(STATE_NEW)
-, m_iteration(0)
-, m_animating(false)
-, m_waitedForResponse(false)
-, m_startTime(0)
-, m_pauseTime(-1)
-, m_object(renderer)
-, m_animationTimerCallback(const_cast<AnimationBase*>(this))
-, m_animationEventDispatcher(const_cast<AnimationBase*>(this))
-, m_animation(const_cast<Animation*>(transition))
-, m_compAnim(compAnim)
-, m_waitingForEndEvent(false)
+ : m_animState(AnimationStateNew)
+ , m_iteration(0)
+ , m_animating(false)
+ , m_waitedForResponse(false)
+ , m_startTime(0)
+ , m_pauseTime(-1)
+ , m_object(renderer)
+ , m_animationTimerCallback(const_cast<AnimationBase*>(this))
+ , m_animationEventDispatcher(const_cast<AnimationBase*>(this))
+ , m_animation(const_cast<Animation*>(transition))
+ , m_compAnim(compAnim)
+ , m_waitingForEndEvent(false)
{
- ensurePropertyMap();
}
AnimationBase::~AnimationBase()
{
- if (m_animState == STATE_START_WAIT_STYLE_AVAILABLE)
+ if (m_animState == AnimationStateStartWaitStyleAvailable)
m_compAnim->setWaitingForStyleAvailable(false);
}
-// static
+
bool AnimationBase::propertiesEqual(int prop, const RenderStyle* a, const RenderStyle* b)
{
ensurePropertyMap();
}
} else {
int propIndex = prop - firstCSSProperty;
-
+
if (propIndex >= 0 && propIndex < numCSSProperties) {
int i = gPropertyWrapperMap[propIndex];
- return (i >= 0) ? (*gPropertyWrappers)[i]->equals(a, b) : true;
+ return i >= 0 ? (*gPropertyWrappers)[i]->equals(a, b) : true;
}
}
return true;
}
-// static
int AnimationBase::getPropertyAtIndex(int i)
{
ensurePropertyMap();
- if (i < 0 || i >= (int) gPropertyWrappers->size())
+ if (i < 0 || i >= static_cast<int>(gPropertyWrappers->size()))
return CSSPropertyInvalid;
-
+
return (*gPropertyWrappers)[i]->property();
}
-//static
int AnimationBase::getNumProperties()
{
ensurePropertyMap();
return gPropertyWrappers->size();
}
-
-// static - return true if we need to start software animation timers
-bool AnimationBase::blendProperties(int prop, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double prog)
+// Returns true if we need to start animation timers
+bool AnimationBase::blendProperties(int prop, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress)
{
+ ASSERT(prop != cAnimateAll);
+ // FIXME: Why can this happen?
if (prop == cAnimateAll) {
- ASSERT(0);
bool needsTimer = false;
-
+
size_t n = gPropertyWrappers->size();
for (unsigned int i = 0; i < n; ++i) {
PropertyWrapperBase* wrapper = (*gPropertyWrappers)[i];
if (!wrapper->equals(a, b)) {
- wrapper->blend(dst, a, b, prog);
+ wrapper->blend(dst, a, b, progress);
needsTimer = true;
}
}
return needsTimer;
}
-
+
int propIndex = prop - firstCSSProperty;
if (propIndex >= 0 && propIndex < numCSSProperties) {
int i = gPropertyWrapperMap[propIndex];
if (i >= 0) {
PropertyWrapperBase* wrapper = (*gPropertyWrappers)[i];
- wrapper->blend(dst, a, b, prog);
+ wrapper->blend(dst, a, b, progress);
return true;
}
}
-
+
return false;
}
return static_cast<Element*>(m_object->node());
return 0;
}
-
+
void AnimationBase::updateStateMachine(AnimStateInput input, double param)
{
- // If we get a RESTART then we force a new animation, regardless of state
- if (input == STATE_INPUT_MAKE_NEW) {
- if (m_animState == STATE_START_WAIT_STYLE_AVAILABLE)
+ // If we get AnimationStateInputRestartAnimation then we force a new animation, regardless of state.
+ if (input == AnimationStateInputMakeNew) {
+ if (m_animState == AnimationStateStartWaitStyleAvailable)
m_compAnim->setWaitingForStyleAvailable(false);
- m_animState = STATE_NEW;
+ m_animState = AnimationStateNew;
m_startTime = 0;
m_pauseTime = -1;
m_waitedForResponse = false;
endAnimation(false);
return;
}
- else if (input == STATE_INPUT_RESTART_ANIMATION) {
+
+ if (input == AnimationStateInputRestartAnimation) {
cancelTimers();
- if (m_animState == STATE_START_WAIT_STYLE_AVAILABLE)
+ if (m_animState == AnimationStateStartWaitStyleAvailable)
m_compAnim->setWaitingForStyleAvailable(false);
- m_animState = STATE_NEW;
+ m_animState = AnimationStateNew;
m_startTime = 0;
m_pauseTime = -1;
endAnimation(false);
-
+
if (!paused())
- updateStateMachine(STATE_INPUT_START_ANIMATION, -1);
+ updateStateMachine(AnimationStateInputStartAnimation, -1);
return;
}
- else if (input == STATE_INPUT_END_ANIMATION) {
+
+ if (input == AnimationStateInputEndAnimation) {
cancelTimers();
- if (m_animState == STATE_START_WAIT_STYLE_AVAILABLE)
+ if (m_animState == AnimationStateStartWaitStyleAvailable)
m_compAnim->setWaitingForStyleAvailable(false);
- m_animState = STATE_DONE;
+ m_animState = AnimationStateDone;
endAnimation(true);
return;
}
- else if (input == STATE_INPUT_PAUSE_OVERRIDE) {
- if (m_animState == STATE_START_WAIT_RESPONSE) {
- // If we are in the WAIT_RESPONSE state, the animation will get canceled before
- // we get a response, so move to the next state
+
+ if (input == AnimationStateInputPauseOverride) {
+ if (m_animState == AnimationStateStartWaitResponse) {
+ // If we are in AnimationStateStartWaitResponse, the animation will get canceled before
+ // we get a response, so move to the next state.
endAnimation(false);
- updateStateMachine(STATE_INPUT_START_TIME_SET, currentTime());
+ updateStateMachine(AnimationStateInputStartTimeSet, currentTime());
}
return;
}
- else if (input == STATE_INPUT_RESUME_OVERRIDE) {
- if (m_animState == STATE_LOOPING || m_animState == STATE_ENDING) {
+
+ if (input == AnimationStateInputResumeOverride) {
+ if (m_animState == AnimationStateLooping || m_animState == AnimationStateEnding) {
// Start the animation
startAnimation(m_startTime);
}
return;
}
-
+
// Execute state machine
switch(m_animState) {
- case STATE_NEW:
- ASSERT(input == STATE_INPUT_START_ANIMATION || input == STATE_INPUT_PLAY_STATE_RUNNING || input == STATE_INPUT_PLAY_STATE_PAUSED);
- if (input == STATE_INPUT_START_ANIMATION || input == STATE_INPUT_PLAY_STATE_RUNNING) {
+ case AnimationStateNew:
+ ASSERT(input == AnimationStateInputStartAnimation || input == AnimationStateInputPlayStateRunnning || input == AnimationStateInputPlayStatePaused);
+ if (input == AnimationStateInputStartAnimation || input == AnimationStateInputPlayStateRunnning) {
// Set the start timer to the initial delay (0 if no delay)
m_waitedForResponse = false;
- m_animState = STATE_START_WAIT_TIMER;
+ m_animState = AnimationStateStartWaitTimer;
m_animationTimerCallback.startTimer(m_animation->delay(), EventNames::webkitAnimationStartEvent, m_animation->delay());
}
break;
- case STATE_START_WAIT_TIMER:
- ASSERT(input == STATE_INPUT_START_TIMER_FIRED || input == STATE_INPUT_PLAY_STATE_PAUSED);
-
- if (input == STATE_INPUT_START_TIMER_FIRED) {
+ case AnimationStateStartWaitTimer:
+ ASSERT(input == AnimationStateInputStartTimerFired || input == AnimationStateInputPlayStatePaused);
+
+ if (input == AnimationStateInputStartTimerFired) {
ASSERT(param >= 0);
// Start timer has fired, tell the animation to start and wait for it to respond with start time
- m_animState = STATE_START_WAIT_STYLE_AVAILABLE;
+ m_animState = AnimationStateStartWaitStyleAvailable;
m_compAnim->setWaitingForStyleAvailable(true);
-
+
// Trigger a render so we can start the animation
setChanged(m_object->element());
m_object->animation()->startUpdateRenderingDispatcher();
- }
- else {
+ } else {
ASSERT(running());
// We're waiting for the start timer to fire and we got a pause. Cancel the timer, pause and wait
m_pauseTime = currentTime();
cancelTimers();
- m_animState = STATE_PAUSED_WAIT_TIMER;
+ m_animState = AnimationStatePausedWaitTimer;
}
break;
- case STATE_START_WAIT_STYLE_AVAILABLE:
- ASSERT(input == STATE_INPUT_STYLE_AVAILABLE || input == STATE_INPUT_PLAY_STATE_PAUSED);
-
+ case AnimationStateStartWaitStyleAvailable:
+ ASSERT(input == AnimationStateInputStyleAvailable || input == AnimationStateInputPlayStatePaused);
+
m_compAnim->setWaitingForStyleAvailable(false);
-
- if (input == STATE_INPUT_STYLE_AVAILABLE) {
+
+ if (input == AnimationStateInputStyleAvailable) {
// Start timer has fired, tell the animation to start and wait for it to respond with start time
- m_animState = STATE_START_WAIT_RESPONSE;
-
+ m_animState = AnimationStateStartWaitResponse;
+
overrideAnimations();
-
+
// Send start event, if needed
- onAnimationStart(0.0f); // The elapsedTime is always 0 here
-
+ onAnimationStart(0); // The elapsedTime is always 0 here
+
// Start the animation
if (overridden() || !startAnimation(0)) {
// We're not going to get a startTime callback, so fire the start time here
- m_animState = STATE_START_WAIT_RESPONSE;
- updateStateMachine(STATE_INPUT_START_TIME_SET, currentTime());
- }
- else
+ m_animState = AnimationStateStartWaitResponse;
+ updateStateMachine(AnimationStateInputStartTimeSet, currentTime());
+ } else
m_waitedForResponse = true;
- }
- else {
+ } else {
ASSERT(running());
// We're waiting for the a notification that the style has been setup. If we're asked to wait
// at this point, the style must have been processed, so we can deal with this like we would
// for WAIT_RESPONSE, except that we don't need to do an endAnimation().
m_pauseTime = 0;
- m_animState = STATE_START_WAIT_RESPONSE;
+ m_animState = AnimationStateStartWaitResponse;
}
break;
- case STATE_START_WAIT_RESPONSE:
- ASSERT(input == STATE_INPUT_START_TIME_SET || input == STATE_INPUT_PLAY_STATE_PAUSED);
-
- if (input == STATE_INPUT_START_TIME_SET) {
+ case AnimationStateStartWaitResponse:
+ ASSERT(input == AnimationStateInputStartTimeSet || input == AnimationStateInputPlayStatePaused);
+
+ if (input == AnimationStateInputStartTimeSet) {
ASSERT(param >= 0);
// We have a start time, set it, unless the startTime is already set
if (m_startTime <= 0)
m_startTime = param;
-
+
// Decide when the end or loop event needs to fire
primeEventTimers();
-
+
// Trigger a render so we can start the animation
setChanged(m_object->element());
m_object->animation()->startUpdateRenderingDispatcher();
- }
- else {
+ } else {
// We are pausing while waiting for a start response. Cancel the animation and wait. When
// we unpause, we will act as though the start timer just fired
m_pauseTime = 0;
endAnimation(false);
- m_animState = STATE_PAUSED_WAIT_RESPONSE;
+ m_animState = AnimationStatePausedWaitResponse;
}
break;
- case STATE_LOOPING:
- ASSERT(input == STATE_INPUT_LOOP_TIMER_FIRED || input == STATE_INPUT_PLAY_STATE_PAUSED);
-
- if (input == STATE_INPUT_LOOP_TIMER_FIRED) {
+ case AnimationStateLooping:
+ ASSERT(input == AnimationStateInputLoopTimerFired || input == AnimationStateInputPlayStatePaused);
+
+ if (input == AnimationStateInputLoopTimerFired) {
ASSERT(param >= 0);
// Loop timer fired, loop again or end.
onAnimationIteration(param);
primeEventTimers();
- }
- else {
+ } else {
// We are pausing while running. Cancel the animation and wait
m_pauseTime = currentTime();
cancelTimers();
endAnimation(false);
- m_animState = STATE_PAUSED_RUN;
+ m_animState = AnimationStatePausedRun;
}
break;
- case STATE_ENDING:
- ASSERT(input == STATE_INPUT_END_TIMER_FIRED || input == STATE_INPUT_PLAY_STATE_PAUSED);
-
- if (input == STATE_INPUT_END_TIMER_FIRED) {
+ case AnimationStateEnding:
+ ASSERT(input == AnimationStateInputEndTimerFired || input == AnimationStateInputPlayStatePaused);
+
+ if (input == AnimationStateInputEndTimerFired) {
ASSERT(param >= 0);
// End timer fired, finish up
onAnimationEnd(param);
-
+
resumeOverriddenAnimations();
-
+
// Fire off another style change so we can set the final value
setChanged(m_object->element());
- m_animState = STATE_DONE;
+ m_animState = AnimationStateDone;
m_object->animation()->startUpdateRenderingDispatcher();
// |this| may be deleted here when we've been called from timerFired()
- }
- else {
+ } else {
// We are pausing while running. Cancel the animation and wait
m_pauseTime = currentTime();
cancelTimers();
endAnimation(false);
- m_animState = STATE_PAUSED_RUN;
+ m_animState = AnimationStatePausedRun;
}
// |this| may be deleted here
break;
- case STATE_PAUSED_WAIT_TIMER:
- ASSERT(input == STATE_INPUT_PLAY_STATE_RUNNING);
+ case AnimationStatePausedWaitTimer:
+ ASSERT(input == AnimationStateInputPlayStateRunnning);
ASSERT(!running());
// Update the times
m_startTime += currentTime() - m_pauseTime;
m_pauseTime = -1;
-
+
// we were waiting for the start timer to fire, go back and wait again
- m_animState = STATE_NEW;
- updateStateMachine(STATE_INPUT_START_ANIMATION, 0);
+ m_animState = AnimationStateNew;
+ updateStateMachine(AnimationStateInputStartAnimation, 0);
break;
- case STATE_PAUSED_WAIT_RESPONSE:
- case STATE_PAUSED_RUN:
- // We treat these two cases the same. The only difference is that, when we are in the WAIT_RESPONSE
- // state, we don't yet have a valid startTime, so we send 0 to startAnimation. When the START_TIME
- // event comes in qnd we were in the RUN state, we will notice that we have already set the
- // startTime and will ignore it.
- ASSERT(input == STATE_INPUT_PLAY_STATE_RUNNING);
+ case AnimationStatePausedWaitResponse:
+ case AnimationStatePausedRun:
+ // We treat these two cases the same. The only difference is that, when we are in
+ // AnimationStatePausedWaitResponse, we don't yet have a valid startTime, so we send 0 to startAnimation.
+ // When the AnimationStateInputStartTimeSet comes in and we were in AnimationStatePausedRun, we will notice
+ // that we have already set the startTime and will ignore it.
+ ASSERT(input == AnimationStateInputPlayStateRunnning);
ASSERT(!running());
// Update the times
- if (m_animState == STATE_PAUSED_RUN)
+ if (m_animState == AnimationStatePausedRun)
m_startTime += currentTime() - m_pauseTime;
else
m_startTime = 0;
m_pauseTime = -1;
-
+
// We were waiting for a begin time response from the animation, go back and wait again
- m_animState = STATE_START_WAIT_RESPONSE;
-
+ m_animState = AnimationStateStartWaitResponse;
+
// Start the animation
if (overridden() || !startAnimation(m_startTime)) {
// We're not going to get a startTime callback, so fire the start time here
- updateStateMachine(STATE_INPUT_START_TIME_SET, currentTime());
- }
- else
+ updateStateMachine(AnimationStateInputStartTimeSet, currentTime());
+ } else
m_waitedForResponse = true;
break;
- case STATE_DONE:
+ case AnimationStateDone:
// We're done. Stay in this state until we are deleted
break;
}
- // |this| may be deleted here if we came out of STATE_ENDING when we've been called from timerFired()
+ // |this| may be deleted here if we came out of AnimationStateEnding when we've been called from timerFired()
}
void AnimationBase::animationTimerCallbackFired(const AtomicString& eventType, double elapsedTime)
{
ASSERT(m_object->document() && !m_object->document()->inPageCache());
-
+
// FIXME: use an enum
if (eventType == EventNames::webkitAnimationStartEvent)
- updateStateMachine(STATE_INPUT_START_TIMER_FIRED, elapsedTime);
+ updateStateMachine(AnimationStateInputStartTimerFired, elapsedTime);
else if (eventType == EventNames::webkitAnimationIterationEvent)
- updateStateMachine(STATE_INPUT_LOOP_TIMER_FIRED, elapsedTime);
+ updateStateMachine(AnimationStateInputLoopTimerFired, elapsedTime);
else if (eventType == EventNames::webkitAnimationEndEvent) {
- updateStateMachine(STATE_INPUT_END_TIMER_FIRED, elapsedTime);
+ updateStateMachine(AnimationStateInputEndTimerFired, elapsedTime);
// |this| may be deleted here
}
}
bool reset, const AtomicString& eventType, double elapsedTime)
{
m_waitingForEndEvent = false;
-
+
// Keep an atomic string on the stack to keep it alive until we exit this method
// (since dispatching the event may cause |this| to be deleted, therefore removing
// the last ref to the atomic string).
AtomicString animEventType(eventType);
// Make sure the element sticks around too
RefPtr<Element> elementRetainer(element);
-
+
ASSERT(!element || (element->document() && !element->document()->inPageCache()));
if (!element)
return;
element->dispatchWebKitAnimationEvent(eventType, name, elapsedTime);
// Restore the original (unanimated) style
- if (animEventType == EventNames::webkitAnimationEndEvent)
- if (element->renderer())
- setChanged(element->renderer()->element());
+ if (animEventType == EventNames::webkitAnimationEndEvent && element->renderer())
+ setChanged(element->renderer()->element());
}
void AnimationBase::updatePlayState(bool run)
{
if (paused() == run || isNew())
- updateStateMachine(run ? STATE_INPUT_PLAY_STATE_RUNNING : STATE_INPUT_PLAY_STATE_PAUSED, -1);
+ updateStateMachine(run ? AnimationStateInputPlayStateRunnning : AnimationStateInputPlayStatePaused, -1);
}
double AnimationBase::progress(double scale, double offset) const
{
if (preActive())
return 0;
-
+
double elapsedTime = running() ? (currentTime() - m_startTime) : (m_pauseTime - m_startTime);
if (running() && elapsedTime < 0)
return 0;
-
+
double dur = m_animation->duration();
if (m_animation->iterationCount() > 0)
dur *= m_animation->iterationCount();
-
+
if (postActive() || !m_animation->duration() || (m_animation->iterationCount() > 0 && elapsedTime >= dur))
return 1.0;
-
+
// Compute the fractional time, taking into account direction.
// There is no need to worry about iterations, we assume that we would have
- // short circuited above if we were done
+ // short circuited above if we were done.
double fractionalTime = elapsedTime / m_animation->duration();
- int integralTime = (int) fractionalTime;
+ int integralTime = static_cast<int>(fractionalTime);
fractionalTime -= integralTime;
-
+
if (m_animation->direction() && (integralTime & 1))
fractionalTime = 1 - fractionalTime;
-
- if (scale != 1 || offset != 0)
+
+ if (scale != 1 || offset)
fractionalTime = (fractionalTime - offset) * scale;
-
+
if (m_animation->timingFunction().type() == LinearTimingFunction)
return fractionalTime;
-
+
// Cubic bezier.
double result = solveCubicBezierFunction(m_animation->timingFunction().x1(),
m_animation->timingFunction().y1(),
double ct = currentTime();
const double elapsedDuration = ct - m_startTime;
ASSERT(elapsedDuration >= 0);
-
+
double totalDuration = -1;
if (m_animation->iterationCount() > 0)
totalDuration = m_animation->duration() * m_animation->iterationCount();
durationLeft = m_animation->duration() - fmod(elapsedDuration, m_animation->duration());
nextIterationTime = elapsedDuration + durationLeft;
}
-
+
// At this point, we may have 0 durationLeft, if we've gotten the event late and we are already
// past totalDuration. In this case we still fire an end timer before processing the end.
// This defers the call to sendAnimationEvents to avoid re-entrant calls that destroy
if (totalDuration < 0 || nextIterationTime < totalDuration) {
// We are not at the end yet, send a loop event
ASSERT(nextIterationTime > 0);
- m_animState = STATE_LOOPING;
+ m_animState = AnimationStateLooping;
m_animationTimerCallback.startTimer(durationLeft, EventNames::webkitAnimationIterationEvent, nextIterationTime);
- }
- else {
+ } else {
// We are at the end, send an end event
- m_animState = STATE_ENDING;
+ m_animState = AnimationStateEnding;
m_animationTimerCallback.startTimer(durationLeft, EventNames::webkitAnimationEndEvent, nextIterationTime);
}
}
-}
+} // namespace WebCore
#ifndef AnimationBase_h
#define AnimationBase_h
-#include "Timer.h"
-#include "wtf/HashMap.h"
#include "AtomicString.h"
+#include "Timer.h"
+#include <wtf/HashMap.h>
namespace WebCore {
-class AnimationController;
+class Animation;
class AnimationBase;
+class AnimationController;
+class CompositeAnimation;
+class Element;
class ImplicitAnimation;
class KeyframeAnimation;
-class CompositeAnimation;
+class Node;
class RenderObject;
class RenderStyle;
-class AtomicStringImpl;
-class Animation;
-class Element;
-class Node;
class AnimationTimerBase {
public:
AnimationTimerBase(AnimationBase* anim)
- : m_timer(this, &AnimationTimerBase::timerFired)
- , m_anim(anim)
+ : m_timer(this, &AnimationTimerBase::timerFired)
+ , m_anim(anim)
{
m_timer.startOneShot(0);
}
- virtual ~AnimationTimerBase()
- {
- }
-
- void startTimer(double timeout=0)
+
+ virtual ~AnimationTimerBase() { }
+
+ void startTimer(double timeout = 0)
{
m_timer.startOneShot(timeout);
}
-
+
void cancelTimer()
{
m_timer.stop();
}
-
+
virtual void timerFired(Timer<AnimationTimerBase>*) = 0;
-
+
private:
Timer<AnimationTimerBase> m_timer;
-
+
protected:
AnimationBase* m_anim;
};
class AnimationEventDispatcher : public AnimationTimerBase {
public:
AnimationEventDispatcher(AnimationBase* anim);
- virtual ~AnimationEventDispatcher()
- {
- }
-
+ virtual ~AnimationEventDispatcher() { }
+
void startTimer(Element* element, const AtomicString& name, int property, bool reset,
const AtomicString& eventType, double elapsedTime)
{
m_elapsedTime = elapsedTime;
AnimationTimerBase::startTimer();
}
-
+
virtual void timerFired(Timer<AnimationTimerBase>*);
-
+
private:
RefPtr<Element> m_element;
AtomicString m_name;
class AnimationTimerCallback : public AnimationTimerBase {
public:
AnimationTimerCallback(AnimationBase* anim)
- : AnimationTimerBase(anim)
- , m_elapsedTime(0)
- { }
+ : AnimationTimerBase(anim)
+ , m_elapsedTime(0)
+ {
+ }
+
virtual ~AnimationTimerCallback() { }
-
+
virtual void timerFired(Timer<AnimationTimerBase>*);
-
+
void startTimer(double timeout, const AtomicString& eventType, double elapsedTime)
{
m_eventType = eventType;
m_elapsedTime = elapsedTime;
AnimationTimerBase::startTimer(timeout);
}
-
+
private:
AtomicString m_eventType;
double m_elapsedTime;
class AnimationBase : public Noncopyable {
friend class CompositeAnimation;
-
+
public:
AnimationBase(const Animation* transition, RenderObject* renderer, CompositeAnimation* compAnim);
virtual ~AnimationBase();
-
+
RenderObject* renderer() const { return m_object; }
double startTime() const { return m_startTime; }
double duration() const;
-
+
void cancelTimers()
{
m_animationTimerCallback.cancelTimer();
m_animationEventDispatcher.cancelTimer();
}
-
+
// Animations and Transitions go through the states below. When entering the STARTED state
// the animation is started. This may or may not require deferred response from the animator.
// If so, we stay in this state until that response is received (and it returns the start time).
- // Otherwise, we use the current time as the start time and go immediately to the LOOPING or
- // ENDING state.
+ // Otherwise, we use the current time as the start time and go immediately to AnimationStateLooping
+ // or AnimationStateEnding.
enum AnimState {
- STATE_NEW, // animation just created, animation not running yet
- STATE_START_WAIT_TIMER, // start timer running, waiting for fire
- STATE_START_WAIT_STYLE_AVAILABLE, // waiting for style setup so we can start animations
- STATE_START_WAIT_RESPONSE, // animation started, waiting for response
- STATE_LOOPING, // response received, animation running, loop timer running, waiting for fire
- STATE_ENDING, // response received, animation running, end timer running, waiting for fire
- STATE_PAUSED_WAIT_TIMER, // animation in pause mode when animation started
- STATE_PAUSED_WAIT_RESPONSE, // animation paused when in STARTING state
- STATE_PAUSED_RUN, // animation paused when in LOOPING or ENDING state
- STATE_DONE // end timer fired, animation finished and removed
+ AnimationStateNew, // animation just created, animation not running yet
+ AnimationStateStartWaitTimer, // start timer running, waiting for fire
+ AnimationStateStartWaitStyleAvailable, // waiting for style setup so we can start animations
+ AnimationStateStartWaitResponse, // animation started, waiting for response
+ AnimationStateLooping, // response received, animation running, loop timer running, waiting for fire
+ AnimationStateEnding, // received, animation running, end timer running, waiting for fire
+ AnimationStatePausedWaitTimer, // in pause mode when animation started
+ AnimationStatePausedWaitResponse, // animation paused when in STARTING state
+ AnimationStatePausedRun, // animation paused when in LOOPING or ENDING state
+ AnimationStateDone // end timer fired, animation finished and removed
};
-
+
enum AnimStateInput {
- STATE_INPUT_MAKE_NEW, // reset back to new from any state
- STATE_INPUT_START_ANIMATION, // animation requests a start
- STATE_INPUT_RESTART_ANIMATION, // force a restart from any state
- STATE_INPUT_START_TIMER_FIRED, // start timer fired
- STATE_INPUT_STYLE_AVAILABLE, // style is setup, ready to start animating
- STATE_INPUT_START_TIME_SET, // m_startTime was set
- STATE_INPUT_LOOP_TIMER_FIRED, // loop timer fired
- STATE_INPUT_END_TIMER_FIRED, // end timer fired
- STATE_INPUT_PAUSE_OVERRIDE, // pause an animation due to override
- STATE_INPUT_RESUME_OVERRIDE, // resume an overridden animation
- STATE_INPUT_PLAY_STATE_RUNNING, // play state paused -> running
- STATE_INPUT_PLAY_STATE_PAUSED, // play state running -> paused
- STATE_INPUT_END_ANIMATION // force an end from any state
+ AnimationStateInputMakeNew, // reset back to new from any state
+ AnimationStateInputStartAnimation, // animation requests a start
+ AnimationStateInputRestartAnimation, // force a restart from any state
+ AnimationStateInputStartTimerFired, // start timer fired
+ AnimationStateInputStyleAvailable, // style is setup, ready to start animating
+ AnimationStateInputStartTimeSet, // m_startTime was set
+ AnimationStateInputLoopTimerFired, // loop timer fired
+ AnimationStateInputEndTimerFired, // end timer fired
+ AnimationStateInputPauseOverride, // pause an animation due to override
+ AnimationStateInputResumeOverride, // resume an overridden animation
+ AnimationStateInputPlayStateRunnning, // play state paused -> running
+ AnimationStateInputPlayStatePaused, // play state running -> paused
+ AnimationStateInputEndAnimation // force an end from any state
};
-
- // Called when animation is in NEW state to start animation
- void updateStateMachine(AnimStateInput input, double param);
-
+
+ // Called when animation is in AnimationStateNew to start animation
+ void updateStateMachine(AnimStateInput, double param);
+
// Animation has actually started, at passed time
void onAnimationStartResponse(double startTime);
-
+
// Called to change to or from paused state
void updatePlayState(bool running);
bool playStatePlaying() const;
-
- bool waitingToStart() const { return m_animState == STATE_NEW || m_animState == STATE_START_WAIT_TIMER; }
+
+ bool waitingToStart() const { return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer; }
bool preActive() const
- { return m_animState == STATE_NEW ||
- m_animState == STATE_START_WAIT_TIMER ||
- m_animState == STATE_START_WAIT_STYLE_AVAILABLE ||
- m_animState == STATE_START_WAIT_RESPONSE;
+ {
+ return m_animState == AnimationStateNew || m_animState == AnimationStateStartWaitTimer || m_animState == AnimationStateStartWaitStyleAvailable || m_animState == AnimationStateStartWaitResponse;
}
- bool postActive() const { return m_animState == STATE_DONE; }
+
+ bool postActive() const { return m_animState == AnimationStateDone; }
bool active() const { return !postActive() && !preActive(); }
bool running() const { return !isNew() && !postActive(); }
bool paused() const { return m_pauseTime >= 0; }
- bool isNew() const { return m_animState == STATE_NEW; }
- bool waitingForStartTime() const { return m_animState == STATE_START_WAIT_RESPONSE; }
- bool waitingForStyleAvailable() const { return m_animState == STATE_START_WAIT_STYLE_AVAILABLE; }
+ bool isNew() const { return m_animState == AnimationStateNew; }
+ bool waitingForStartTime() const { return m_animState == AnimationStateStartWaitResponse; }
+ bool waitingForStyleAvailable() const { return m_animState == AnimationStateStartWaitStyleAvailable; }
bool waitingForEndEvent() const { return m_waitingForEndEvent; }
-
+
// "animating" means that something is running that requires a timer to keep firing
// (e.g. a software animation)
void setAnimating(bool inAnimating = true) { m_animating = inAnimating; }
bool animating() const { return m_animating; }
-
+
double progress(double scale, double offset) const;
-
+
virtual void animate(CompositeAnimation*, RenderObject*, const RenderStyle* currentStyle,
const RenderStyle* targetStyle, RenderStyle*& animatedStyle) { }
- virtual void reset(RenderObject* renderer, const RenderStyle* from = 0, const RenderStyle* to = 0) { }
-
+ virtual void reset(RenderObject*, const RenderStyle* from = 0, const RenderStyle* to = 0) { }
+
virtual bool shouldFireEvents() const { return false; }
-
+
void animationTimerCallbackFired(const AtomicString& eventType, double elapsedTime);
- void animationEventDispatcherFired(Element* element, const AtomicString& name, int property, bool reset,
+ void animationEventDispatcherFired(Element*, const AtomicString& name, int property, bool reset,
const AtomicString& eventType, double elapsedTime);
-
- bool animationsMatch(const Animation* anim) const;
-
+
+ bool animationsMatch(const Animation*) const;
+
void setAnimation(const Animation* anim) { m_animation = const_cast<Animation*>(anim); }
-
+
// Return true if this animation is overridden. This will only be the case for
// ImplicitAnimations and is used to determine whether or not we should force
// set the start time. If an animation is overridden, it will probably not get
- // back the START_TIME event.
+ // back the AnimationStateInputStartTimeSet input.
virtual bool overridden() const { return false; }
-
+
// Does this animation/transition involve the given property?
virtual bool affectsProperty(int property) const { return false; }
bool isAnimatingProperty(int property, bool isRunningNow) const
return !postActive() && affectsProperty(property);
}
-
+
protected:
Element* elementForEventDispatch();
-
+
virtual void overrideAnimations() { }
virtual void resumeOverriddenAnimations() { }
-
+
CompositeAnimation* compositeAnimation() { return m_compAnim; }
-
+
// These are called when the corresponding timer fires so subclasses can do any extra work
virtual void onAnimationStart(double elapsedTime) { }
virtual void onAnimationIteration(double elapsedTime) { }
virtual void onAnimationEnd(double elapsedTime) { }
virtual bool startAnimation(double beginTime) { return false; }
virtual void endAnimation(bool reset) { }
-
+
void primeEventTimers();
-
+
static bool propertiesEqual(int prop, const RenderStyle* a, const RenderStyle* b);
- static int getPropertyAtIndex(int i);
+ static int getPropertyAtIndex(int);
static int getNumProperties();
-
+
// Return true if we need to start software animation timers
- static bool blendProperties(int prop, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double prog);
-
- static void setChanged(Node* node);
+ static bool blendProperties(int prop, RenderStyle* dst, const RenderStyle* a, const RenderStyle* b, double progress);
+ static void setChanged(Node*);
+
protected:
AnimState m_animState;
int m_iteration;
-
+
bool m_animating; // transition/animation requires continual timer firing
bool m_waitedForResponse;
double m_startTime;
double m_pauseTime;
RenderObject* m_object;
-
+
AnimationTimerCallback m_animationTimerCallback;
AnimationEventDispatcher m_animationEventDispatcher;
RefPtr<Animation> m_animation;
CompositeAnimation* m_compAnim;
bool m_waitingForEndEvent;
-
-private:
};
-}
+} // namespace WebCore
-#endif
+#endif // AnimationBase_h