diff options
author | Minh Nguyễn <mxn@1ec5.org> | 2018-03-27 00:51:01 -0700 |
---|---|---|
committer | Fabian Guerra <fabian.guerra@mapbox.com> | 2018-03-28 19:40:08 -0400 |
commit | 3b79fc9b4b6adbd4a18b51f2ffab21029e723d66 (patch) | |
tree | 02be72992ad5c870c4542c4dad3d80bb768dc70e | |
parent | ee3b5a2cd91a88ef617f6f0675fd419d43ee71ca (diff) | |
download | qtlocation-mapboxgl-3b79fc9b4b6adbd4a18b51f2ffab21029e723d66.tar.gz |
[ios, macos] Added generic expression function
-rw-r--r-- | platform/darwin/docs/guides/For Style Authors.md.ejs | 8 | ||||
-rw-r--r-- | platform/darwin/docs/guides/Predicates and Expressions.md | 4 | ||||
-rw-r--r-- | platform/darwin/src/NSExpression+MGLAdditions.mm | 20 | ||||
-rw-r--r-- | platform/darwin/test/MGLExpressionTests.mm | 32 | ||||
-rw-r--r-- | platform/ios/docs/guides/For Style Authors.md | 8 | ||||
-rw-r--r-- | platform/macos/docs/guides/For Style Authors.md | 8 |
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 |