bool Animation::update(TimingUpdateReason reason) { if (!m_timeline) return false; PlayStateUpdateScope updateScope(*this, reason, DoNotSetCompositorPending); clearOutdated(); bool idle = playStateInternal() == Idle; if (m_content) { double inheritedTime = idle || isNull(m_timeline->currentTimeInternal()) ? nullValue() : currentTimeInternal(); if (!isNull(inheritedTime)) { double timeForClipping = m_held && (!limited(inheritedTime) || isNull(m_startTime)) // Use hold time when there is no start time. ? inheritedTime // Use calculated current time when the animation is limited. : calculateCurrentTime(); if (clipped(timeForClipping)) inheritedTime = nullValue(); } // Special case for end-exclusivity when playing backwards. if (inheritedTime == 0 && m_playbackRate < 0) inheritedTime = -1; m_content->updateInheritedTime(inheritedTime, reason); } if ((idle || limited()) && !m_finished) { if (reason == TimingUpdateForAnimationFrame && (idle || hasStartTime())) { if (idle) { // TODO(dstockwell): Fire the cancel event. } else { const AtomicString& eventType = EventTypeNames::finish; if (executionContext() && hasEventListeners(eventType)) { double eventCurrentTime = currentTimeInternal() * 1000; m_pendingFinishedEvent = AnimationPlayerEvent::create(eventType, eventCurrentTime, timeline()->currentTime()); m_pendingFinishedEvent->setTarget(this); m_pendingFinishedEvent->setCurrentTarget(this); m_timeline->document()->enqueueAnimationFrameEvent(m_pendingFinishedEvent); } } m_finished = true; } } ASSERT(!m_outdated); return !m_finished || std::isfinite(timeToEffectChange()); }
void AnimationPlayer::setCurrentTimeInternal(double newCurrentTime, TimingUpdateReason reason) { ASSERT(std::isfinite(newCurrentTime)); bool oldHeld = m_held; bool outdated = false; bool isLimited = limited(newCurrentTime); m_held = m_paused || !m_playbackRate || isLimited || std::isnan(m_startTime); if (m_held) { if (!oldHeld || m_holdTime != newCurrentTime) outdated = true; m_holdTime = newCurrentTime; if (m_paused || !m_playbackRate) { m_startTime = nullValue(); } else if (isLimited && std::isnan(m_startTime) && reason == TimingUpdateForAnimationFrame) { m_startTime = calculateStartTime(newCurrentTime); } } else { m_holdTime = nullValue(); m_startTime = calculateStartTime(newCurrentTime); m_finished = false; outdated = true; } if (outdated) { setOutdated(); } }
double Animation::timeToEffectChange() { ASSERT(!m_outdated); if (!hasStartTime()) return std::numeric_limits<double>::infinity(); double currentTime = calculateCurrentTime(); if (m_held) { if (limited(currentTime)) { if (m_playbackRate > 0 && m_endClip + effectEnd() > currentTime) return m_endClip + effectEnd() - currentTime; if (m_playbackRate < 0 && m_startClip <= currentTime) return m_startClip - currentTime; } return std::numeric_limits<double>::infinity(); } if (!m_content) return -currentTimeInternal() / m_playbackRate; double result = m_playbackRate > 0 ? m_content->timeToForwardsEffectChange() / m_playbackRate : m_content->timeToReverseEffectChange() / -m_playbackRate; return !hasActiveAnimationsOnCompositor() && m_content->phase() == AnimationEffect::PhaseActive ? 0 : clipTimeToEffectChange(result); }
// Update timing to reflect updated animation clock due to tick void AnimationPlayer::updateCurrentTimingState(TimingUpdateReason reason) { if (m_held) { setCurrentTimeInternal(m_holdTime, reason); return; } if (!limited(calculateCurrentTime())) return; m_held = true; m_holdTime = m_playbackRate < 0 ? 0 : sourceEnd(); }
void AnimationPlayer::updateCurrentTimingState() { if (m_held) { updateTimingState(m_holdTime); return; } if (!limited(currentTimeWithLag())) return; m_held = true; m_holdTime = m_playbackRate < 0 ? 0 : sourceEnd(); m_storedTimeLag = nullValue(); }
Animation::AnimationPlayState Animation::calculatePlayState() { if (m_playState == Idle) return Idle; if (m_currentTimePending || (isNull(m_startTime) && !m_paused && m_playbackRate != 0)) return Pending; if (m_paused) return Paused; if (limited()) return Finished; return Running; }
// Update timing to reflect updated animation clock due to tick void Animation::updateCurrentTimingState(TimingUpdateReason reason) { if (m_held) { double newCurrentTime = m_holdTime; if (playStateInternal() == Finished && !isNull(m_startTime) && m_timeline) { // Add hystersis due to floating point error accumulation if (!limited(calculateCurrentTime() + 0.001 * m_playbackRate)) { // The current time became unlimited, eg. due to a backwards // seek of the timeline. newCurrentTime = calculateCurrentTime(); } else if (!limited(m_holdTime)) { // The hold time became unlimited, eg. due to the effect // becoming longer. newCurrentTime = clampTo<double>(calculateCurrentTime(), 0, effectEnd()); } } setCurrentTimeInternal(newCurrentTime, reason); } else if (limited(calculateCurrentTime())) { m_held = true; m_holdTime = m_playbackRate < 0 ? 0 : effectEnd(); } }
Stream::ptr Connection::getStream(const GeneralHeaders &general, const EntityHeaders &entity, const std::string &method, Status status, boost::function<void()> notifyOnEof, boost::function<void()> notifyOnException, bool forRead) { MORDOR_ASSERT(hasMessageBody(general, entity, method, status)); Stream::ptr stream; if (forRead) { stream.reset(new SingleplexStream(m_stream, SingleplexStream::READ, false)); } else { stream.reset(new SingleplexStream(m_stream, SingleplexStream::WRITE, false)); } Stream::ptr baseStream(stream); for (ParameterizedList::const_reverse_iterator it(general.transferEncoding.rbegin()); it != general.transferEncoding.rend(); ++it) { if (stricmp(it->value.c_str(), "chunked") == 0) { stream.reset(new ChunkedStream(stream)); } else if (stricmp(it->value.c_str(), "deflate") == 0) { stream.reset(new ZlibStream(stream)); } else if (stricmp(it->value.c_str(), "gzip") == 0 || stricmp(it->value.c_str(), "x-gzip") == 0) { stream.reset(new GzipStream(stream)); } else if (stricmp(it->value.c_str(), "compress") == 0 || stricmp(it->value.c_str(), "x-compress") == 0) { MORDOR_ASSERT(false); } else if (stricmp(it->value.c_str(), "identity") == 0) { MORDOR_ASSERT(false); } else { MORDOR_ASSERT(false); } } if (stream != baseStream) { } else if (entity.contentLength != ~0ull) { LimitedStream::ptr limited(new LimitedStream(stream, entity.contentLength)); limited->strict(true); stream = limited; } else if (entity.contentType.type == "multipart") { // Getting stream to pass to multipart; self-delimiting } else { // Delimited by closing the connection } NotifyStream::ptr notify(new NotifyStream(stream)); stream = notify; notify->notifyOnClose = notifyOnEof; notify->notifyOnEof = notifyOnEof; notify->notifyOnException = notifyOnException; return stream; }
void AnimationPlayer::updateTimingState(double newCurrentTime) { ASSERT(!isNull(newCurrentTime)); bool oldHeld = m_held; m_held = m_paused || !m_playbackRate || limited(newCurrentTime); if (m_held) { if (!oldHeld || m_holdTime != newCurrentTime) setOutdated(); m_holdTime = newCurrentTime; m_storedTimeLag = nullValue(); } else { m_holdTime = nullValue(); m_storedTimeLag = currentTimeWithoutLag() - newCurrentTime; setOutdated(); } }
void Animation::setPlaybackRateInternal(double playbackRate) { ASSERT(std::isfinite(playbackRate)); ASSERT(playbackRate != m_playbackRate); if (!limited() && !paused() && hasStartTime()) m_currentTimePending = true; double storedCurrentTime = currentTimeInternal(); if ((m_playbackRate < 0 && playbackRate >= 0) || (m_playbackRate > 0 && playbackRate <= 0)) m_finished = false; m_playbackRate = playbackRate; m_startTime = std::numeric_limits<double>::quiet_NaN(); setCurrentTimeInternal(storedCurrentTime, TimingUpdateOnDemand); }
void Animation::finish(ExceptionState& exceptionState) { PlayStateUpdateScope updateScope(*this, TimingUpdateOnDemand); if (!m_playbackRate || playStateInternal() == Idle) { return; } if (m_playbackRate > 0 && effectEnd() == std::numeric_limits<double>::infinity()) { exceptionState.throwDOMException(InvalidStateError, "Animation has effect whose end time is infinity."); return; } double newCurrentTime = m_playbackRate < 0 ? 0 : effectEnd(); setCurrentTimeInternal(newCurrentTime, TimingUpdateOnDemand); if (!paused()) { m_startTime = calculateStartTime(newCurrentTime); } m_currentTimePending = false; ASSERT(playStateInternal() != Idle); ASSERT(limited()); }