12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#ifndef CC_ANIMATION_ANIMATION_H_
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#define CC_ANIMATION_ANIMATION_H_
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "cc/base/cc_export.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cc {
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AnimationCurve;
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// An Animation, contains all the state required to play an AnimationCurve.
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Specifically, the affected property, the run state (paused, finished, etc.),
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// loop count, last pause time, and the total time spent paused.
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class CC_EXPORT Animation {
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Animations begin in one of the 'waiting' states. Animations waiting for the
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // next tick will start the next time the controller animates. Animations
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // waiting for target availibility will run as soon as their target property
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // is free (and all the animations animating with it are also able to run).
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Animations waiting for their start time to come have be scheduled to run at
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // a particular point in time. When this time arrives, the controller will
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // move the animations into the Starting state, and then into the Running
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // state. Running animations may toggle between Running and Paused, and may be
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // stopped by moving into either the Aborted or Finished states. A Finished
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // animation was allowed to run to completion, but an Aborted animation was
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // not.
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  enum RunState {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WaitingForNextTick = 0,
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WaitingForTargetAvailability,
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WaitingForStartTime,
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    WaitingForDeletion,
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Starting,
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Running,
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Paused,
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Finished,
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Aborted,
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // This sentinel must be last.
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    RunStateEnumSize
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  enum TargetProperty {
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Transform = 0,
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Opacity,
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // This sentinel must be last.
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    TargetPropertyEnumSize
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static scoped_ptr<Animation> Create(scoped_ptr<AnimationCurve> curve,
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      int animation_id,
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      int group_id,
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      TargetProperty target_property);
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~Animation();
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int id() const { return id_; }
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int group() const { return group_; }
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TargetProperty target_property() const { return target_property_; }
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunState run_state() const { return run_state_; }
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void SetRunState(RunState run_state, double monotonic_time);
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This is the number of times that the animation will play. If this
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // value is zero the animation will not play. If it is negative, then
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // the animation will loop indefinitely.
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int iterations() const { return iterations_; }
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_iterations(int n) { iterations_ = n; }
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double start_time() const { return start_time_; }
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_start_time(double monotonic_time) { start_time_ = monotonic_time; }
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool has_set_start_time() const { return !!start_time_; }
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double time_offset() const { return time_offset_; }
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_time_offset(double monotonic_time) { time_offset_ = monotonic_time; }
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Suspend(double monotonic_time);
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void Resume(double monotonic_time);
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If alternates_direction is true, on odd numbered iterations we reverse the
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // curve.
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool alternates_direction() const { return alternates_direction_; }
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_alternates_direction(bool alternates) {
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    alternates_direction_ = alternates;
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool IsFinishedAt(double monotonic_time) const;
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_finished() const {
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return run_state_ == Finished ||
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        run_state_ == Aborted ||
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        run_state_ == WaitingForDeletion;
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  AnimationCurve* curve() { return curve_.get(); }
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const AnimationCurve* curve() const { return curve_.get(); }
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If this is true, even if the animation is running, it will not be tickable
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // until it is given a start time. This is true for animations running on the
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // main thread.
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool needs_synchronized_start_time() const {
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return needs_synchronized_start_time_;
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_needs_synchronized_start_time(bool needs_synchronized_start_time) {
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    needs_synchronized_start_time_ = needs_synchronized_start_time;
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // This is true for animations running on the main thread when the Finished
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // event sent by the corresponding impl animation has been received.
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool received_finished_event() const {
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return received_finished_event_;
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void set_received_finished_event(bool received_finished_event) {
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    received_finished_event_ = received_finished_event;
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Takes the given absolute time, and using the start time and the number
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // of iterations, returns the relative time in the current iteration.
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double TrimTimeToCurrentIteration(double monotonic_time) const;
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  enum InstanceType {
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ControllingInstance = 0,
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NonControllingInstance
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Animation> Clone(InstanceType instance_type) const;
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<Animation> CloneAndInitialize(InstanceType instance_type,
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           RunState initial_run_state,
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                           double start_time) const;
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_controlling_instance() const { return is_controlling_instance_; }
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void PushPropertiesTo(Animation* other) const;
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_is_impl_only(bool is_impl_only) { is_impl_only_ = is_impl_only; }
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_impl_only() const { return is_impl_only_; }
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Animation(scoped_ptr<AnimationCurve> curve,
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            int animation_id,
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            int group_id,
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            TargetProperty target_property);
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<AnimationCurve> curve_;
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // IDs are not necessarily unique.
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int id_;
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Animations that must be run together are called 'grouped' and have the same
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // group id. Grouped animations are guaranteed to start at the same time and
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // no other animations may animate any of the group's target properties until
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // all animations in the group have finished animating. Note: an active
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // animation's group id and target property uniquely identify that animation.
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int group_;
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TargetProperty target_property_;
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RunState run_state_;
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  int iterations_;
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double start_time_;
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool alternates_direction_;
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The time offset effectively pushes the start of the animation back in time.
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This is used for resuming paused animations -- an animation is added with a
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // non-zero time offset, causing the animation to skip ahead to the desired
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // point in time.
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double time_offset_;
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool needs_synchronized_start_time_;
170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool received_finished_event_;
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // When an animation is suspended, it behaves as if it is paused and it also
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // ignores all run state changes until it is resumed. This is used for testing
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // purposes.
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool suspended_;
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // These are used in TrimTimeToCurrentIteration to account for time
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // spent while paused. This is not included in AnimationState since it
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // there is absolutely no need for clients of this controller to know
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // about these values.
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double pause_time_;
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  double total_paused_time_;
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Animations lead dual lives. An active animation will be conceptually owned
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // by two controllers, one on the impl thread and one on the main. In reality,
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // there will be two separate Animation instances for the same animation. They
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // will have the same group id and the same target property (these two values
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // uniquely identify an animation). The instance on the impl thread is the
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // instance that ultimately controls the values of the animating layer and so
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // we will refer to it as the 'controlling instance'.
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_controlling_instance_;
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_impl_only_;
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(Animation);
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cc
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif  // CC_ANIMATION_ANIMATION_H_
201