blob: 3c7790f5b644155e16102c10476c4c13f23113e6 [file] [log] [blame]
// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "cobalt/web_animations/animation.h"
#include "cobalt/web_animations/animation_set.h"
#include "cobalt/web_animations/animation_timeline.h"
namespace cobalt {
namespace web_animations {
AnimationTimeline::AnimationTimeline(const scoped_refptr<base::Clock>& clock)
: clock_(clock), animations_(new AnimationSet()) {}
AnimationTimeline::~AnimationTimeline() { DCHECK(animations_->IsEmpty()); }
void AnimationTimeline::Register(Animation* animation) {
animations_->AddAnimation(animation);
}
void AnimationTimeline::Deregister(Animation* animation) {
animations_->RemoveAnimation(animation);
}
unsigned int AnimationTimeline::num_animations() const {
return static_cast<unsigned int>(animations_->GetSize());
}
// Returns the current time for the document. This is based off of the last
// sampled time.
// https://www.w3.org/TR/web-animations-1/#the-animationtimeline-interface
base::optional<double> AnimationTimeline::current_time() const {
if (sampled_clock_time_) {
return sampled_clock_time_->InMillisecondsF();
} else {
return base::nullopt;
}
}
void AnimationTimeline::Sample() {
if (clock_) {
sampled_clock_time_ = clock_->Now();
event_queue_.UpdateTime(*sampled_clock_time_);
} else {
sampled_clock_time_ = base::nullopt;
}
UpdateNextEventTimer();
}
scoped_ptr<TimedTaskQueue::Task> AnimationTimeline::QueueTask(
base::TimeDelta fire_time, const base::Closure& closure) {
scoped_ptr<TimedTaskQueue::Task> task =
event_queue_.QueueTask(fire_time, closure);
// Update our next-event timer since we may have modified the time of the
// next-to-fire event by inserting this new event.
UpdateNextEventTimer();
return task.Pass();
}
void AnimationTimeline::UpdateNextEventTimer() {
if (event_queue_.empty() || !sampled_clock_time_ || !clock_) {
next_event_timer_.Stop();
} else {
base::TimeDelta delay = event_queue_.next_fire_time() - clock_->Now();
next_event_timer_.Start(
FROM_HERE, delay < base::TimeDelta() ? base::TimeDelta() : delay,
base::Bind(&AnimationTimeline::Sample, base::Unretained(this)));
}
}
} // namespace web_animations
} // namespace cobalt