summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2018-06-27 16:57:23 -0700
committerJohn Firebaugh <john.firebaugh@gmail.com>2018-06-29 15:38:11 -0700
commit542a4b4501794653b55fd1ffc60cb01348d8fc88 (patch)
tree9e451d4117427044d4155396992faf0495a544f7 /src
parent16a3f318a13448a46a4f59b0e8df6a7f0b73bc17 (diff)
downloadqtlocation-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.cpp144
-rw-r--r--src/mbgl/style/expression/dsl.cpp147
-rw-r--r--src/mbgl/style/expression/literal.cpp9
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
-