Index: cc/animation/animation_timeline.cc |
diff --git a/cc/animation/animation_timeline.cc b/cc/animation/animation_timeline.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..ccc9a7925ca7abc043c1c44a9fdcac130f5c0441 |
--- /dev/null |
+++ b/cc/animation/animation_timeline.cc |
@@ -0,0 +1,120 @@ |
+// Copyright 2015 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 "cc/animation/animation_timeline.h" |
+ |
+#include <algorithm> |
+ |
+#include "cc/animation/animation_player.h" |
+ |
+namespace cc { |
+ |
+scoped_refptr<AnimationTimeline> AnimationTimeline::Create(int id) { |
+ return make_scoped_refptr(new AnimationTimeline(id)); |
+} |
+ |
+AnimationTimeline::AnimationTimeline(int id) |
+ : id_(id), animation_host_(), is_impl_only_(false) { |
+} |
+ |
+AnimationTimeline::~AnimationTimeline() { |
+ for (auto& player : players_) |
+ player->SetAnimationTimeline(nullptr); |
+} |
+ |
+scoped_refptr<AnimationTimeline> AnimationTimeline::CreateImplInstance() const { |
+ scoped_refptr<AnimationTimeline> to_return = AnimationTimeline::Create(id()); |
+ return to_return; |
+} |
+ |
+void AnimationTimeline::SetAnimationHost(AnimationHost* animation_host) { |
+ animation_host_ = animation_host; |
+ for (auto& player : players_) |
+ player->SetAnimationHost(animation_host); |
+} |
+ |
+void AnimationTimeline::AttachPlayer(AnimationPlayer* player) { |
+ DCHECK(animation_host_); |
+ player->SetAnimationHost(animation_host_); |
+ player->SetAnimationTimeline(this); |
+ players_.push_back(player); |
+} |
+ |
+void AnimationTimeline::DetachPlayer(AnimationPlayer* player) { |
+ for (AnimationPlayerList::iterator iter = players_.begin(); |
+ iter != players_.end(); ++iter) { |
+ if (iter->get() != player) |
+ continue; |
+ |
+ ErasePlayers(iter, iter + 1); |
+ break; |
+ } |
+ |
+ player->SetAnimationHost(nullptr); |
+} |
+ |
+AnimationPlayer* AnimationTimeline::GetPlayerById(int player_id) const { |
+ for (auto& player : players_) |
+ if (player->id() == player_id) |
+ return player.get(); |
+ return nullptr; |
+} |
+ |
+void AnimationTimeline::ClearPlayers() { |
+ ErasePlayers(players_.begin(), players_.end()); |
+} |
+ |
+void AnimationTimeline::PushPropertiesTo(AnimationTimeline* timeline_impl) { |
+ PushAttachedPlayersToImplThread(timeline_impl); |
+ RemoveDetachedPlayersFromImplThread(timeline_impl); |
+ PushPropertiesToImplThread(timeline_impl); |
+} |
+ |
+void AnimationTimeline::PushAttachedPlayersToImplThread( |
+ AnimationTimeline* timeline_impl) const { |
+ for (auto& player : players_) { |
+ AnimationPlayer* player_impl = timeline_impl->GetPlayerById(player->id()); |
+ if (player_impl) |
+ continue; |
+ |
+ scoped_refptr<AnimationPlayer> to_add = player->CreateImplInstance(); |
+ timeline_impl->AttachPlayer(to_add.get()); |
+ } |
+} |
+ |
+void AnimationTimeline::RemoveDetachedPlayersFromImplThread( |
+ AnimationTimeline* timeline_impl) const { |
+ AnimationPlayerList& players_impl = timeline_impl->players_; |
+ |
+ auto to_erase = |
+ std::partition(players_impl.begin(), players_impl.end(), |
+ [this](AnimationPlayerList::value_type player_impl) { |
+ return GetPlayerById(player_impl->id()); |
+ }); |
+ |
+ timeline_impl->ErasePlayers(to_erase, players_impl.end()); |
+} |
+ |
+void AnimationTimeline::ErasePlayers(AnimationPlayerList::iterator begin, |
+ AnimationPlayerList::iterator end) { |
+ for (auto i = begin; i != end; ++i) { |
+ auto& player = *i; |
+ if (player->layer_animation_controller()) |
+ player->DetachLayer(); |
+ player->SetAnimationTimeline(nullptr); |
+ } |
+ |
+ players_.erase(begin, end); |
+} |
+ |
+void AnimationTimeline::PushPropertiesToImplThread( |
+ AnimationTimeline* timeline_impl) { |
+ for (auto& player : players_) { |
+ AnimationPlayer* player_impl = timeline_impl->GetPlayerById(player->id()); |
+ if (player_impl) |
+ player->PushPropertiesTo(player_impl); |
+ } |
+} |
+ |
+} // namespace cc |