blob: 21428f412281df0efc19c7b76c3b1ddbd57deccd [file] [log] [blame]
// Copyright 2014 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.
#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_INTERPOLABLE_VALUE_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_ANIMATION_INTERPOLABLE_VALUE_H_
#include <memory>
#include <utility>
#include "base/memory/ptr_util.h"
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/casting.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
namespace blink {
// Represents the components of a PropertySpecificKeyframe's value that change
// smoothly as it interpolates to an adjacent value.
class CORE_EXPORT InterpolableValue {
USING_FAST_MALLOC(InterpolableValue);
public:
virtual ~InterpolableValue() = default;
// Interpolates from |this| InterpolableValue towards |to| at the given
// |progress|, placing the output in |result|. That is:
//
// result = this * (1 - progress) + to * progress
//
// Callers must make sure that |this|, |to|, and |result| are all of the same
// concrete subclass.
virtual void Interpolate(const InterpolableValue& to,
const double progress,
InterpolableValue& result) const = 0;
virtual bool IsNumber() const { return false; }
virtual bool IsBool() const { return false; }
virtual bool IsList() const { return false; }
virtual bool IsLength() const { return false; }
virtual bool IsAspectRatio() const { return false; }
virtual bool IsShadow() const { return false; }
virtual bool IsFilter() const { return false; }
virtual bool IsTransformList() const { return false; }
// TODO(alancutter): Remove Equals().
virtual bool Equals(const InterpolableValue&) const = 0;
virtual void Scale(double scale) = 0;
virtual void Add(const InterpolableValue& other) = 0;
// The default implementation should be sufficient for most types, but
// subclasses can override this to be more efficient if they chose.
virtual void ScaleAndAdd(double scale, const InterpolableValue& other) {
Scale(scale);
Add(other);
}
virtual void AssertCanInterpolateWith(
const InterpolableValue& other) const = 0;
// Clone this value, optionally zeroing out the components at the same time.
// These are not virtual to allow for covariant return types; see
// documentation on RawClone/RawCloneAndZero.
std::unique_ptr<InterpolableValue> Clone() const {
return std::unique_ptr<InterpolableValue>(RawClone());
}
std::unique_ptr<InterpolableValue> CloneAndZero() const {
return std::unique_ptr<InterpolableValue>(RawCloneAndZero());
}
private:
// Helper methods to allow covariant Clone/CloneAndZero methods. Concrete
// subclasses should not expose these methods publically, but instead should
// declare their own version of Clone/CloneAndZero with a concrete return type
// if it is useful for their clients.
virtual InterpolableValue* RawClone() const = 0;
virtual InterpolableValue* RawCloneAndZero() const = 0;
};
class CORE_EXPORT InterpolableNumber final : public InterpolableValue {
public:
explicit InterpolableNumber(double value) : value_(value) {}
double Value() const { return value_; }
void Set(double value) { value_ = value; }
// InterpolableValue
void Interpolate(const InterpolableValue& to,
const double progress,
InterpolableValue& result) const final;
bool IsNumber() const final { return true; }
bool Equals(const InterpolableValue& other) const final;
void Scale(double scale) final;
void Add(const InterpolableValue& other) final;
void AssertCanInterpolateWith(const InterpolableValue& other) const final;
private:
InterpolableNumber* RawClone() const final {
return new InterpolableNumber(value_);
}
InterpolableNumber* RawCloneAndZero() const final {
return new InterpolableNumber(0);
}
double value_;
};
class CORE_EXPORT InterpolableList : public InterpolableValue {
public:
// Explicitly delete operator= because MSVC automatically generate
// copy constructors and operator= for dll-exported classes.
// Since InterpolableList is not copyable, automatically generated
// operator= causes MSVC compiler error.
// However, we cannot use DISALLOW_COPY_AND_ASSIGN because InterpolableList
// has its own copy constructor. So just delete operator= here.
InterpolableList& operator=(const InterpolableList&) = delete;
explicit InterpolableList(wtf_size_t size) : values_(size) {}
InterpolableList(const InterpolableList& other) : values_(other.length()) {
for (wtf_size_t i = 0; i < length(); i++)
Set(i, other.values_[i]->Clone());
}
const InterpolableValue* Get(wtf_size_t position) const {
return values_[position].get();
}
std::unique_ptr<InterpolableValue>& GetMutable(wtf_size_t position) {
return values_[position];
}
wtf_size_t length() const { return values_.size(); }
void Set(wtf_size_t position, std::unique_ptr<InterpolableValue> value) {
values_[position] = std::move(value);
}
// InterpolableValue
void Interpolate(const InterpolableValue& to,
const double progress,
InterpolableValue& result) const final;
bool IsList() const final { return true; }
bool Equals(const InterpolableValue& other) const final;
void Scale(double scale) final;
void Add(const InterpolableValue& other) final;
// We override this to avoid two passes on the list from the base version.
void ScaleAndAdd(double scale, const InterpolableValue& other) final;
void AssertCanInterpolateWith(const InterpolableValue& other) const final;
private:
InterpolableList* RawClone() const final {
return new InterpolableList(*this);
}
InterpolableList* RawCloneAndZero() const final;
Vector<std::unique_ptr<InterpolableValue>> values_;
};
template <>
struct DowncastTraits<InterpolableNumber> {
static bool AllowFrom(const InterpolableValue& value) {
return value.IsNumber();
}
};
template <>
struct DowncastTraits<InterpolableList> {
static bool AllowFrom(const InterpolableValue& value) {
return value.IsList();
}
};
} // namespace blink
#endif