AnimatorManager.cpp revision 8d8af3c1b768d590754d657a7d1242dcb462454b
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16#include "AnimatorManager.h" 17 18#include <algorithm> 19 20#include "RenderNode.h" 21 22namespace android { 23namespace uirenderer { 24 25using namespace std; 26 27static void unref(BaseRenderNodeAnimator* animator) { 28 animator->detach(); 29 animator->decStrong(0); 30} 31 32AnimatorManager::AnimatorManager(RenderNode& parent) 33 : mParent(parent) { 34} 35 36AnimatorManager::~AnimatorManager() { 37 for_each(mNewAnimators.begin(), mNewAnimators.end(), unref); 38 for_each(mAnimators.begin(), mAnimators.end(), unref); 39} 40 41void AnimatorManager::addAnimator(const sp<BaseRenderNodeAnimator>& animator) { 42 animator->incStrong(0); 43 animator->attach(&mParent); 44 mNewAnimators.push_back(animator.get()); 45} 46 47template<typename T> 48static void move_all(T& source, T& dest) { 49 dest.reserve(source.size() + dest.size()); 50 for (typename T::iterator it = source.begin(); it != source.end(); it++) { 51 dest.push_back(*it); 52 } 53 source.clear(); 54} 55 56void AnimatorManager::pushStaging(TreeInfo& info) { 57 if (mNewAnimators.size()) { 58 // Since this is a straight move, we don't need to inc/dec the ref count 59 move_all(mNewAnimators, mAnimators); 60 } 61 for (vector<BaseRenderNodeAnimator*>::iterator it = mAnimators.begin(); it != mAnimators.end(); it++) { 62 (*it)->pushStaging(info); 63 } 64} 65 66class AnimateFunctor { 67public: 68 AnimateFunctor(RenderNode& target, TreeInfo& info) 69 : mTarget(target), mInfo(info) {} 70 71 bool operator() (BaseRenderNodeAnimator* animator) { 72 bool remove = animator->animate(mInfo); 73 if (remove) { 74 animator->decStrong(0); 75 } 76 return remove; 77 } 78private: 79 RenderNode& mTarget; 80 TreeInfo& mInfo; 81}; 82 83void AnimatorManager::animate(TreeInfo& info) { 84 if (!mAnimators.size()) return; 85 86 // TODO: Can we target this better? For now treat it like any other staging 87 // property push and just damage self before and after animators are run 88 89 mParent.damageSelf(info); 90 info.damageAccumulator->popTransform(); 91 92 AnimateFunctor functor(mParent, info); 93 std::vector< BaseRenderNodeAnimator* >::iterator newEnd; 94 newEnd = std::remove_if(mAnimators.begin(), mAnimators.end(), functor); 95 mAnimators.erase(newEnd, mAnimators.end()); 96 97 mParent.mProperties.updateMatrix(); 98 info.damageAccumulator->pushTransform(&mParent); 99 mParent.damageSelf(info); 100} 101 102} /* namespace uirenderer */ 103} /* namespace android */ 104