blob: c7e9cb125b4186b3e279bf94979c2388b82cc629 [file] [log] [blame]
// Copyright 2015 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 InterpolationType_h
#define InterpolationType_h
#include "core/animation/InterpolationValue.h"
#include "core/animation/Keyframe.h"
#include "core/animation/PairwiseInterpolationValue.h"
#include "core/animation/PrimitiveInterpolation.h"
#include "core/animation/PropertyHandle.h"
#include "core/animation/UnderlyingValueOwner.h"
#include "platform/heap/Handle.h"
#include "wtf/Allocator.h"
#include <memory>
namespace blink {
class InterpolationEnvironment;
// Subclasses of InterpolationType implement the logic for a specific value type
// of a specific PropertyHandle to:
// - Convert PropertySpecificKeyframe values to (Pairwise)?InterpolationValues:
// maybeConvertPairwise() and maybeConvertSingle()
// - Convert the target Element's property value to an InterpolationValue:
// maybeConvertUnderlyingValue()
// - Apply an InterpolationValue to a target Element's property: apply().
class InterpolationType {
USING_FAST_MALLOC(InterpolationType);
WTF_MAKE_NONCOPYABLE(InterpolationType);
public:
virtual ~InterpolationType() { NOTREACHED(); }
PropertyHandle getProperty() const { return m_property; }
// ConversionCheckers are returned from calls to maybeConvertPairwise() and
// maybeConvertSingle() to enable the caller to check whether the result is
// still valid given changes in the InterpolationEnvironment and underlying
// InterpolationValue.
class ConversionChecker {
USING_FAST_MALLOC(ConversionChecker);
WTF_MAKE_NONCOPYABLE(ConversionChecker);
public:
virtual ~ConversionChecker() {}
void setType(const InterpolationType& type) { m_type = &type; }
const InterpolationType& type() const { return *m_type; }
virtual bool isValid(const InterpolationEnvironment&,
const InterpolationValue& underlying) const = 0;
protected:
ConversionChecker() : m_type(nullptr) {}
const InterpolationType* m_type;
};
using ConversionCheckers = Vector<std::unique_ptr<ConversionChecker>>;
virtual PairwiseInterpolationValue maybeConvertPairwise(
const PropertySpecificKeyframe& startKeyframe,
const PropertySpecificKeyframe& endKeyframe,
const InterpolationEnvironment& environment,
const InterpolationValue& underlying,
ConversionCheckers& conversionCheckers) const {
InterpolationValue start = maybeConvertSingle(
startKeyframe, environment, underlying, conversionCheckers);
if (!start)
return nullptr;
InterpolationValue end = maybeConvertSingle(endKeyframe, environment,
underlying, conversionCheckers);
if (!end)
return nullptr;
return maybeMergeSingles(std::move(start), std::move(end));
}
virtual InterpolationValue maybeConvertSingle(
const PropertySpecificKeyframe&,
const InterpolationEnvironment&,
const InterpolationValue& underlying,
ConversionCheckers&) const = 0;
virtual InterpolationValue maybeConvertUnderlyingValue(
const InterpolationEnvironment&) const = 0;
virtual void composite(UnderlyingValueOwner& underlyingValueOwner,
double underlyingFraction,
const InterpolationValue& value,
double interpolationFraction) const {
DCHECK(!underlyingValueOwner.value().nonInterpolableValue);
DCHECK(!value.nonInterpolableValue);
underlyingValueOwner.mutableValue().interpolableValue->scaleAndAdd(
underlyingFraction, *value.interpolableValue);
}
virtual void apply(const InterpolableValue&,
const NonInterpolableValue*,
InterpolationEnvironment&) const = 0;
// Implement reference equality checking via pointer equality checking as
// these are singletons.
bool operator==(const InterpolationType& other) const {
return this == &other;
}
bool operator!=(const InterpolationType& other) const {
return this != &other;
}
protected:
InterpolationType(PropertyHandle property) : m_property(property) {}
virtual PairwiseInterpolationValue maybeMergeSingles(
InterpolationValue&& start,
InterpolationValue&& end) const {
DCHECK(!start.nonInterpolableValue);
DCHECK(!end.nonInterpolableValue);
return PairwiseInterpolationValue(std::move(start.interpolableValue),
std::move(end.interpolableValue),
nullptr);
}
const PropertyHandle m_property;
};
} // namespace blink
#endif // InterpolationType_h