| Index: services/view_manager/animation_runner.cc
|
| diff --git a/services/view_manager/animation_runner.cc b/services/view_manager/animation_runner.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..df0fefdc2e71a4d4e206bce8adcc9ce3e1e1329d
|
| --- /dev/null
|
| +++ b/services/view_manager/animation_runner.cc
|
| @@ -0,0 +1,112 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "services/view_manager/animation_runner.h"
|
| +
|
| +#include <set>
|
| +
|
| +#include "services/view_manager/animation_runner_observer.h"
|
| +#include "services/view_manager/scheduled_animation_group.h"
|
| +#include "services/view_manager/server_view.h"
|
| +
|
| +namespace mojo {
|
| +namespace service {
|
| +namespace {
|
| +
|
| +struct AnimationDoneState {
|
| + ServerView* view;
|
| + uint32_t animation_id;
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +AnimationRunner::AnimationRunner(base::TimeTicks now)
|
| + : next_id_(1), last_tick_time_(now) {
|
| +}
|
| +
|
| +AnimationRunner::~AnimationRunner() {
|
| +}
|
| +
|
| +void AnimationRunner::AddObserver(AnimationRunnerObserver* observer) {
|
| + observers_.AddObserver(observer);
|
| +}
|
| +
|
| +void AnimationRunner::RemoveObserver(AnimationRunnerObserver* observer) {
|
| + observers_.RemoveObserver(observer);
|
| +}
|
| +
|
| +uint32_t AnimationRunner::Schedule(ServerView* view,
|
| + const AnimationGroup& transport_group) {
|
| + scoped_ptr<ScheduledAnimationGroup> group(ScheduledAnimationGroup::Create(
|
| + view, last_tick_time_, next_id_++, transport_group));
|
| + if (!group.get())
|
| + return 0;
|
| +
|
| + if (animation_map_.contains(view)) {
|
| + animation_map_.get(view)->SetValuesToTargetValuesForPropertiesNotIn(*group);
|
| + const uint32_t animation_id = animation_map_.get(view)->id();
|
| + animation_map_.erase(view);
|
| + FOR_EACH_OBSERVER(AnimationRunnerObserver, observers_,
|
| + OnAnimationInterrupted(view, animation_id));
|
| + }
|
| +
|
| + group->ObtainStartValues();
|
| +
|
| + const uint32_t id = group->id();
|
| + animation_map_.set(view, group.Pass());
|
| +
|
| + FOR_EACH_OBSERVER(AnimationRunnerObserver, observers_,
|
| + OnAnimationScheduled(view, id));
|
| + return id;
|
| +}
|
| +
|
| +ServerView* AnimationRunner::GetViewForAnimation(uint32_t id) {
|
| + for (ViewAnimationMap::iterator i = animation_map_.begin();
|
| + i != animation_map_.end(); ++i) {
|
| + if (i->second->id() == id)
|
| + return i->first;
|
| + }
|
| + return nullptr;
|
| +}
|
| +
|
| +void AnimationRunner::CancelAnimationForView(ServerView* view) {
|
| + if (!animation_map_.contains(view))
|
| + return;
|
| +
|
| + const uint32_t id = animation_map_.get(view)->id();
|
| + animation_map_.erase(view);
|
| + FOR_EACH_OBSERVER(AnimationRunnerObserver, observers_,
|
| + OnAnimationCanceled(view, id));
|
| +}
|
| +
|
| +void AnimationRunner::Tick(base::TimeTicks time) {
|
| + DCHECK(time >= last_tick_time_);
|
| + last_tick_time_ = time;
|
| + if (animation_map_.empty())
|
| + return;
|
| +
|
| + std::vector<AnimationDoneState> animations_done;
|
| + for (ViewAnimationMap::iterator i = animation_map_.begin();
|
| + i != animation_map_.end(); ) {
|
| + // Any animations that complete are notified at the end of the loop. This
|
| + // way if the obsevert attempts to schedule another animation or mutate us
|
| + // in some other way we aren't in a bad state.
|
| + if (i->second->Tick(time)) {
|
| + AnimationDoneState done_state;
|
| + done_state.view = i->first;
|
| + done_state.animation_id = i->second->id();
|
| + animations_done.push_back(done_state);
|
| + animation_map_.erase(i++);
|
| + } else {
|
| + ++i;
|
| + }
|
| + }
|
| + for (const AnimationDoneState& done : animations_done) {
|
| + FOR_EACH_OBSERVER(AnimationRunnerObserver, observers_,
|
| + OnAnimationDone(done.view, done.animation_id));
|
| + }
|
| +}
|
| +
|
| +} // namespace service
|
| +} // namespace mojo
|
|
|