1// Copyright 2012 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#ifndef CC_ANIMATION_ANIMATION_H_
6#define CC_ANIMATION_ANIMATION_H_
7
8#include "base/basictypes.h"
9#include "base/memory/scoped_ptr.h"
10#include "cc/base/cc_export.h"
11
12namespace cc {
13
14class AnimationCurve;
15
16// An Animation contains all the state required to play an AnimationCurve.
17// Specifically, the affected property, the run state (paused, finished, etc.),
18// loop count, last pause time, and the total time spent paused.
19class CC_EXPORT Animation {
20 public:
21  // Animations begin in the 'WaitingForTargetAvailability' state. An Animation
22  // waiting for target availibility will run as soon as its target property
23  // is free (and all the animations animating with it are also able to run).
24  // When this time arrives, the controller will move the animation into the
25  // Starting state, and then into the Running state. Running animations may
26  // toggle between Running and Paused, and may be stopped by moving into either
27  // the Aborted or Finished states. A Finished animation was allowed to run to
28  // completion, but an Aborted animation was not.
29  enum RunState {
30    WaitingForTargetAvailability = 0,
31    WaitingForDeletion,
32    Starting,
33    Running,
34    Paused,
35    Finished,
36    Aborted,
37    // This sentinel must be last.
38    RunStateEnumSize
39  };
40
41  enum TargetProperty {
42    Transform = 0,
43    Opacity,
44    Filter,
45    BackgroundColor,
46    ScrollOffset,
47    // This sentinel must be last.
48    TargetPropertyEnumSize
49  };
50
51  static scoped_ptr<Animation> Create(scoped_ptr<AnimationCurve> curve,
52                                      int animation_id,
53                                      int group_id,
54                                      TargetProperty target_property);
55
56  virtual ~Animation();
57
58  int id() const { return id_; }
59  int group() const { return group_; }
60  TargetProperty target_property() const { return target_property_; }
61
62  RunState run_state() const { return run_state_; }
63  void SetRunState(RunState run_state, double monotonic_time);
64
65  // This is the number of times that the animation will play. If this
66  // value is zero the animation will not play. If it is negative, then
67  // the animation will loop indefinitely.
68  int iterations() const { return iterations_; }
69  void set_iterations(int n) { iterations_ = n; }
70
71  double start_time() const { return start_time_; }
72  void set_start_time(double monotonic_time) { start_time_ = monotonic_time; }
73  bool has_set_start_time() const { return !!start_time_; }
74
75  double time_offset() const { return time_offset_; }
76  void set_time_offset(double monotonic_time) { time_offset_ = monotonic_time; }
77
78  void Suspend(double monotonic_time);
79  void Resume(double monotonic_time);
80
81  // If alternates_direction is true, on odd numbered iterations we reverse the
82  // curve.
83  bool alternates_direction() const { return alternates_direction_; }
84  void set_alternates_direction(bool alternates) {
85    alternates_direction_ = alternates;
86  }
87
88  bool IsFinishedAt(double monotonic_time) const;
89  bool is_finished() const {
90    return run_state_ == Finished ||
91        run_state_ == Aborted ||
92        run_state_ == WaitingForDeletion;
93  }
94
95  AnimationCurve* curve() { return curve_.get(); }
96  const AnimationCurve* curve() const { return curve_.get(); }
97
98  // If this is true, even if the animation is running, it will not be tickable
99  // until it is given a start time. This is true for animations running on the
100  // main thread.
101  bool needs_synchronized_start_time() const {
102    return needs_synchronized_start_time_;
103  }
104  void set_needs_synchronized_start_time(bool needs_synchronized_start_time) {
105    needs_synchronized_start_time_ = needs_synchronized_start_time;
106  }
107
108  // This is true for animations running on the main thread when the Finished
109  // event sent by the corresponding impl animation has been received.
110  bool received_finished_event() const {
111    return received_finished_event_;
112  }
113  void set_received_finished_event(bool received_finished_event) {
114    received_finished_event_ = received_finished_event;
115  }
116
117  // Takes the given absolute time, and using the start time and the number
118  // of iterations, returns the relative time in the current iteration.
119  double TrimTimeToCurrentIteration(double monotonic_time) const;
120
121  scoped_ptr<Animation> Clone() const;
122  scoped_ptr<Animation> CloneAndInitialize(RunState initial_run_state,
123                                           double start_time) const;
124  bool is_controlling_instance() const { return is_controlling_instance_; }
125
126  void PushPropertiesTo(Animation* other) const;
127
128  void set_is_impl_only(bool is_impl_only) { is_impl_only_ = is_impl_only; }
129  bool is_impl_only() const { return is_impl_only_; }
130
131 private:
132  Animation(scoped_ptr<AnimationCurve> curve,
133            int animation_id,
134            int group_id,
135            TargetProperty target_property);
136
137  scoped_ptr<AnimationCurve> curve_;
138
139  // IDs are not necessarily unique.
140  int id_;
141
142  // Animations that must be run together are called 'grouped' and have the same
143  // group id. Grouped animations are guaranteed to start at the same time and
144  // no other animations may animate any of the group's target properties until
145  // all animations in the group have finished animating. Note: an active
146  // animation's group id and target property uniquely identify that animation.
147  int group_;
148
149  TargetProperty target_property_;
150  RunState run_state_;
151  int iterations_;
152  double start_time_;
153  bool alternates_direction_;
154
155  // The time offset effectively pushes the start of the animation back in time.
156  // This is used for resuming paused animations -- an animation is added with a
157  // non-zero time offset, causing the animation to skip ahead to the desired
158  // point in time.
159  double time_offset_;
160
161  bool needs_synchronized_start_time_;
162  bool received_finished_event_;
163
164  // When an animation is suspended, it behaves as if it is paused and it also
165  // ignores all run state changes until it is resumed. This is used for testing
166  // purposes.
167  bool suspended_;
168
169  // These are used in TrimTimeToCurrentIteration to account for time
170  // spent while paused. This is not included in AnimationState since it
171  // there is absolutely no need for clients of this controller to know
172  // about these values.
173  double pause_time_;
174  double total_paused_time_;
175
176  // Animations lead dual lives. An active animation will be conceptually owned
177  // by two controllers, one on the impl thread and one on the main. In reality,
178  // there will be two separate Animation instances for the same animation. They
179  // will have the same group id and the same target property (these two values
180  // uniquely identify an animation). The instance on the impl thread is the
181  // instance that ultimately controls the values of the animating layer and so
182  // we will refer to it as the 'controlling instance'.
183  bool is_controlling_instance_;
184
185  bool is_impl_only_;
186
187  DISALLOW_COPY_AND_ASSIGN(Animation);
188};
189
190}  // namespace cc
191
192#endif  // CC_ANIMATION_ANIMATION_H_
193