[core] Simplify Function

This commit is contained in:
John Firebaugh
2015-11-03 13:51:27 -08:00
parent 5ef5d08867
commit 7de4ce5bcb
9 changed files with 81 additions and 103 deletions

View File

@@ -120,8 +120,8 @@ void AnnotationManager::updateStyle(Style& style) {
layer->source = SourceID;
layer->sourceLayer = PointLayerID;
layer->layout.set(PropertyKey::IconImage, ConstantFunction<std::string>("{sprite}"));
layer->layout.set(PropertyKey::IconAllowOverlap, ConstantFunction<bool>(true));
layer->layout.set(PropertyKey::IconImage, Function<std::string>("{sprite}"));
layer->layout.set(PropertyKey::IconAllowOverlap, Function<bool>(true));
style.addLayer(std::move(layer));
}

View File

@@ -34,9 +34,9 @@ void ShapeAnnotationImpl::updateStyle(Style& style) {
const LinePaintProperties& properties = shape.properties.get<LinePaintProperties>();
ClassProperties paintProperties;
paintProperties.set(PropertyKey::LineOpacity, ConstantFunction<float>(properties.opacity));
paintProperties.set(PropertyKey::LineWidth, ConstantFunction<float>(properties.width));
paintProperties.set(PropertyKey::LineColor, ConstantFunction<Color>(properties.color));
paintProperties.set(PropertyKey::LineOpacity, Function<float>(properties.opacity));
paintProperties.set(PropertyKey::LineWidth, Function<float>(properties.width));
paintProperties.set(PropertyKey::LineColor, Function<Color>(properties.color));
layer->paints.paints.emplace(ClassID::Default, std::move(paintProperties));
} else if (shape.properties.is<FillPaintProperties>()) {
@@ -44,9 +44,9 @@ void ShapeAnnotationImpl::updateStyle(Style& style) {
const FillPaintProperties& properties = shape.properties.get<FillPaintProperties>();
ClassProperties paintProperties;
paintProperties.set(PropertyKey::FillOpacity, ConstantFunction<float>(properties.opacity));
paintProperties.set(PropertyKey::FillColor, ConstantFunction<Color>(properties.fill_color));
paintProperties.set(PropertyKey::FillOutlineColor, ConstantFunction<Color>(properties.stroke_color));
paintProperties.set(PropertyKey::FillOpacity, Function<float>(properties.opacity));
paintProperties.set(PropertyKey::FillColor, Function<Color>(properties.fill_color));
paintProperties.set(PropertyKey::FillOutlineColor, Function<Color>(properties.stroke_color));
layer->paints.paints.emplace(ClassID::Default, std::move(paintProperties));
} else {
@@ -83,7 +83,7 @@ std::unique_ptr<StyleLayer> ShapeAnnotationImpl::createLineLayer() {
type = ProjectedFeatureType::LineString;
std::unique_ptr<LineLayer> layer = std::make_unique<LineLayer>();
layer->type = StyleLayerType::Line;
layer->layout.set(PropertyKey::LineJoin, ConstantFunction<JoinType>(JoinType::Round));
layer->layout.set(PropertyKey::LineJoin, Function<JoinType>(JoinType::Round));
return std::move(layer);
}

View File

@@ -1,4 +1,4 @@
#include <mbgl/style/function_properties.hpp>
#include <mbgl/style/function.hpp>
#include <mbgl/style/types.hpp>
#include <mbgl/util/interpolate.hpp>
@@ -27,7 +27,7 @@ template <> inline TextTransformType defaultStopsValue() { return {}; };
template <> inline RotationAlignmentType defaultStopsValue() { return {}; };
template <typename T>
T StopsFunction<T>::evaluate(float z) const {
T Function<T>::evaluate(float z) const {
bool smaller = false;
float smaller_z = 0.0f;
T smaller_val = T();
@@ -35,9 +35,9 @@ T StopsFunction<T>::evaluate(float z) const {
float larger_z = 0.0f;
T larger_val = T();
for (uint32_t i = 0; i < values.size(); i++) {
float stop_z = values[i].first;
T stop_val = values[i].second;
for (uint32_t i = 0; i < stops.size(); i++) {
float stop_z = stops[i].first;
T stop_val = stops[i].second;
if (stop_z <= z && (!smaller || smaller_z < stop_z)) {
smaller = true;
smaller_z = stop_z;
@@ -73,20 +73,21 @@ T StopsFunction<T>::evaluate(float z) const {
}
}
template bool StopsFunction<bool>::evaluate(float z) const;
template float StopsFunction<float>::evaluate(float z) const;
template Color StopsFunction<Color>::evaluate(float z) const;
template std::vector<float> StopsFunction<std::vector<float>>::evaluate(float z) const;
template std::array<float, 2> StopsFunction<std::array<float, 2>>::evaluate(float z) const;
template bool Function<bool>::evaluate(float z) const;
template float Function<float>::evaluate(float z) const;
template Color Function<Color>::evaluate(float z) const;
template std::vector<float> Function<std::vector<float>>::evaluate(float z) const;
template std::array<float, 2> Function<std::array<float, 2>>::evaluate(float z) const;
template std::string Function<std::string>::evaluate(float z) const;
template TranslateAnchorType Function<TranslateAnchorType>::evaluate(float z) const;
template RotateAnchorType Function<RotateAnchorType>::evaluate(float z) const;
template CapType Function<CapType>::evaluate(float z) const;
template JoinType Function<JoinType>::evaluate(float z) const;
template PlacementType Function<PlacementType>::evaluate(float z) const;
template TextAnchorType Function<TextAnchorType>::evaluate(float z) const;
template TextJustifyType Function<TextJustifyType>::evaluate(float z) const;
template TextTransformType Function<TextTransformType>::evaluate(float z) const;
template RotationAlignmentType Function<RotationAlignmentType>::evaluate(float z) const;
template std::string StopsFunction<std::string>::evaluate(float z) const;
template TranslateAnchorType StopsFunction<TranslateAnchorType>::evaluate(float z) const;
template RotateAnchorType StopsFunction<RotateAnchorType>::evaluate(float z) const;
template CapType StopsFunction<CapType>::evaluate(float z) const;
template JoinType StopsFunction<JoinType>::evaluate(float z) const;
template PlacementType StopsFunction<PlacementType>::evaluate(float z) const;
template TextAnchorType StopsFunction<TextAnchorType>::evaluate(float z) const;
template TextJustifyType StopsFunction<TextJustifyType>::evaluate(float z) const;
template TextTransformType StopsFunction<TextTransformType>::evaluate(float z) const;
template RotationAlignmentType StopsFunction<RotationAlignmentType>::evaluate(float z) const;
}

View File

@@ -0,0 +1,31 @@
#ifndef MBGL_STYLE_FUNCTION
#define MBGL_STYLE_FUNCTION
#include <vector>
#include <utility>
namespace mbgl {
template <typename T>
class Function {
public:
using Stop = std::pair<float, T>;
using Stops = std::vector<Stop>;
// TODO: make explicit
/* explicit */ Function(const T& constant)
: stops({{ 0, constant }}) {}
explicit Function(const Stops& stops_, float base_)
: base(base_), stops(stops_) {}
T evaluate(float z) const;
private:
const float base = 1;
const std::vector<std::pair<float, T>> stops;
};
}
#endif

View File

@@ -1,55 +0,0 @@
#ifndef MBGL_STYLE_FUNCTION_PROPERTIES
#define MBGL_STYLE_FUNCTION_PROPERTIES
#include <mapbox/variant.hpp>
#include <vector>
namespace mbgl {
template <typename T>
struct ConstantFunction {
inline ConstantFunction(const T &value_) : value(value_) {}
inline T evaluate(float) const { return value; }
private:
const T value;
};
template <typename T>
struct StopsFunction {
inline StopsFunction(const std::vector<std::pair<float, T>> &values_, float base_) : values(values_), base(base_) {}
T evaluate(float z) const;
private:
const std::vector<std::pair<float, T>> values;
const float base;
};
template <typename T>
using Function = mapbox::util::variant<
std::false_type,
ConstantFunction<T>,
StopsFunction<T>
>;
template <typename T>
struct FunctionEvaluator {
typedef T result_type;
inline FunctionEvaluator(float z_) : z(z_) {}
inline result_type operator()(const std::false_type &) {
return result_type();
}
template <template <typename> class Fn>
inline result_type operator()(const Fn<T>& fn) {
return fn.evaluate(z);
}
private:
float z;
};
}
#endif

View File

@@ -2,7 +2,7 @@
#define MBGL_PROPERTY_EVALUATOR
#include <mbgl/style/zoom_history.hpp>
#include <mbgl/style/function_properties.hpp>
#include <mbgl/style/function.hpp>
#include <mbgl/style/piecewisefunction_properties.hpp>
#include <mbgl/style/style_calculation_parameters.hpp>
@@ -24,7 +24,7 @@ public:
}
T operator()(const Function<T>& value) const {
return mapbox::util::apply_visitor(FunctionEvaluator<T>(parameters.z), value);
return value.evaluate(parameters.z);
}
T operator()(const PiecewiseConstantFunction<T>& value) const {

View File

@@ -273,7 +273,7 @@ optional<Function<T>> parseFunction(const char* name, const JSVal& value) {
if (!constant) {
return {};
}
return { ConstantFunction<T>(*constant) };
return { Function<T>(*constant) };
}
if (!value.HasMember("stops")) {
@@ -300,7 +300,7 @@ optional<Function<T>> parseFunction(const char* name, const JSVal& value) {
return {};
}
return { StopsFunction<T>(*stops, base) };
return { Function<T>(*stops, base) };
}
template <> optional<Function<std::array<float, 2>>> parseProperty(const char* name, const JSVal& value) {

View File

@@ -3,7 +3,7 @@
#include <mapbox/variant.hpp>
#include <mbgl/style/function_properties.hpp>
#include <mbgl/style/function.hpp>
#include <mbgl/style/piecewisefunction_properties.hpp>
#include <mbgl/style/types.hpp>

View File

@@ -1,25 +1,26 @@
#include <iostream>
#include "../fixtures/util.hpp"
#include <mbgl/style/function_properties.hpp>
#include <mbgl/style/function.hpp>
#include <mbgl/style/style_calculation_parameters.hpp>
using namespace mbgl;
TEST(Function, Constant) {
EXPECT_EQ(2.0f, mbgl::ConstantFunction<float>(2).evaluate(0));
EXPECT_EQ(3.8f, mbgl::ConstantFunction<float>(3.8).evaluate(0));
EXPECT_EQ(22.0f, mbgl::ConstantFunction<float>(22).evaluate(0));
EXPECT_EQ(2.0f, mbgl::ConstantFunction<float>(2).evaluate(4));
EXPECT_EQ(3.8f, mbgl::ConstantFunction<float>(3.8).evaluate(4));
EXPECT_EQ(22.0f, mbgl::ConstantFunction<float>(22).evaluate(4));
EXPECT_EQ(2.0f, mbgl::ConstantFunction<float>(2).evaluate(22));
EXPECT_EQ(3.8f, mbgl::ConstantFunction<float>(3.8).evaluate(22));
EXPECT_EQ(22.0f, mbgl::ConstantFunction<float>(22).evaluate(22));
EXPECT_EQ(2.0f, mbgl::Function<float>(2).evaluate(0));
EXPECT_EQ(3.8f, mbgl::Function<float>(3.8).evaluate(0));
EXPECT_EQ(22.0f, mbgl::Function<float>(22).evaluate(0));
EXPECT_EQ(2.0f, mbgl::Function<float>(2).evaluate(4));
EXPECT_EQ(3.8f, mbgl::Function<float>(3.8).evaluate(4));
EXPECT_EQ(22.0f, mbgl::Function<float>(22).evaluate(4));
EXPECT_EQ(2.0f, mbgl::Function<float>(2).evaluate(22));
EXPECT_EQ(3.8f, mbgl::Function<float>(3.8).evaluate(22));
EXPECT_EQ(22.0f, mbgl::Function<float>(22).evaluate(22));
}
TEST(Function, Stops) {
// Explicit constant slope in fringe regions.
mbgl::StopsFunction<float> slope_1({ { 0, 1.5 }, { 6, 1.5 }, { 8, 3 }, { 22, 3 } }, 1.75);
mbgl::Function<float> slope_1({ { 0, 1.5 }, { 6, 1.5 }, { 8, 3 }, { 22, 3 } }, 1.75);
EXPECT_EQ(1.5, slope_1.evaluate(0));
EXPECT_EQ(1.5, slope_1.evaluate(4));
EXPECT_EQ(1.5, slope_1.evaluate(6));
@@ -31,7 +32,7 @@ TEST(Function, Stops) {
// Test constant values in fringe regions.
mbgl::StopsFunction<float> slope_2({ { 6, 1.5 }, { 8, 3 } }, 1.75);
mbgl::Function<float> slope_2({ { 6, 1.5 }, { 8, 3 } }, 1.75);
EXPECT_EQ(1.5, slope_2.evaluate(0));
EXPECT_EQ(1.5, slope_2.evaluate(4));
EXPECT_EQ(1.5, slope_2.evaluate(6));
@@ -42,14 +43,14 @@ TEST(Function, Stops) {
EXPECT_EQ(3.0, slope_2.evaluate(22));
// Test no values.
mbgl::StopsFunction<float> slope_3({}, 1.75);
mbgl::Function<float> slope_3({}, 1.75);
EXPECT_EQ(1, slope_3.evaluate(2));
EXPECT_EQ(1, slope_3.evaluate(6));
EXPECT_EQ(1, slope_3.evaluate(12));
// Explicit constant slope in fringe regions.
mbgl::StopsFunction<float> slope_4({ { 0, 2 }, { 8, 10 } }, 1);
mbgl::Function<float> slope_4({ { 0, 2 }, { 8, 10 } }, 1);
EXPECT_EQ(2, slope_4.evaluate(0));
EXPECT_EQ(3, slope_4.evaluate(1));
EXPECT_EQ(4, slope_4.evaluate(2));