summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinh Nguyễn <mxn@1ec5.org>2018-03-27 00:51:01 -0700
committerFabian Guerra <fabian.guerra@mapbox.com>2018-03-28 19:40:08 -0400
commit3b79fc9b4b6adbd4a18b51f2ffab21029e723d66 (patch)
tree02be72992ad5c870c4542c4dad3d80bb768dc70e
parentee3b5a2cd91a88ef617f6f0675fd419d43ee71ca (diff)
downloadqtlocation-mapboxgl-3b79fc9b4b6adbd4a18b51f2ffab21029e723d66.tar.gz
[ios, macos] Added generic expression function
-rw-r--r--platform/darwin/docs/guides/For Style Authors.md.ejs8
-rw-r--r--platform/darwin/docs/guides/Predicates and Expressions.md4
-rw-r--r--platform/darwin/src/NSExpression+MGLAdditions.mm20
-rw-r--r--platform/darwin/test/MGLExpressionTests.mm32
-rw-r--r--platform/ios/docs/guides/For Style Authors.md8
-rw-r--r--platform/macos/docs/guides/For Style Authors.md8
6 files changed, 67 insertions, 13 deletions
diff --git a/platform/darwin/docs/guides/For Style Authors.md.ejs b/platform/darwin/docs/guides/For Style Authors.md.ejs
index d10aa58d56..c3c699f8ab 100644
--- a/platform/darwin/docs/guides/For Style Authors.md.ejs
+++ b/platform/darwin/docs/guides/For Style Authors.md.ejs
@@ -321,6 +321,11 @@ iOS.
<% } -%>
### Expression operators
+Many expression operators defined in the style specification have corresponding
+symbols to be used with the `+[NSExpression expressionWithFormat:]`,
+`+[NSExpression expressionForFunction:arguments:]`, or
+`+[NSExpression expressionForFunction:selectorName:arguments:]` method:
+
In style specification | Method, function, or predicate type | Format string syntax
-----------------------|-------------------------------------|---------------------
`array` | |
@@ -391,6 +396,9 @@ In style specification | Method, function, or predicate type | Format string syn
`zoom` | | `$zoom`
`heatmap-density` | | `$heatmapDensity`
+For operators that have no corresponding `NSExpression` symbol, use the
+`MGL_FUNCTION()` format string syntax.
+
## Filtering sources
You can filter a shape or vector source by setting the
diff --git a/platform/darwin/docs/guides/Predicates and Expressions.md b/platform/darwin/docs/guides/Predicates and Expressions.md
index 538aa2b850..85d907daa8 100644
--- a/platform/darwin/docs/guides/Predicates and Expressions.md
+++ b/platform/darwin/docs/guides/Predicates and Expressions.md
@@ -377,6 +377,10 @@ classes, but you should not call them directly outside the context of an
expression, because the result may differ from the evaluated expression’s result
or may result in undefined behavior.
+The Mapbox Style Specification defines some operators for which no custom
+function is available. To use these operators in an `NSExpression`, call the
+`MGL_FUNCTION()` function with the same arguments that the operator expects.
+
### Variables
The following variables are defined by this SDK for use with style layers:
diff --git a/platform/darwin/src/NSExpression+MGLAdditions.mm b/platform/darwin/src/NSExpression+MGLAdditions.mm
index 4ee0371e9d..ef35c52e2c 100644
--- a/platform/darwin/src/NSExpression+MGLAdditions.mm
+++ b/platform/darwin/src/NSExpression+MGLAdditions.mm
@@ -65,6 +65,7 @@
// numbers of arguments. Vararg aftermarket functions need to be declared
// with an explicit and implicit first argument.
INSTALL_CONTROL_STRUCTURE(MGL_LET);
+ INSTALL_CONTROL_STRUCTURE(MGL_FUNCTION);
#undef INSTALL_AFTERMARKET_FN
#pragma clang pop
@@ -106,6 +107,17 @@
return nil;
}
+/**
+ A placeholder for a catch-all method that evaluates an arbitrary number of
+ arguments as an expression according to the Mapbox Style Specification’s
+ expression language.
+ */
+- (id)MGL_FUNCTION:(id)firstArgument, ... {
+ [NSException raise:NSInvalidArgumentException
+ format:@"Mapbox GL function expressions lack underlying Objective-C implementations."];
+ return nil;
+}
+
@end
@implementation NSExpression (MGLPrivateAdditions)
@@ -624,9 +636,9 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) {
}
return [NSExpression expressionWithFormat:@"FUNCTION(%@, 'mgl_coalesce')", expressions];
- }else {
- [NSException raise:NSInvalidArgumentException
- format:@"Expression operator %@ not yet implemented.", op];
+ } else {
+ NSArray *subexpressions = MGLSubexpressionsWithJSONObjects(array);
+ return [NSExpression expressionForFunction:@"MGL_FUNCTION" arguments:subexpressions];
}
}
@@ -852,6 +864,8 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) {
}
[NSException raise:NSInvalidArgumentException
format:@"Casting expression to %@ not yet implemented.", type];
+ } else if ([function isEqualToString:@"MGL_FUNCTION"]) {
+ return self.arguments.mgl_jsonExpressionObject;
} else if ([function isEqualToString:@"median:"] ||
[function isEqualToString:@"mode:"] ||
[function isEqualToString:@"stddev:"] ||
diff --git a/platform/darwin/test/MGLExpressionTests.mm b/platform/darwin/test/MGLExpressionTests.mm
index b37c880783..5d94829b8f 100644
--- a/platform/darwin/test/MGLExpressionTests.mm
+++ b/platform/darwin/test/MGLExpressionTests.mm
@@ -646,10 +646,11 @@ using namespace std::string_literals;
- (void)testCoalesceExpressionObject {
{
- NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(%@, 'mgl_coalesce')", @[[NSExpression expressionForKeyPath:@"x"],
- [NSExpression expressionForKeyPath:@"y"],
- [NSExpression expressionForKeyPath:@"z"],
- [NSExpression expressionForConstantValue:@0]]];
+ NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(%@, 'mgl_coalesce')",
+ @[[NSExpression expressionForKeyPath:@"x"],
+ [NSExpression expressionForKeyPath:@"y"],
+ [NSExpression expressionForKeyPath:@"z"],
+ [NSExpression expressionForConstantValue:@0]]];
NSArray *jsonExpression = @[@"coalesce", @[@"get", @"x"], @[@"get", @"y"], @[@"get", @"z"], @0];
XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression);
@@ -661,8 +662,8 @@ using namespace std::string_literals;
{
NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(%@, 'mgl_case:', %@, %@)",
[NSExpression expressionWithFormat:@"%@", [NSPredicate predicateWithFormat:@"1 = 2"]],
- MGLConstantExpression(@YES),
- MGLConstantExpression(@NO)];
+ MGLConstantExpression(@YES),
+ MGLConstantExpression(@NO)];
NSArray *jsonExpression = @[@"case", @[@"==", @1, @2], @YES, @NO];
XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression);
@@ -671,10 +672,10 @@ using namespace std::string_literals;
{
NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(%@, 'mgl_case:', %@, %@, %@, %@)",
[NSExpression expressionWithFormat:@"%@", [NSPredicate predicateWithFormat:@"1 = 2"]],
- MGLConstantExpression(@YES),
- [NSExpression expressionWithFormat:@"%@", [NSPredicate predicateWithFormat:@"1 = 1"]],
- MGLConstantExpression(@YES),
- MGLConstantExpression(@NO)];
+ MGLConstantExpression(@YES),
+ [NSExpression expressionWithFormat:@"%@", [NSPredicate predicateWithFormat:@"1 = 1"]],
+ MGLConstantExpression(@YES),
+ MGLConstantExpression(@NO)];
NSArray *jsonExpression = @[@"case", @[@"==", @1, @2], @YES, @[@"==", @1, @1], @YES, @NO];
XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression);
@@ -722,4 +723,15 @@ using namespace std::string_literals;
}
}
+- (void)testGenericExpressionObject {
+ {
+ NSExpression *expression = [NSExpression expressionWithFormat:@"MGL_FUNCTION('random', 1, 2, 3, 4, 5)"];
+ NSArray *jsonExpression = @[@"random", @1, @2, @3, @4, @5];
+ XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
+ XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression);
+ expression = [NSExpression expressionWithFormat:@"MGL_FUNCTION('random', 1, 2, 3, 4)"];
+ XCTAssertThrowsSpecificNamed([expression expressionValueWithObject:nil context:nil], NSException, NSInvalidArgumentException);
+ }
+}
+
@end
diff --git a/platform/ios/docs/guides/For Style Authors.md b/platform/ios/docs/guides/For Style Authors.md
index 122928fd93..fff6373995 100644
--- a/platform/ios/docs/guides/For Style Authors.md
+++ b/platform/ios/docs/guides/For Style Authors.md
@@ -311,6 +311,11 @@ defined by the style specification.
### Expression operators
+Many expression operators defined in the style specification have corresponding
+symbols to be used with the `+[NSExpression expressionWithFormat:]`,
+`+[NSExpression expressionForFunction:arguments:]`, or
+`+[NSExpression expressionForFunction:selectorName:arguments:]` method:
+
In style specification | Method, function, or predicate type | Format string syntax
-----------------------|-------------------------------------|---------------------
`array` | |
@@ -376,6 +381,9 @@ In style specification | Method, function, or predicate type | Format string syn
`zoom` | | `$zoom`
`heatmap-density` | | `$heatmapDensity`
+For operators that have no corresponding `NSExpression` symbol, use the
+`MGL_FUNCTION()` format string syntax.
+
## Filtering sources
You can filter a shape or vector source by setting the
diff --git a/platform/macos/docs/guides/For Style Authors.md b/platform/macos/docs/guides/For Style Authors.md
index 269f2a8ce1..a9d537eb15 100644
--- a/platform/macos/docs/guides/For Style Authors.md
+++ b/platform/macos/docs/guides/For Style Authors.md
@@ -304,6 +304,11 @@ iOS.
### Expression operators
+Many expression operators defined in the style specification have corresponding
+symbols to be used with the `+[NSExpression expressionWithFormat:]`,
+`+[NSExpression expressionForFunction:arguments:]`, or
+`+[NSExpression expressionForFunction:selectorName:arguments:]` method:
+
In style specification | Method, function, or predicate type | Format string syntax
-----------------------|-------------------------------------|---------------------
`array` | |
@@ -369,6 +374,9 @@ In style specification | Method, function, or predicate type | Format string syn
`zoom` | | `$zoom`
`heatmap-density` | | `$heatmapDensity`
+For operators that have no corresponding `NSExpression` symbol, use the
+`MGL_FUNCTION()` format string syntax.
+
## Filtering sources
You can filter a shape or vector source by setting the