diff options
author | John Firebaugh <john.firebaugh@gmail.com> | 2018-06-27 16:57:23 -0700 |
---|---|---|
committer | John Firebaugh <john.firebaugh@gmail.com> | 2018-06-29 15:38:11 -0700 |
commit | 542a4b4501794653b55fd1ffc60cb01348d8fc88 (patch) | |
tree | 9e451d4117427044d4155396992faf0495a544f7 /src | |
parent | 16a3f318a13448a46a4f59b0e8df6a7f0b73bc17 (diff) | |
download | qtlocation-mapboxgl-542a4b4501794653b55fd1ffc60cb01348d8fc88.tar.gz |
[core] Replace use of *Stops with expressions DSL
Diffstat (limited to 'src')
-rw-r--r-- | src/mbgl/style/expression/compound_expression.cpp | 144 | ||||
-rw-r--r-- | src/mbgl/style/expression/dsl.cpp | 147 | ||||
-rw-r--r-- | src/mbgl/style/expression/literal.cpp | 9 |
3 files changed, 208 insertions, 92 deletions
diff --git a/src/mbgl/style/expression/compound_expression.cpp b/src/mbgl/style/expression/compound_expression.cpp index a961de60ae..c37f02612b 100644 --- a/src/mbgl/style/expression/compound_expression.cpp +++ b/src/mbgl/style/expression/compound_expression.cpp @@ -640,76 +640,13 @@ std::unordered_map<std::string, CompoundExpressionRegistry::Definition> initiali std::unordered_map<std::string, Definition> CompoundExpressionRegistry::definitions = initializeDefinitions(); using namespace mbgl::style::conversion; -ParseResult parseCompoundExpression(const std::string name, const Convertible& value, ParsingContext& ctx) { - assert(isArray(value) && arrayLength(value) > 0); - - auto it = CompoundExpressionRegistry::definitions.find(name); - if (it == CompoundExpressionRegistry::definitions.end()) { - ctx.error( - R"(Unknown expression ")" + name + R"(". If you wanted a literal array, use ["literal", [...]].)", - 0 - ); - return ParseResult(); - } - const CompoundExpressionRegistry::Definition& definition = it->second; - - auto length = arrayLength(value); - - // Check if we have a single signature with the correct number of - // parameters. If so, then use that signature's parameter types for parsing - // (and inferring the types of) the arguments. - optional<std::size_t> singleMatchingSignature; - for (std::size_t j = 0; j < definition.size(); j++) { - const std::unique_ptr<detail::SignatureBase>& signature = definition[j]; - if ( - signature->params.is<VarargsType>() || - signature->params.get<std::vector<type::Type>>().size() == length - 1 - ) { - if (singleMatchingSignature) { - singleMatchingSignature = {}; - } else { - singleMatchingSignature = j; - } - } - } - // parse subexpressions first - std::vector<std::unique_ptr<Expression>> args; - args.reserve(length - 1); - for (std::size_t i = 1; i < length; i++) { - optional<type::Type> expected; - - if (singleMatchingSignature) { - expected = definition[*singleMatchingSignature]->params.match( - [](const VarargsType& varargs) { return varargs.type; }, - [&](const std::vector<type::Type>& params_) { return params_[i - 1]; } - ); - } - - auto parsed = ctx.parse(arrayMember(value, i), i, expected); - if (!parsed) { - return parsed; - } - args.push_back(std::move(*parsed)); - } - return createCompoundExpression(definition, std::move(args), ctx); -} - - -ParseResult createCompoundExpression(const std::string& name, - std::vector<std::unique_ptr<Expression>> args, - ParsingContext& ctx) -{ - return createCompoundExpression(CompoundExpressionRegistry::definitions.at(name), std::move(args), ctx); -} - - -ParseResult createCompoundExpression(const Definition& definition, - std::vector<std::unique_ptr<Expression>> args, - ParsingContext& ctx) +static ParseResult createCompoundExpression(const Definition& definition, + std::vector<std::unique_ptr<Expression>> args, + ParsingContext& ctx) { ParsingContext signatureContext(ctx.getKey()); - + for (const std::unique_ptr<detail::SignatureBase>& signature : definition) { signatureContext.clearErrors(); @@ -767,7 +704,7 @@ ParseResult createCompoundExpression(const Definition& definition, signatures += ")"; } ); - + } std::string actualTypes; for (const auto& arg : args) { @@ -782,26 +719,67 @@ ParseResult createCompoundExpression(const Definition& definition, return ParseResult(); } -ParseResult createCompoundExpression(const std::string& name, ParsingContext& ctx) { - return createCompoundExpression(name, std::vector<std::unique_ptr<Expression>>(), ctx); -} +ParseResult parseCompoundExpression(const std::string name, const Convertible& value, ParsingContext& ctx) { + assert(isArray(value) && arrayLength(value) > 0); -ParseResult createCompoundExpression(const std::string& name, - std::unique_ptr<Expression> arg1, - ParsingContext& ctx) { + auto it = CompoundExpressionRegistry::definitions.find(name); + if (it == CompoundExpressionRegistry::definitions.end()) { + ctx.error( + R"(Unknown expression ")" + name + R"(". If you wanted a literal array, use ["literal", [...]].)", + 0 + ); + return ParseResult(); + } + const CompoundExpressionRegistry::Definition& definition = it->second; + + auto length = arrayLength(value); + + // Check if we have a single signature with the correct number of + // parameters. If so, then use that signature's parameter types for parsing + // (and inferring the types of) the arguments. + optional<std::size_t> singleMatchingSignature; + for (std::size_t j = 0; j < definition.size(); j++) { + const std::unique_ptr<detail::SignatureBase>& signature = definition[j]; + if ( + signature->params.is<VarargsType>() || + signature->params.get<std::vector<type::Type>>().size() == length - 1 + ) { + if (singleMatchingSignature) { + singleMatchingSignature = {}; + } else { + singleMatchingSignature = j; + } + } + } + + // parse subexpressions first std::vector<std::unique_ptr<Expression>> args; - args.push_back(std::move(arg1)); - return createCompoundExpression(name, std::move(args), ctx); + args.reserve(length - 1); + for (std::size_t i = 1; i < length; i++) { + optional<type::Type> expected; + + if (singleMatchingSignature) { + expected = definition[*singleMatchingSignature]->params.match( + [](const VarargsType& varargs) { return varargs.type; }, + [&](const std::vector<type::Type>& params_) { return params_[i - 1]; } + ); + } + + auto parsed = ctx.parse(arrayMember(value, i), i, expected); + if (!parsed) { + return parsed; + } + args.push_back(std::move(*parsed)); + } + + return createCompoundExpression(definition, std::move(args), ctx); } ParseResult createCompoundExpression(const std::string& name, - std::unique_ptr<Expression> arg1, - std::unique_ptr<Expression> arg2, - ParsingContext& ctx) { - std::vector<std::unique_ptr<Expression>> args; - args.push_back(std::move(arg1)); - args.push_back(std::move(arg2)); - return createCompoundExpression(name, std::move(args), ctx); + std::vector<std::unique_ptr<Expression>> args, + ParsingContext& ctx) +{ + return createCompoundExpression(CompoundExpressionRegistry::definitions.at(name), std::move(args), ctx); } } // namespace expression diff --git a/src/mbgl/style/expression/dsl.cpp b/src/mbgl/style/expression/dsl.cpp new file mode 100644 index 0000000000..9f204cadc9 --- /dev/null +++ b/src/mbgl/style/expression/dsl.cpp @@ -0,0 +1,147 @@ +#include <mbgl/style/expression/dsl.hpp> +#include <mbgl/style/expression/literal.hpp> +#include <mbgl/style/expression/assertion.hpp> +#include <mbgl/style/expression/coercion.hpp> +#include <mbgl/style/expression/equals.hpp> +#include <mbgl/style/expression/interpolate.hpp> +#include <mbgl/style/expression/compound_expression.hpp> +#include <mbgl/util/ignore.hpp> + +namespace mbgl { +namespace style { +namespace expression { +namespace dsl { + +template <class... Args> +static std::vector<std::unique_ptr<Expression>> vec(Args... args) { + std::vector<std::unique_ptr<Expression>> result; + util::ignore({ (result.push_back(std::move(args)), 0)... }); + return result; +} + +template <class... Args> +static std::unique_ptr<Expression> compound(const char* op, Args... args) { + ParsingContext ctx; + ParseResult result = createCompoundExpression(op, vec(std::move(args)...), ctx); + assert(result); + return std::move(*result); +} + +std::unique_ptr<Expression> literal(const char* value) { + return literal(std::string(value)); +} + +std::unique_ptr<Expression> literal(Value value) { + return std::make_unique<Literal>(value); +} + +std::unique_ptr<Expression> number(std::unique_ptr<Expression> value) { + return std::make_unique<Assertion>(type::Number, vec(std::move(value))); +} + +std::unique_ptr<Expression> string(std::unique_ptr<Expression> value) { + return std::make_unique<Assertion>(type::String, vec(std::move(value))); +} + +std::unique_ptr<Expression> toColor(const char* value) { + return toColor(literal(value)); +} + +std::unique_ptr<Expression> toColor(std::unique_ptr<Expression> value) { + return std::make_unique<Coercion>(type::Color, vec(std::move(value))); +} + +std::unique_ptr<Expression> get(const char* value) { + return get(literal(value)); +} + +std::unique_ptr<Expression> get(std::unique_ptr<Expression> property) { + return compound("get", std::move(property)); +} + +std::unique_ptr<Expression> id() { + return compound("id"); +} + +std::unique_ptr<Expression> zoom() { + return compound("zoom"); +} + +std::unique_ptr<Expression> eq(std::unique_ptr<Expression> lhs, + std::unique_ptr<Expression> rhs) { + return std::make_unique<Equals>(std::move(lhs), std::move(rhs), false); +} + +std::unique_ptr<Expression> ne(std::unique_ptr<Expression> lhs, + std::unique_ptr<Expression> rhs) { + return std::make_unique<Equals>(std::move(lhs), std::move(rhs), true); +} + +std::unique_ptr<Expression> gt(std::unique_ptr<Expression> lhs, + std::unique_ptr<Expression> rhs) { + return compound(">", std::move(lhs), std::move(rhs)); +} + +std::unique_ptr<Expression> lt(std::unique_ptr<Expression> lhs, + std::unique_ptr<Expression> rhs) { + return compound("<", std::move(lhs), std::move(rhs)); +} + +Interpolator linear() { + return ExponentialInterpolator(1.0); +} + +Interpolator exponential(double base) { + return ExponentialInterpolator(base); +} + +Interpolator cubicBezier(double x1, double y1, double x2, double y2) { + return CubicBezierInterpolator(x1, y1, x2, y2); +} + +std::unique_ptr<Expression> interpolate(Interpolator interpolator, + std::unique_ptr<Expression> input, + double input1, std::unique_ptr<Expression> output1) { + type::Type type = output1->getType(); + std::map<double, std::unique_ptr<Expression>> stops; + stops[input1] = std::move(output1); + ParsingContext ctx; + ParseResult result = createInterpolate(type, interpolator, std::move(input), std::move(stops), ctx); + assert(result); + return std::move(*result); +} + +std::unique_ptr<Expression> interpolate(Interpolator interpolator, + std::unique_ptr<Expression> input, + double input1, std::unique_ptr<Expression> output1, + double input2, std::unique_ptr<Expression> output2) { + type::Type type = output1->getType(); + std::map<double, std::unique_ptr<Expression>> stops; + stops[input1] = std::move(output1); + stops[input2] = std::move(output2); + ParsingContext ctx; + ParseResult result = createInterpolate(type, interpolator, std::move(input), std::move(stops), ctx); + assert(result); + return std::move(*result); +} + +std::unique_ptr<Expression> interpolate(Interpolator interpolator, + std::unique_ptr<Expression> input, + double input1, std::unique_ptr<Expression> output1, + double input2, std::unique_ptr<Expression> output2, + double input3, std::unique_ptr<Expression> output3) { + type::Type type = output1->getType(); + std::map<double, std::unique_ptr<Expression>> stops; + stops[input1] = std::move(output1); + stops[input2] = std::move(output2); + stops[input3] = std::move(output3); + ParsingContext ctx; + ParseResult result = createInterpolate(type, interpolator, std::move(input), std::move(stops), ctx); + assert(result); + return std::move(*result); +} + +} // namespace dsl +} // namespace expression +} // namespace style +} // namespace mbgl diff --git a/src/mbgl/style/expression/literal.cpp b/src/mbgl/style/expression/literal.cpp index f68cfd5cf5..345a52de9b 100644 --- a/src/mbgl/style/expression/literal.cpp +++ b/src/mbgl/style/expression/literal.cpp @@ -109,16 +109,7 @@ mbgl::Value Literal::serialize() const { return *fromExpressionValue<mbgl::Value>(value); } } - -std::unique_ptr<Literal> createLiteral(const char* value) { - return createLiteral(std::string(value)); -} - -std::unique_ptr<Literal> createLiteral(Value value) { - return std::make_unique<Literal>(value); -} } // namespace expression } // namespace style } // namespace mbgl - |