Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
Implement Expressions (#9439)
Browse files Browse the repository at this point in the history
Ports mapbox/mapbox-gl-js#4777 (and its several follow-ups)
  • Loading branch information
anandthakker authored Nov 8, 2017
1 parent 9aac976 commit f648cfe
Show file tree
Hide file tree
Showing 167 changed files with 6,460 additions and 175 deletions.
51 changes: 51 additions & 0 deletions cmake/core-files.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -365,10 +365,12 @@ set(MBGL_CORE_FILES
include/mbgl/style/conversion/constant.hpp
include/mbgl/style/conversion/coordinate.hpp
include/mbgl/style/conversion/data_driven_property_value.hpp
include/mbgl/style/conversion/expression.hpp
include/mbgl/style/conversion/filter.hpp
include/mbgl/style/conversion/function.hpp
include/mbgl/style/conversion/geojson.hpp
include/mbgl/style/conversion/geojson_options.hpp
include/mbgl/style/conversion/get_json_type.hpp
include/mbgl/style/conversion/layer.hpp
include/mbgl/style/conversion/light.hpp
include/mbgl/style/conversion/position.hpp
Expand All @@ -381,6 +383,7 @@ set(MBGL_CORE_FILES
src/mbgl/style/conversion/filter.cpp
src/mbgl/style/conversion/geojson.cpp
src/mbgl/style/conversion/geojson_options.cpp
src/mbgl/style/conversion/get_json_type.cpp
src/mbgl/style/conversion/json.hpp
src/mbgl/style/conversion/layer.cpp
src/mbgl/style/conversion/light.cpp
Expand All @@ -392,18 +395,66 @@ set(MBGL_CORE_FILES
src/mbgl/style/conversion/tileset.cpp
src/mbgl/style/conversion/transition_options.cpp

# style/expression
include/mbgl/style/expression/array_assertion.hpp
include/mbgl/style/expression/assertion.hpp
include/mbgl/style/expression/at.hpp
include/mbgl/style/expression/boolean_operator.hpp
include/mbgl/style/expression/case.hpp
include/mbgl/style/expression/check_subtype.hpp
include/mbgl/style/expression/coalesce.hpp
include/mbgl/style/expression/coercion.hpp
include/mbgl/style/expression/compound_expression.hpp
include/mbgl/style/expression/expression.hpp
include/mbgl/style/expression/find_zoom_curve.hpp
include/mbgl/style/expression/get_covering_stops.hpp
include/mbgl/style/expression/interpolate.hpp
include/mbgl/style/expression/is_constant.hpp
include/mbgl/style/expression/is_expression.hpp
include/mbgl/style/expression/let.hpp
include/mbgl/style/expression/literal.hpp
include/mbgl/style/expression/match.hpp
include/mbgl/style/expression/parsing_context.hpp
include/mbgl/style/expression/step.hpp
include/mbgl/style/expression/type.hpp
include/mbgl/style/expression/value.hpp
src/mbgl/style/expression/array_assertion.cpp
src/mbgl/style/expression/assertion.cpp
src/mbgl/style/expression/at.cpp
src/mbgl/style/expression/boolean_operator.cpp
src/mbgl/style/expression/case.cpp
src/mbgl/style/expression/check_subtype.cpp
src/mbgl/style/expression/coalesce.cpp
src/mbgl/style/expression/coercion.cpp
src/mbgl/style/expression/compound_expression.cpp
src/mbgl/style/expression/find_zoom_curve.cpp
src/mbgl/style/expression/get_covering_stops.cpp
src/mbgl/style/expression/interpolate.cpp
src/mbgl/style/expression/is_constant.cpp
src/mbgl/style/expression/is_expression.cpp
src/mbgl/style/expression/let.cpp
src/mbgl/style/expression/literal.cpp
src/mbgl/style/expression/match.cpp
src/mbgl/style/expression/parsing_context.cpp
src/mbgl/style/expression/step.cpp
src/mbgl/style/expression/util.cpp
src/mbgl/style/expression/util.hpp
src/mbgl/style/expression/value.cpp

# style/function
include/mbgl/style/function/camera_function.hpp
include/mbgl/style/function/categorical_stops.hpp
include/mbgl/style/function/composite_categorical_stops.hpp
include/mbgl/style/function/composite_exponential_stops.hpp
include/mbgl/style/function/composite_function.hpp
include/mbgl/style/function/composite_interval_stops.hpp
include/mbgl/style/function/convert.hpp
include/mbgl/style/function/exponential_stops.hpp
include/mbgl/style/function/identity_stops.hpp
include/mbgl/style/function/interval_stops.hpp
include/mbgl/style/function/source_function.hpp
src/mbgl/style/function/categorical_stops.cpp
src/mbgl/style/function/expression.cpp
src/mbgl/style/function/identity_stops.cpp

# style/layers
Expand Down
13 changes: 13 additions & 0 deletions cmake/node.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ target_sources(mbgl-node
PRIVATE platform/node/src/node_feature.cpp
PRIVATE platform/node/src/node_thread_pool.hpp
PRIVATE platform/node/src/node_thread_pool.cpp
PRIVATE platform/node/src/node_expression.hpp
PRIVATE platform/node/src/node_expression.cpp
PRIVATE platform/node/src/util/async_queue.hpp
)

Expand Down Expand Up @@ -91,6 +93,17 @@ xcode_create_scheme(
"test"
)

xcode_create_scheme(
TARGET mbgl-node
TYPE node
NAME "node expression tests"
ARGS
"platform/node/test/expression.test.js"
OPTIONAL_ARGS
"group"
"test"
)

xcode_create_scheme(
TARGET mbgl-node
TYPE node
Expand Down
1 change: 1 addition & 0 deletions cmake/render.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ target_link_libraries(mbgl-render

target_add_mason_package(mbgl-render PRIVATE boost)
target_add_mason_package(mbgl-render PRIVATE boost_libprogram_options)
target_add_mason_package(mbgl-render PRIVATE geojson)

mbgl_platform_render()

Expand Down
4 changes: 4 additions & 0 deletions cmake/test-files.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ set(MBGL_TEST_FILES
test/style/conversion/light.test.cpp
test/style/conversion/stringify.test.cpp

# style/expression
test/style/expression/expression.test.cpp
test/style/expression/util.test.cpp

# style
test/style/filter.test.cpp

Expand Down
25 changes: 25 additions & 0 deletions include/mbgl/style/conversion/data_driven_property_value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,41 @@
#include <mbgl/style/conversion.hpp>
#include <mbgl/style/conversion/constant.hpp>
#include <mbgl/style/conversion/function.hpp>
#include <mbgl/style/conversion/expression.hpp>
#include <mbgl/style/expression/is_expression.hpp>
#include <mbgl/style/expression/is_constant.hpp>
#include <mbgl/style/expression/find_zoom_curve.hpp>

#include <unordered_set>


namespace mbgl {
namespace style {
namespace conversion {

template <class T>
struct Converter<DataDrivenPropertyValue<T>> {

optional<DataDrivenPropertyValue<T>> operator()(const Convertible& value, Error& error) const {
if (isUndefined(value)) {
return DataDrivenPropertyValue<T>();
} else if (expression::isExpression(value)) {
optional<std::unique_ptr<Expression>> expression = convert<std::unique_ptr<Expression>>(
value,
error,
valueTypeToExpressionType<T>());

if (!expression) {
return {};
}

if (isFeatureConstant(**expression)) {
return DataDrivenPropertyValue<T>(CameraFunction<T>(std::move(*expression)));
} else if (isZoomConstant(**expression)) {
return DataDrivenPropertyValue<T>(SourceFunction<T>(std::move(*expression)));
} else {
return DataDrivenPropertyValue<T>(CompositeFunction<T>(std::move(*expression)));
}
} else if (!isObject(value)) {
optional<T> constant = convert<T>(value, error);
if (!constant) {
Expand Down
39 changes: 39 additions & 0 deletions include/mbgl/style/conversion/expression.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#pragma once

#include <mbgl/style/expression/parsing_context.hpp>
#include <mbgl/style/expression/type.hpp>
#include <mbgl/style/conversion.hpp>

#include <memory>

namespace mbgl {
namespace style {
namespace conversion {

using namespace mbgl::style::expression;

template<> struct Converter<std::unique_ptr<Expression>> {
optional<std::unique_ptr<Expression>> operator()(const Convertible& value, Error& error, type::Type expected) const {
ParsingContext ctx(optional<type::Type> {expected});
ParseResult parsed = ctx.parse(value);
if (parsed) {
return std::move(*parsed);
}
std::string combinedError;
for (const ParsingError& parsingError : ctx.getErrors()) {
if (combinedError.size() > 0) {
combinedError += "\n";
}
if (parsingError.key.size() > 0) {
combinedError += parsingError.key + ": ";
}
combinedError += parsingError.message;
}
error = { combinedError };
return {};
};
};

} // namespace conversion
} // namespace style
} // namespace mbgl
14 changes: 14 additions & 0 deletions include/mbgl/style/conversion/get_json_type.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

#include <mbgl/style/conversion.hpp>
#include <string>

namespace mbgl {
namespace style {
namespace conversion {

std::string getJSONType(const Convertible& value);

} // namespace conversion
} // namespace style
} // namespace mbgl
16 changes: 16 additions & 0 deletions include/mbgl/style/conversion/property_value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
#include <mbgl/style/conversion.hpp>
#include <mbgl/style/conversion/constant.hpp>
#include <mbgl/style/conversion/function.hpp>
#include <mbgl/style/conversion/expression.hpp>
#include <mbgl/style/expression/value.hpp>
#include <mbgl/style/expression/is_constant.hpp>
#include <mbgl/style/expression/is_expression.hpp>
#include <mbgl/style/expression/find_zoom_curve.hpp>

namespace mbgl {
namespace style {
Expand All @@ -14,6 +19,17 @@ struct Converter<PropertyValue<T>> {
optional<PropertyValue<T>> operator()(const Convertible& value, Error& error) const {
if (isUndefined(value)) {
return PropertyValue<T>();
} else if (isExpression(value)) {
optional<std::unique_ptr<Expression>> expression = convert<std::unique_ptr<Expression>>(value, error, valueTypeToExpressionType<T>());
if (!expression) {
return {};
}
if (isFeatureConstant(**expression)) {
return { CameraFunction<T>(std::move(*expression)) };
} else {
error = { "property expressions not supported" };
return {};
}
} else if (isObject(value)) {
optional<CameraFunction<T>> function = convert<CameraFunction<T>>(value, error);
if (!function) {
Expand Down
39 changes: 39 additions & 0 deletions include/mbgl/style/expression/array_assertion.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#pragma once

#include <mbgl/style/expression/expression.hpp>
#include <mbgl/style/expression/type.hpp>
#include <mbgl/style/expression/parsing_context.hpp>
#include <mbgl/style/conversion.hpp>

#include <memory>

namespace mbgl {
namespace style {
namespace expression {

class ArrayAssertion : public Expression {
public:
ArrayAssertion(type::Array type_, std::unique_ptr<Expression> input_) :
Expression(type_),
input(std::move(input_))
{}

static ParseResult parse(const mbgl::style::conversion::Convertible& value, ParsingContext& ctx);

EvaluationResult evaluate(const EvaluationContext& params) const override;
void eachChild(const std::function<void(const Expression&)>& visit) const override;

bool operator==(const Expression& e) const override {
if (auto rhs = dynamic_cast<const ArrayAssertion*>(&e)) {
return getType() == rhs->getType() && *input == *(rhs->input);
}
return false;
}

private:
std::unique_ptr<Expression> input;
};

} // namespace expression
} // namespace style
} // namespace mbgl
33 changes: 33 additions & 0 deletions include/mbgl/style/expression/assertion.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#pragma once
#include <mbgl/style/expression/expression.hpp>
#include <mbgl/style/conversion.hpp>
#include <mbgl/style/expression/parsing_context.hpp>
#include <memory>
#include <vector>

namespace mbgl {
namespace style {
namespace expression {

class Assertion : public Expression {
public:
Assertion(type::Type type_, std::vector<std::unique_ptr<Expression>> inputs_) :
Expression(type_),
inputs(std::move(inputs_))
{}

static ParseResult parse(const mbgl::style::conversion::Convertible& value, ParsingContext& ctx);

EvaluationResult evaluate(const EvaluationContext& params) const override;
void eachChild(const std::function<void(const Expression&)>& visit) const override;

bool operator==(const Expression& e) const override;

private:
std::vector<std::unique_ptr<Expression>> inputs;
};

} // namespace expression
} // namespace style
} // namespace mbgl

38 changes: 38 additions & 0 deletions include/mbgl/style/expression/at.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#pragma once

#include <mbgl/style/expression/expression.hpp>
#include <mbgl/style/conversion.hpp>
#include <memory>

namespace mbgl {
namespace style {
namespace expression {

class At : public Expression {
public:
At(std::unique_ptr<Expression> index_, std::unique_ptr<Expression> input_) :
Expression(input_->getType().get<type::Array>().itemType),
index(std::move(index_)),
input(std::move(input_))
{}

static ParseResult parse(const mbgl::style::conversion::Convertible& value, ParsingContext& ctx);

EvaluationResult evaluate(const EvaluationContext& params) const override;
void eachChild(const std::function<void(const Expression&)>&) const override;

bool operator==(const Expression& e) const override {
if (auto rhs = dynamic_cast<const At*>(&e)) {
return *index == *(rhs->index) && *input == *(rhs->input);
}
return false;
}

private:
std::unique_ptr<Expression> index;
std::unique_ptr<Expression> input;
};

} // namespace expression
} // namespace style
} // namespace mbgl
Loading

0 comments on commit f648cfe

Please sign in to comment.