OLD | NEW |
(Empty) | |
| 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. |
| 4 |
| 5 #include "services/view_manager/animation_runner.h" |
| 6 |
| 7 #include <set> |
| 8 |
| 9 #include "services/view_manager/animation_runner_observer.h" |
| 10 #include "services/view_manager/scheduled_animation_group.h" |
| 11 #include "services/view_manager/server_view.h" |
| 12 |
| 13 namespace mojo { |
| 14 namespace service { |
| 15 namespace { |
| 16 |
| 17 struct AnimationDoneState { |
| 18 ServerView* view; |
| 19 uint32_t animation_id; |
| 20 }; |
| 21 |
| 22 } // namespace |
| 23 |
| 24 AnimationRunner::AnimationRunner(base::TimeTicks now) |
| 25 : next_id_(1), last_tick_time_(now) { |
| 26 } |
| 27 |
| 28 AnimationRunner::~AnimationRunner() { |
| 29 } |
| 30 |
| 31 void AnimationRunner::AddObserver(AnimationRunnerObserver* observer) { |
| 32 observers_.AddObserver(observer); |
| 33 } |
| 34 |
| 35 void AnimationRunner::RemoveObserver(AnimationRunnerObserver* observer) { |
| 36 observers_.RemoveObserver(observer); |
| 37 } |
| 38 |
| 39 uint32_t AnimationRunner::Schedule(ServerView* view, |
| 40 const AnimationGroup& transport_group) { |
| 41 scoped_ptr<ScheduledAnimationGroup> group(ScheduledAnimationGroup::Create( |
| 42 view, last_tick_time_, next_id_++, transport_group)); |
| 43 if (!group.get()) |
| 44 return 0; |
| 45 |
| 46 if (animation_map_.contains(view)) { |
| 47 animation_map_.get(view)->SetValuesToTargetValuesForPropertiesNotIn(*group); |
| 48 const uint32_t animation_id = animation_map_.get(view)->id(); |
| 49 animation_map_.erase(view); |
| 50 FOR_EACH_OBSERVER(AnimationRunnerObserver, observers_, |
| 51 OnAnimationInterrupted(view, animation_id)); |
| 52 } |
| 53 |
| 54 group->ObtainStartValues(); |
| 55 |
| 56 const uint32_t id = group->id(); |
| 57 animation_map_.set(view, group.Pass()); |
| 58 |
| 59 FOR_EACH_OBSERVER(AnimationRunnerObserver, observers_, |
| 60 OnAnimationScheduled(view, id)); |
| 61 return id; |
| 62 } |
| 63 |
| 64 ServerView* AnimationRunner::GetViewForAnimation(uint32_t id) { |
| 65 for (ViewAnimationMap::iterator i = animation_map_.begin(); |
| 66 i != animation_map_.end(); ++i) { |
| 67 if (i->second->id() == id) |
| 68 return i->first; |
| 69 } |
| 70 return nullptr; |
| 71 } |
| 72 |
| 73 void AnimationRunner::CancelAnimationForView(ServerView* view) { |
| 74 if (!animation_map_.contains(view)) |
| 75 return; |
| 76 |
| 77 const uint32_t id = animation_map_.get(view)->id(); |
| 78 animation_map_.erase(view); |
| 79 FOR_EACH_OBSERVER(AnimationRunnerObserver, observers_, |
| 80 OnAnimationCanceled(view, id)); |
| 81 } |
| 82 |
| 83 void AnimationRunner::Tick(base::TimeTicks time) { |
| 84 DCHECK(time >= last_tick_time_); |
| 85 last_tick_time_ = time; |
| 86 if (animation_map_.empty()) |
| 87 return; |
| 88 |
| 89 std::vector<AnimationDoneState> animations_done; |
| 90 for (ViewAnimationMap::iterator i = animation_map_.begin(); |
| 91 i != animation_map_.end(); ) { |
| 92 // Any animations that complete are notified at the end of the loop. This |
| 93 // way if the obsevert attempts to schedule another animation or mutate us |
| 94 // in some other way we aren't in a bad state. |
| 95 if (i->second->Tick(time)) { |
| 96 AnimationDoneState done_state; |
| 97 done_state.view = i->first; |
| 98 done_state.animation_id = i->second->id(); |
| 99 animations_done.push_back(done_state); |
| 100 animation_map_.erase(i++); |
| 101 } else { |
| 102 ++i; |
| 103 } |
| 104 } |
| 105 for (const AnimationDoneState& done : animations_done) { |
| 106 FOR_EACH_OBSERVER(AnimationRunnerObserver, observers_, |
| 107 OnAnimationDone(done.view, done.animation_id)); |
| 108 } |
| 109 } |
| 110 |
| 111 } // namespace service |
| 112 } // namespace mojo |
OLD | NEW |