1// Copyright 2014 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 InterpolableValue_h
6#define InterpolableValue_h
7
8#include "core/animation/animatable/AnimatableValue.h"
9#include "wtf/OwnPtr.h"
10#include "wtf/PassOwnPtr.h"
11#include "wtf/Vector.h"
12
13namespace blink {
14
15class InterpolableValue : public NoBaseWillBeGarbageCollected<InterpolableValue> {
16    DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(InterpolableValue);
17public:
18    virtual bool isNumber() const { return false; }
19    virtual bool isBool() const { return false; }
20    virtual bool isList() const { return false; }
21    virtual bool isAnimatableValue() const { return false; }
22
23    virtual PassOwnPtrWillBeRawPtr<InterpolableValue> clone() const = 0;
24
25    virtual void trace(Visitor*) { }
26
27private:
28    virtual PassOwnPtrWillBeRawPtr<InterpolableValue> interpolate(const InterpolableValue &to, const double progress) const = 0;
29
30    friend class Interpolation;
31
32    // Keep interpolate private, but allow calls within the hierarchy without
33    // knowledge of type.
34    friend class DeferredLegacyStyleInterpolation;
35    friend class InterpolableNumber;
36    friend class InterpolableBool;
37    friend class InterpolableList;
38};
39
40class InterpolableNumber : public InterpolableValue {
41public:
42    static PassOwnPtrWillBeRawPtr<InterpolableNumber> create(double value)
43    {
44        return adoptPtrWillBeNoop(new InterpolableNumber(value));
45    }
46
47    virtual bool isNumber() const OVERRIDE FINAL { return true; }
48    double value() const { return m_value; }
49    virtual PassOwnPtrWillBeRawPtr<InterpolableValue> clone() const OVERRIDE FINAL { return create(m_value); }
50
51    virtual void trace(Visitor* visitor) OVERRIDE { InterpolableValue::trace(visitor); }
52
53private:
54    virtual PassOwnPtrWillBeRawPtr<InterpolableValue> interpolate(const InterpolableValue &to, const double progress) const OVERRIDE FINAL;
55    double m_value;
56
57    explicit InterpolableNumber(double value)
58        : m_value(value)
59    {
60    }
61
62};
63
64class InterpolableBool : public InterpolableValue {
65public:
66    static PassOwnPtrWillBeRawPtr<InterpolableBool> create(bool value)
67    {
68        return adoptPtrWillBeNoop(new InterpolableBool(value));
69    }
70
71    virtual bool isBool() const OVERRIDE FINAL { return true; }
72    bool value() const { return m_value; }
73    virtual PassOwnPtrWillBeRawPtr<InterpolableValue> clone() const OVERRIDE FINAL { return create(m_value); }
74
75    virtual void trace(Visitor* visitor) OVERRIDE { InterpolableValue::trace(visitor); }
76
77private:
78    virtual PassOwnPtrWillBeRawPtr<InterpolableValue> interpolate(const InterpolableValue &to, const double progress) const OVERRIDE FINAL;
79    bool m_value;
80
81    explicit InterpolableBool(bool value)
82        : m_value(value)
83    {
84    }
85
86};
87
88class InterpolableList : public InterpolableValue {
89public:
90    static PassOwnPtrWillBeRawPtr<InterpolableList> create(const InterpolableList &other)
91    {
92        return adoptPtrWillBeNoop(new InterpolableList(other));
93    }
94
95    static PassOwnPtrWillBeRawPtr<InterpolableList> create(size_t size)
96    {
97        return adoptPtrWillBeNoop(new InterpolableList(size));
98    }
99
100    virtual bool isList() const OVERRIDE FINAL { return true; }
101    void set(size_t position, PassOwnPtrWillBeRawPtr<InterpolableValue> value)
102    {
103        ASSERT(position < m_size);
104        m_values[position] = value;
105    }
106    const InterpolableValue* get(size_t position) const
107    {
108        ASSERT(position < m_size);
109        return m_values[position].get();
110    }
111    size_t length() const { return m_size; }
112    virtual PassOwnPtrWillBeRawPtr<InterpolableValue> clone() const OVERRIDE FINAL { return create(*this); }
113
114    virtual void trace(Visitor*) OVERRIDE;
115
116private:
117    virtual PassOwnPtrWillBeRawPtr<InterpolableValue> interpolate(const InterpolableValue &other, const double progress) const OVERRIDE FINAL;
118    explicit InterpolableList(size_t size)
119        : m_size(size)
120        , m_values(m_size)
121    {
122    }
123
124    InterpolableList(const InterpolableList& other)
125        : m_size(other.m_size)
126        , m_values(m_size)
127    {
128        for (size_t i = 0; i < m_size; i++)
129            set(i, other.m_values[i]->clone());
130    }
131
132    size_t m_size;
133    WillBeHeapVector<OwnPtrWillBeMember<InterpolableValue> > m_values;
134};
135
136// FIXME: Remove this when we can.
137class InterpolableAnimatableValue : public InterpolableValue {
138public:
139    static PassOwnPtrWillBeRawPtr<InterpolableAnimatableValue> create(PassRefPtrWillBeRawPtr<AnimatableValue> value)
140    {
141        return adoptPtrWillBeNoop(new InterpolableAnimatableValue(value));
142    }
143
144    virtual bool isAnimatableValue() const OVERRIDE FINAL { return true; }
145    AnimatableValue* value() const { return m_value.get(); }
146    virtual PassOwnPtrWillBeRawPtr<InterpolableValue> clone() const OVERRIDE FINAL { return create(m_value); }
147
148    virtual void trace(Visitor*) OVERRIDE;
149
150private:
151    virtual PassOwnPtrWillBeRawPtr<InterpolableValue> interpolate(const InterpolableValue &other, const double progress) const OVERRIDE FINAL;
152    RefPtrWillBeMember<AnimatableValue> m_value;
153
154    InterpolableAnimatableValue(PassRefPtrWillBeRawPtr<AnimatableValue> value)
155        : m_value(value)
156    {
157    }
158};
159
160DEFINE_TYPE_CASTS(InterpolableNumber, InterpolableValue, value, value->isNumber(), value.isNumber());
161DEFINE_TYPE_CASTS(InterpolableBool, InterpolableValue, value, value->isBool(), value.isBool());
162DEFINE_TYPE_CASTS(InterpolableList, InterpolableValue, value, value->isList(), value.isList());
163DEFINE_TYPE_CASTS(InterpolableAnimatableValue, InterpolableValue, value, value->isAnimatableValue(), value.isAnimatableValue());
164
165}
166
167#endif
168