Add a stub __cxa_demangle to disable LLVM's demangler.
[chromium-blink-merge.git] / components / view_manager / animation_runner.cc
blob6569ff1ada768ebecd788310c7ac9d389770a6db
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/view_manager/animation_runner.h"
7 #include "base/memory/scoped_vector.h"
8 #include "components/view_manager/animation_runner_observer.h"
9 #include "components/view_manager/scheduled_animation_group.h"
10 #include "components/view_manager/server_view.h"
12 namespace view_manager {
13 namespace {
15 bool ConvertViewAndAnimationPairToScheduledAnimationGroup(
16 const std::vector<AnimationRunner::ViewAndAnimationPair>& views,
17 AnimationRunner::AnimationId id,
18 base::TimeTicks now,
19 ScopedVector<ScheduledAnimationGroup>* groups) {
20 for (const auto& view_animation_pair : views) {
21 DCHECK(view_animation_pair.second);
22 scoped_ptr<ScheduledAnimationGroup> group(ScheduledAnimationGroup::Create(
23 view_animation_pair.first, now, id, *(view_animation_pair.second)));
24 if (!group.get())
25 return false;
26 groups->push_back(group.release());
28 return true;
31 } // namespace
33 AnimationRunner::AnimationRunner(base::TimeTicks now)
34 : next_id_(1), last_tick_time_(now) {
37 AnimationRunner::~AnimationRunner() {
40 void AnimationRunner::AddObserver(AnimationRunnerObserver* observer) {
41 observers_.AddObserver(observer);
44 void AnimationRunner::RemoveObserver(AnimationRunnerObserver* observer) {
45 observers_.RemoveObserver(observer);
48 AnimationRunner::AnimationId AnimationRunner::Schedule(
49 const std::vector<ViewAndAnimationPair>& views,
50 base::TimeTicks now) {
51 DCHECK_GE(now, last_tick_time_);
53 const AnimationId animation_id = next_id_++;
54 ScopedVector<ScheduledAnimationGroup> groups;
55 if (!ConvertViewAndAnimationPairToScheduledAnimationGroup(views, animation_id,
56 now, &groups)) {
57 return 0;
60 // Cancel any animations for the views.
61 for (auto* group : groups) {
62 ScheduledAnimationGroup* current_group =
63 view_to_animation_map_.get(group->view());
64 if (current_group)
65 current_group->SetValuesToTargetValuesForPropertiesNotIn(*group);
67 CancelAnimationForViewImpl(group->view(), CANCEL_SOURCE_SCHEDULE);
70 for (auto* group : groups) {
71 group->ObtainStartValues();
72 view_to_animation_map_.set(group->view(), make_scoped_ptr(group));
73 DCHECK(!id_to_views_map_[animation_id].count(group->view()));
74 id_to_views_map_[animation_id].insert(group->view());
76 // |view_to_animation_map_| owns the groups.
77 groups.weak_clear();
79 FOR_EACH_OBSERVER(AnimationRunnerObserver, observers_,
80 OnAnimationScheduled(animation_id));
81 return animation_id;
84 void AnimationRunner::CancelAnimation(AnimationId id) {
85 if (id_to_views_map_.count(id) == 0)
86 return;
88 std::set<ServerView*> views(id_to_views_map_[id]);
89 for (ServerView* view : views)
90 CancelAnimationForView(view);
93 void AnimationRunner::CancelAnimationForView(ServerView* view) {
94 CancelAnimationForViewImpl(view, CANCEL_SOURCE_CANCEL);
97 void AnimationRunner::Tick(base::TimeTicks time) {
98 DCHECK(time >= last_tick_time_);
99 last_tick_time_ = time;
100 if (view_to_animation_map_.empty())
101 return;
103 // The animation ids of any views whose animation completes are added here. We
104 // notify after processing all views so that if an observer mutates us in some
105 // way we're aren't left in a weird state.
106 std::set<AnimationId> animations_completed;
107 for (ViewToAnimationMap::iterator i = view_to_animation_map_.begin();
108 i != view_to_animation_map_.end();) {
109 if (i->second->Tick(time)) {
110 const AnimationId animation_id = i->second->id();
111 ServerView* view = i->first;
112 ++i;
113 if (RemoveViewFromMaps(view))
114 animations_completed.insert(animation_id);
115 } else {
116 ++i;
119 for (const AnimationId& id : animations_completed) {
120 FOR_EACH_OBSERVER(AnimationRunnerObserver, observers_, OnAnimationDone(id));
124 void AnimationRunner::CancelAnimationForViewImpl(ServerView* view,
125 CancelSource source) {
126 if (!view_to_animation_map_.contains(view))
127 return;
129 const AnimationId animation_id = view_to_animation_map_.get(view)->id();
130 if (RemoveViewFromMaps(view)) {
131 // This was the last view in the group.
132 if (source == CANCEL_SOURCE_CANCEL) {
133 FOR_EACH_OBSERVER(AnimationRunnerObserver, observers_,
134 OnAnimationCanceled(animation_id));
135 } else {
136 FOR_EACH_OBSERVER(AnimationRunnerObserver, observers_,
137 OnAnimationInterrupted(animation_id));
142 bool AnimationRunner::RemoveViewFromMaps(ServerView* view) {
143 DCHECK(view_to_animation_map_.contains(view));
145 const AnimationId animation_id = view_to_animation_map_.get(view)->id();
146 view_to_animation_map_.erase(view);
148 DCHECK(id_to_views_map_.count(animation_id));
149 id_to_views_map_[animation_id].erase(view);
150 if (!id_to_views_map_[animation_id].empty())
151 return false;
153 id_to_views_map_.erase(animation_id);
154 return true;
157 } // namespace view_manager