// 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 #include "cc/animation/animation_player.h" namespace cc { scoped_refptr 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::CreateImplInstance() const { scoped_refptr timeline = AnimationTimeline::Create(id()); return timeline; } void AnimationTimeline::SetAnimationHost(AnimationHost* animation_host) { animation_host_ = animation_host; for (auto& player : players_) player->SetAnimationHost(animation_host); } void AnimationTimeline::AttachPlayer(scoped_refptr player) { player->SetAnimationHost(animation_host_); player->SetAnimationTimeline(this); players_.push_back(player); } void AnimationTimeline::DetachPlayer(scoped_refptr player) { for (AnimationPlayerList::iterator iter = players_.begin(); iter != players_.end(); ++iter) { if (iter->get() != player) continue; ErasePlayers(iter, iter + 1); break; } } 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 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->element_animations()) player->DetachLayer(); player->SetAnimationTimeline(nullptr); player->SetAnimationHost(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